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/Passes.h"
19 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
20 #include "llvm/CodeGen/TargetPassConfig.h"
21 #include "llvm/IR/LegacyPassManager.h"
22 #include "llvm/IR/PassManager.h"
23 #include "llvm/Passes/PassBuilder.h"
24 #include "llvm/Support/FormattedStream.h"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
28 #include "llvm/Transforms/Scalar.h"
29 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
30 #include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
34 opt
<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden
,
35 cl::desc("Disable machine peepholes for BPF"));
37 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeBPFTarget() {
38 // Register the target.
39 RegisterTargetMachine
<BPFTargetMachine
> X(getTheBPFleTarget());
40 RegisterTargetMachine
<BPFTargetMachine
> Y(getTheBPFbeTarget());
41 RegisterTargetMachine
<BPFTargetMachine
> Z(getTheBPFTarget());
43 PassRegistry
&PR
= *PassRegistry::getPassRegistry();
44 initializeBPFAbstractMemberAccessLegacyPassPass(PR
);
45 initializeBPFPreserveDITypePass(PR
);
46 initializeBPFAdjustOptPass(PR
);
47 initializeBPFCheckAndAdjustIRPass(PR
);
48 initializeBPFMIPeepholePass(PR
);
49 initializeBPFMIPeepholeTruncElimPass(PR
);
52 // DataLayout: little or big endian
53 static std::string
computeDataLayout(const Triple
&TT
) {
54 if (TT
.getArch() == Triple::bpfeb
)
55 return "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
57 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
60 static Reloc::Model
getEffectiveRelocModel(Optional
<Reloc::Model
> RM
) {
61 return RM
.getValueOr(Reloc::PIC_
);
64 BPFTargetMachine::BPFTargetMachine(const Target
&T
, const Triple
&TT
,
65 StringRef CPU
, StringRef FS
,
66 const TargetOptions
&Options
,
67 Optional
<Reloc::Model
> RM
,
68 Optional
<CodeModel::Model
> CM
,
69 CodeGenOpt::Level OL
, bool JIT
)
70 : LLVMTargetMachine(T
, computeDataLayout(TT
), TT
, CPU
, FS
, Options
,
71 getEffectiveRelocModel(RM
),
72 getEffectiveCodeModel(CM
, CodeModel::Small
), OL
),
73 TLOF(std::make_unique
<TargetLoweringObjectFileELF
>()),
74 Subtarget(TT
, std::string(CPU
), std::string(FS
), *this) {
78 static_cast<BPFMCAsmInfo
*>(const_cast<MCAsmInfo
*>(AsmInfo
.get()));
79 MAI
->setDwarfUsesRelocationsAcrossSections(!Subtarget
.getUseDwarfRIS());
83 // BPF Code Generator Pass Configuration Options.
84 class BPFPassConfig
: public TargetPassConfig
{
86 BPFPassConfig(BPFTargetMachine
&TM
, PassManagerBase
&PM
)
87 : TargetPassConfig(TM
, PM
) {}
89 BPFTargetMachine
&getBPFTargetMachine() const {
90 return getTM
<BPFTargetMachine
>();
93 void addIRPasses() override
;
94 bool addInstSelector() override
;
95 void addMachineSSAOptimization() override
;
96 void addPreEmitPass() override
;
100 TargetPassConfig
*BPFTargetMachine::createPassConfig(PassManagerBase
&PM
) {
101 return new BPFPassConfig(*this, PM
);
104 void BPFTargetMachine::adjustPassManager(PassManagerBuilder
&Builder
) {
105 Builder
.addExtension(
106 PassManagerBuilder::EP_EarlyAsPossible
,
107 [&](const PassManagerBuilder
&, legacy::PassManagerBase
&PM
) {
108 PM
.add(createBPFAbstractMemberAccess(this));
109 PM
.add(createBPFPreserveDIType());
112 Builder
.addExtension(
113 PassManagerBuilder::EP_Peephole
,
114 [&](const PassManagerBuilder
&, legacy::PassManagerBase
&PM
) {
115 PM
.add(createCFGSimplificationPass(
116 SimplifyCFGOptions().hoistCommonInsts(true)));
118 Builder
.addExtension(
119 PassManagerBuilder::EP_ModuleOptimizerEarly
,
120 [&](const PassManagerBuilder
&, legacy::PassManagerBase
&PM
) {
121 PM
.add(createBPFAdjustOpt());
125 void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder
&PB
) {
126 PB
.registerPipelineStartEPCallback(
127 [=](ModulePassManager
&MPM
, OptimizationLevel
) {
128 FunctionPassManager FPM
;
129 FPM
.addPass(BPFAbstractMemberAccessPass(this));
130 FPM
.addPass(BPFPreserveDITypePass());
131 MPM
.addPass(createModuleToFunctionPassAdaptor(std::move(FPM
)));
133 PB
.registerPeepholeEPCallback([=](FunctionPassManager
&FPM
,
134 OptimizationLevel Level
) {
135 FPM
.addPass(SimplifyCFGPass(SimplifyCFGOptions().hoistCommonInsts(true)));
137 PB
.registerPipelineEarlySimplificationEPCallback(
138 [=](ModulePassManager
&MPM
, OptimizationLevel
) {
139 MPM
.addPass(BPFAdjustOptPass());
143 void BPFPassConfig::addIRPasses() {
144 addPass(createBPFCheckAndAdjustIR());
145 TargetPassConfig::addIRPasses();
149 BPFTargetMachine::getTargetTransformInfo(const Function
&F
) {
150 return TargetTransformInfo(BPFTTIImpl(this, F
));
153 // Install an instruction selector pass using
154 // the ISelDag to gen BPF code.
155 bool BPFPassConfig::addInstSelector() {
156 addPass(createBPFISelDag(getBPFTargetMachine()));
161 void BPFPassConfig::addMachineSSAOptimization() {
162 addPass(createBPFMISimplifyPatchablePass());
164 // The default implementation must be called first as we want eBPF
165 // Peephole ran at last.
166 TargetPassConfig::addMachineSSAOptimization();
168 const BPFSubtarget
*Subtarget
= getBPFTargetMachine().getSubtargetImpl();
169 if (!DisableMIPeephole
) {
170 if (Subtarget
->getHasAlu32())
171 addPass(createBPFMIPeepholePass());
172 addPass(createBPFMIPeepholeTruncElimPass());
176 void BPFPassConfig::addPreEmitPass() {
177 addPass(createBPFMIPreEmitCheckingPass());
178 if (getOptLevel() != CodeGenOpt::None
)
179 if (!DisableMIPeephole
)
180 addPass(createBPFMIPreEmitPeepholePass());