1 //===-- BPFTargetMachine.cpp - Define TargetMachine for BPF ---------------===//
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
7 //===----------------------------------------------------------------------===//
9 // Implements the info about BPF target spec.
11 //===----------------------------------------------------------------------===//
13 #include "BPFTargetMachine.h"
15 #include "BPFTargetTransformInfo.h"
16 #include "MCTargetDesc/BPFMCAsmInfo.h"
17 #include "TargetInfo/BPFTargetInfo.h"
18 #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
19 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
20 #include "llvm/CodeGen/GlobalISel/Legalizer.h"
21 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
22 #include "llvm/CodeGen/Passes.h"
23 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
24 #include "llvm/CodeGen/TargetPassConfig.h"
25 #include "llvm/IR/PassManager.h"
26 #include "llvm/InitializePasses.h"
27 #include "llvm/MC/TargetRegistry.h"
28 #include "llvm/Passes/PassBuilder.h"
29 #include "llvm/Support/FormattedStream.h"
30 #include "llvm/Target/TargetOptions.h"
31 #include "llvm/Transforms/Scalar.h"
32 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
33 #include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
38 opt
<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden
,
39 cl::desc("Disable machine peepholes for BPF"));
41 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeBPFTarget() {
42 // Register the target.
43 RegisterTargetMachine
<BPFTargetMachine
> X(getTheBPFleTarget());
44 RegisterTargetMachine
<BPFTargetMachine
> Y(getTheBPFbeTarget());
45 RegisterTargetMachine
<BPFTargetMachine
> Z(getTheBPFTarget());
47 PassRegistry
&PR
= *PassRegistry::getPassRegistry();
48 initializeGlobalISel(PR
);
49 initializeBPFCheckAndAdjustIRPass(PR
);
50 initializeBPFMIPeepholePass(PR
);
51 initializeBPFDAGToDAGISelLegacyPass(PR
);
54 // DataLayout: little or big endian
55 static std::string
computeDataLayout(const Triple
&TT
) {
56 if (TT
.getArch() == Triple::bpfeb
)
57 return "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
59 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
62 static Reloc::Model
getEffectiveRelocModel(std::optional
<Reloc::Model
> RM
) {
63 return RM
.value_or(Reloc::PIC_
);
66 BPFTargetMachine::BPFTargetMachine(const Target
&T
, const Triple
&TT
,
67 StringRef CPU
, StringRef FS
,
68 const TargetOptions
&Options
,
69 std::optional
<Reloc::Model
> RM
,
70 std::optional
<CodeModel::Model
> CM
,
71 CodeGenOptLevel OL
, bool JIT
)
72 : LLVMTargetMachine(T
, computeDataLayout(TT
), TT
, CPU
, FS
, Options
,
73 getEffectiveRelocModel(RM
),
74 getEffectiveCodeModel(CM
, CodeModel::Small
), OL
),
75 TLOF(std::make_unique
<TargetLoweringObjectFileELF
>()),
76 Subtarget(TT
, std::string(CPU
), std::string(FS
), *this) {
80 static_cast<BPFMCAsmInfo
*>(const_cast<MCAsmInfo
*>(AsmInfo
.get()));
81 MAI
->setDwarfUsesRelocationsAcrossSections(!Subtarget
.getUseDwarfRIS());
85 // BPF Code Generator Pass Configuration Options.
86 class BPFPassConfig
: public TargetPassConfig
{
88 BPFPassConfig(BPFTargetMachine
&TM
, PassManagerBase
&PM
)
89 : TargetPassConfig(TM
, PM
) {}
91 BPFTargetMachine
&getBPFTargetMachine() const {
92 return getTM
<BPFTargetMachine
>();
95 void addIRPasses() override
;
96 bool addInstSelector() override
;
97 void addMachineSSAOptimization() override
;
98 void addPreEmitPass() override
;
100 bool addIRTranslator() override
;
101 bool addLegalizeMachineIR() override
;
102 bool addRegBankSelect() override
;
103 bool addGlobalInstructionSelect() override
;
107 TargetPassConfig
*BPFTargetMachine::createPassConfig(PassManagerBase
&PM
) {
108 return new BPFPassConfig(*this, PM
);
111 static Expected
<bool> parseBPFPreserveStaticOffsetOptions(StringRef Params
) {
112 return PassBuilder::parseSinglePassOption(Params
, "allow-partial",
113 "BPFPreserveStaticOffsetPass");
116 void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder
&PB
) {
117 #define GET_PASS_REGISTRY "BPFPassRegistry.def"
118 #include "llvm/Passes/TargetPassRegistry.inc"
120 PB
.registerPipelineStartEPCallback(
121 [=](ModulePassManager
&MPM
, OptimizationLevel
) {
122 FunctionPassManager FPM
;
123 FPM
.addPass(BPFPreserveStaticOffsetPass(true));
124 FPM
.addPass(BPFAbstractMemberAccessPass(this));
125 FPM
.addPass(BPFPreserveDITypePass());
126 FPM
.addPass(BPFIRPeepholePass());
127 MPM
.addPass(createModuleToFunctionPassAdaptor(std::move(FPM
)));
129 PB
.registerPeepholeEPCallback([=](FunctionPassManager
&FPM
,
130 OptimizationLevel Level
) {
131 FPM
.addPass(SimplifyCFGPass(SimplifyCFGOptions().hoistCommonInsts(true)));
132 FPM
.addPass(BPFASpaceCastSimplifyPass());
134 PB
.registerScalarOptimizerLateEPCallback(
135 [=](FunctionPassManager
&FPM
, OptimizationLevel Level
) {
136 // Run this after loop unrolling but before
137 // SimplifyCFGPass(... .sinkCommonInsts(true))
138 FPM
.addPass(BPFPreserveStaticOffsetPass(false));
140 PB
.registerPipelineEarlySimplificationEPCallback(
141 [=](ModulePassManager
&MPM
, OptimizationLevel
) {
142 MPM
.addPass(BPFAdjustOptPass());
146 void BPFPassConfig::addIRPasses() {
147 addPass(createAtomicExpandLegacyPass());
148 addPass(createBPFCheckAndAdjustIR());
150 TargetPassConfig::addIRPasses();
154 BPFTargetMachine::getTargetTransformInfo(const Function
&F
) const {
155 return TargetTransformInfo(BPFTTIImpl(this, F
));
158 // Install an instruction selector pass using
159 // the ISelDag to gen BPF code.
160 bool BPFPassConfig::addInstSelector() {
161 addPass(createBPFISelDag(getBPFTargetMachine()));
166 void BPFPassConfig::addMachineSSAOptimization() {
167 addPass(createBPFMISimplifyPatchablePass());
169 // The default implementation must be called first as we want eBPF
170 // Peephole ran at last.
171 TargetPassConfig::addMachineSSAOptimization();
173 const BPFSubtarget
*Subtarget
= getBPFTargetMachine().getSubtargetImpl();
174 if (!DisableMIPeephole
) {
175 if (Subtarget
->getHasAlu32())
176 addPass(createBPFMIPeepholePass());
180 void BPFPassConfig::addPreEmitPass() {
181 addPass(createBPFMIPreEmitCheckingPass());
182 if (getOptLevel() != CodeGenOptLevel::None
)
183 if (!DisableMIPeephole
)
184 addPass(createBPFMIPreEmitPeepholePass());
187 bool BPFPassConfig::addIRTranslator() {
188 addPass(new IRTranslator());
192 bool BPFPassConfig::addLegalizeMachineIR() {
193 addPass(new Legalizer());
197 bool BPFPassConfig::addRegBankSelect() {
198 addPass(new RegBankSelect());
202 bool BPFPassConfig::addGlobalInstructionSelect() {
203 addPass(new InstructionSelect(getOptLevel()));