1//===-- BPFTargetMachine.cpp - Define TargetMachine for BPF ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Implements the info about BPF target spec.
10//
11//===----------------------------------------------------------------------===//
12
13#include "BPFTargetMachine.h"
14#include "BPF.h"
15#include "BPFTargetLoweringObjectFile.h"
16#include "BPFTargetTransformInfo.h"
17#include "MCTargetDesc/BPFMCAsmInfo.h"
18#include "TargetInfo/BPFTargetInfo.h"
19#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
20#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
21#include "llvm/CodeGen/GlobalISel/Legalizer.h"
22#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
23#include "llvm/CodeGen/Passes.h"
24#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
25#include "llvm/CodeGen/TargetPassConfig.h"
26#include "llvm/IR/PassManager.h"
27#include "llvm/InitializePasses.h"
28#include "llvm/MC/TargetRegistry.h"
29#include "llvm/Passes/PassBuilder.h"
30#include "llvm/Support/Compiler.h"
31#include "llvm/Target/TargetOptions.h"
32#include "llvm/Transforms/Scalar.h"
33#include "llvm/Transforms/Scalar/SimplifyCFG.h"
34#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
35#include <optional>
36using namespace llvm;
37
38cl::opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden,
39 cl::desc("Disable machine peepholes for BPF"));
40
41static cl::opt<bool>
42 DisableCheckUnreachable("bpf-disable-trap-unreachable", cl::Hidden,
43 cl::desc("Disable Trap Unreachable for BPF"));
44
45extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() {
46 // Register the target.
47 RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget());
48 RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget());
49 RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget());
50
51 PassRegistry &PR = *PassRegistry::getPassRegistry();
52 initializeGlobalISel(PR);
53 initializeBPFAsmPrinterPass(PR);
54 initializeBPFCheckAndAdjustIRLegacyPass(PR);
55 initializeBPFMIPeepholeLegacyPass(PR);
56 initializeBPFMIExpandStackArgPseudosLegacyPass(PR);
57 initializeBPFMIPreEmitPeepholeLegacyPass(PR);
58 initializeBPFDAGToDAGISelLegacyPass(PR);
59 initializeBPFMISimplifyPatchableLegacyPass(PR);
60 initializeBPFMIPreEmitCheckingLegacyPass(PR);
61}
62
63static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
64 return RM.value_or(u: Reloc::PIC_);
65}
66
67BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT,
68 StringRef CPU, StringRef FS,
69 const TargetOptions &Options,
70 std::optional<Reloc::Model> RM,
71 std::optional<CodeModel::Model> CM,
72 CodeGenOptLevel OL, bool JIT)
73 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
74 getEffectiveRelocModel(RM),
75 getEffectiveCodeModel(CM, Default: CodeModel::Small), OL),
76 TLOF(std::make_unique<BPFTargetLoweringObjectFileELF>()),
77 Subtarget(TT, std::string(CPU), std::string(FS), *this) {
78 if (!DisableCheckUnreachable) {
79 this->Options.TrapUnreachable = true;
80 this->Options.NoTrapAfterNoreturn = true;
81 }
82
83 initAsmInfo();
84
85 BPFMCAsmInfo *MAI =
86 static_cast<BPFMCAsmInfo *>(const_cast<MCAsmInfo *>(AsmInfo.get()));
87 MAI->setDwarfUsesRelocationsAcrossSections(!Subtarget.getUseDwarfRIS());
88}
89
90namespace {
91// BPF Code Generator Pass Configuration Options.
92class BPFPassConfig : public TargetPassConfig {
93public:
94 BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM)
95 : TargetPassConfig(TM, PM) {}
96
97 BPFTargetMachine &getBPFTargetMachine() const {
98 return getTM<BPFTargetMachine>();
99 }
100
101 void addIRPasses() override;
102 bool addInstSelector() override;
103 void addMachineSSAOptimization() override;
104 void addPreEmitPass() override;
105
106 bool addIRTranslator() override;
107 bool addLegalizeMachineIR() override;
108 bool addRegBankSelect() override;
109 bool addGlobalInstructionSelect() override;
110};
111}
112
113TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) {
114 return new BPFPassConfig(*this, PM);
115}
116
117void BPFPassConfig::addIRPasses() {
118 addPass(P: createAtomicExpandLegacyPass());
119 addPass(P: createBPFCheckAndAdjustIRLegacyPass());
120
121 TargetPassConfig::addIRPasses();
122}
123
124TargetTransformInfo
125BPFTargetMachine::getTargetTransformInfo(const Function &F) const {
126 return TargetTransformInfo(std::make_unique<BPFTTIImpl>(args: this, args: F));
127}
128
129// Install an instruction selector pass using
130// the ISelDag to gen BPF code.
131bool BPFPassConfig::addInstSelector() {
132 addPass(P: createBPFISelDag(TM&: getBPFTargetMachine()));
133
134 return false;
135}
136
137void BPFPassConfig::addMachineSSAOptimization() {
138 addPass(P: createBPFMISimplifyPatchableLegacyPass());
139
140 // The default implementation must be called first as we want eBPF
141 // Peephole ran at last.
142 TargetPassConfig::addMachineSSAOptimization();
143
144 const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl();
145 if (!DisableMIPeephole) {
146 if (Subtarget->getHasAlu32())
147 addPass(P: createBPFMIPeepholeLegacyPass());
148 }
149}
150
151void BPFPassConfig::addPreEmitPass() {
152 addPass(P: createBPFMIPreEmitCheckingLegacyPass());
153 if (!DisableMIPeephole) {
154 addPass(P: createBPFMIExpandStackArgPseudosLegacyPass());
155 addPass(P: createBPFMIPreEmitPeepholeLegacyPass());
156 }
157}
158
159bool BPFPassConfig::addIRTranslator() {
160 addPass(P: new IRTranslator());
161 return false;
162}
163
164bool BPFPassConfig::addLegalizeMachineIR() {
165 addPass(P: new Legalizer());
166 return false;
167}
168
169bool BPFPassConfig::addRegBankSelect() {
170 addPass(P: new RegBankSelect());
171 return false;
172}
173
174bool BPFPassConfig::addGlobalInstructionSelect() {
175 addPass(P: new InstructionSelect(getOptLevel()));
176 return false;
177}
178