1e4c8c807SAlexei Starovoitov //===-- BPFTargetMachine.cpp - Define TargetMachine for BPF ---------------===//
2e4c8c807SAlexei Starovoitov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e4c8c807SAlexei Starovoitov //
7e4c8c807SAlexei Starovoitov //===----------------------------------------------------------------------===//
8e4c8c807SAlexei Starovoitov //
9e4c8c807SAlexei Starovoitov // Implements the info about BPF target spec.
10e4c8c807SAlexei Starovoitov //
11e4c8c807SAlexei Starovoitov //===----------------------------------------------------------------------===//
12e4c8c807SAlexei Starovoitov
13e4c8c807SAlexei Starovoitov #include "BPFTargetMachine.h"
146bda14b3SChandler Carruth #include "BPF.h"
15a260ae71SYonghong Song #include "BPFTargetTransformInfo.h"
1603e1c8b8SYonghong Song #include "MCTargetDesc/BPFMCAsmInfo.h"
17a68ee931SRichard Trieu #include "TargetInfo/BPFTargetInfo.h"
18e4c8c807SAlexei Starovoitov #include "llvm/CodeGen/Passes.h"
196bda14b3SChandler Carruth #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
2031d19d43SMatthias Braun #include "llvm/CodeGen/TargetPassConfig.h"
216bda14b3SChandler Carruth #include "llvm/IR/LegacyPassManager.h"
2240251feeSArthur Eubanks #include "llvm/IR/PassManager.h"
2389b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
2440251feeSArthur Eubanks #include "llvm/Passes/PassBuilder.h"
25e4c8c807SAlexei Starovoitov #include "llvm/Support/FormattedStream.h"
26e4c8c807SAlexei Starovoitov #include "llvm/Target/TargetOptions.h"
2787cba434SYonghong Song #include "llvm/Transforms/IPO/PassManagerBuilder.h"
2887cba434SYonghong Song #include "llvm/Transforms/Scalar.h"
2940251feeSArthur Eubanks #include "llvm/Transforms/Scalar/SimplifyCFG.h"
3087cba434SYonghong Song #include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
31e4c8c807SAlexei Starovoitov using namespace llvm;
32e4c8c807SAlexei Starovoitov
3360fed1feSYonghong Song static cl::
3460fed1feSYonghong Song opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden,
3560fed1feSYonghong Song cl::desc("Disable machine peepholes for BPF"));
3660fed1feSYonghong Song
LLVMInitializeBPFTarget()370dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() {
38e4c8c807SAlexei Starovoitov // Register the target.
39f42454b9SMehdi Amini RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget());
40f42454b9SMehdi Amini RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget());
41f42454b9SMehdi Amini RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget());
4260fed1feSYonghong Song
4360fed1feSYonghong Song PassRegistry &PR = *PassRegistry::getPassRegistry();
4440251feeSArthur Eubanks initializeBPFAbstractMemberAccessLegacyPassPass(PR);
456b01b465SYonghong Song initializeBPFPreserveDITypePass(PR);
46009f3a89SYonghong Song initializeBPFIRPeepholePass(PR);
47ddf1864aSYonghong Song initializeBPFAdjustOptPass(PR);
4854d9f743SYonghong Song initializeBPFCheckAndAdjustIRPass(PR);
4960fed1feSYonghong Song initializeBPFMIPeepholePass(PR);
50ec518510SJiong Wang initializeBPFMIPeepholeTruncElimPass(PR);
51e4c8c807SAlexei Starovoitov }
52e4c8c807SAlexei Starovoitov
53310deadaSAlexei Starovoitov // DataLayout: little or big endian
computeDataLayout(const Triple & TT)543e5de88dSDaniel Sanders static std::string computeDataLayout(const Triple &TT) {
553e5de88dSDaniel Sanders if (TT.getArch() == Triple::bpfeb)
56ced0d1f4SYonghong Song return "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
57310deadaSAlexei Starovoitov else
58ced0d1f4SYonghong Song return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
59310deadaSAlexei Starovoitov }
60310deadaSAlexei Starovoitov
getEffectiveRelocModel(Optional<Reloc::Model> RM)618c34dd82SRafael Espindola static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
62*129b531cSKazu Hirata return RM.value_or(Reloc::PIC_);
638c34dd82SRafael Espindola }
648c34dd82SRafael Espindola
BPFTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,Optional<CodeModel::Model> CM,CodeGenOpt::Level OL,bool JIT)653e5de88dSDaniel Sanders BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT,
663e5de88dSDaniel Sanders StringRef CPU, StringRef FS,
673e5de88dSDaniel Sanders const TargetOptions &Options,
688c34dd82SRafael Espindola Optional<Reloc::Model> RM,
6979e238afSRafael Espindola Optional<CodeModel::Model> CM,
7079e238afSRafael Espindola CodeGenOpt::Level OL, bool JIT)
71bb8507e6SMatthias Braun : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
72ca29c271SDavid Green getEffectiveRelocModel(RM),
73ca29c271SDavid Green getEffectiveCodeModel(CM, CodeModel::Small), OL),
740eaee545SJonas Devlieghere TLOF(std::make_unique<TargetLoweringObjectFileELF>()),
75adcd0268SBenjamin Kramer Subtarget(TT, std::string(CPU), std::string(FS), *this) {
76e4c8c807SAlexei Starovoitov initAsmInfo();
7703e1c8b8SYonghong Song
7810a21625SFangrui Song BPFMCAsmInfo *MAI =
7910a21625SFangrui Song static_cast<BPFMCAsmInfo *>(const_cast<MCAsmInfo *>(AsmInfo.get()));
8003e1c8b8SYonghong Song MAI->setDwarfUsesRelocationsAcrossSections(!Subtarget.getUseDwarfRIS());
81e4c8c807SAlexei Starovoitov }
82d3d88d08SYonghong Song
83e4c8c807SAlexei Starovoitov namespace {
84e4c8c807SAlexei Starovoitov // BPF Code Generator Pass Configuration Options.
85e4c8c807SAlexei Starovoitov class BPFPassConfig : public TargetPassConfig {
86e4c8c807SAlexei Starovoitov public:
BPFPassConfig(BPFTargetMachine & TM,PassManagerBase & PM)875e394c3dSMatthias Braun BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM)
88e4c8c807SAlexei Starovoitov : TargetPassConfig(TM, PM) {}
89e4c8c807SAlexei Starovoitov
getBPFTargetMachine() const90e4c8c807SAlexei Starovoitov BPFTargetMachine &getBPFTargetMachine() const {
91e4c8c807SAlexei Starovoitov return getTM<BPFTargetMachine>();
92e4c8c807SAlexei Starovoitov }
93e4c8c807SAlexei Starovoitov
94d3d88d08SYonghong Song void addIRPasses() override;
95e4c8c807SAlexei Starovoitov bool addInstSelector() override;
9660fed1feSYonghong Song void addMachineSSAOptimization() override;
97e91802f3SYonghong Song void addPreEmitPass() override;
98e4c8c807SAlexei Starovoitov };
99f00654e3SAlexander Kornienko }
100e4c8c807SAlexei Starovoitov
createPassConfig(PassManagerBase & PM)101e4c8c807SAlexei Starovoitov TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) {
1025e394c3dSMatthias Braun return new BPFPassConfig(*this, PM);
103e4c8c807SAlexei Starovoitov }
104e4c8c807SAlexei Starovoitov
adjustPassManager(PassManagerBuilder & Builder)10587cba434SYonghong Song void BPFTargetMachine::adjustPassManager(PassManagerBuilder &Builder) {
10687cba434SYonghong Song Builder.addExtension(
10754d9f743SYonghong Song PassManagerBuilder::EP_EarlyAsPossible,
10854d9f743SYonghong Song [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
10954d9f743SYonghong Song PM.add(createBPFAbstractMemberAccess(this));
11054d9f743SYonghong Song PM.add(createBPFPreserveDIType());
111009f3a89SYonghong Song PM.add(createBPFIRPeephole());
11254d9f743SYonghong Song });
11354d9f743SYonghong Song
11454d9f743SYonghong Song Builder.addExtension(
11587cba434SYonghong Song PassManagerBuilder::EP_Peephole,
11687cba434SYonghong Song [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
11787cba434SYonghong Song PM.add(createCFGSimplificationPass(
11887cba434SYonghong Song SimplifyCFGOptions().hoistCommonInsts(true)));
11987cba434SYonghong Song });
120ddf1864aSYonghong Song Builder.addExtension(
121ddf1864aSYonghong Song PassManagerBuilder::EP_ModuleOptimizerEarly,
122ddf1864aSYonghong Song [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
123ddf1864aSYonghong Song PM.add(createBPFAdjustOpt());
124ddf1864aSYonghong Song });
12587cba434SYonghong Song }
126d3d88d08SYonghong Song
registerPassBuilderCallbacks(PassBuilder & PB)12734a8a437SArthur Eubanks void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
128ab0ddbc3SArthur Eubanks PB.registerPipelineStartEPCallback(
1297a797b29STarindu Jayatilaka [=](ModulePassManager &MPM, OptimizationLevel) {
13034a8a437SArthur Eubanks FunctionPassManager FPM;
13140251feeSArthur Eubanks FPM.addPass(BPFAbstractMemberAccessPass(this));
13240251feeSArthur Eubanks FPM.addPass(BPFPreserveDITypePass());
133009f3a89SYonghong Song FPM.addPass(BPFIRPeepholePass());
13440251feeSArthur Eubanks MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
13540251feeSArthur Eubanks });
13640251feeSArthur Eubanks PB.registerPeepholeEPCallback([=](FunctionPassManager &FPM,
1377a797b29STarindu Jayatilaka OptimizationLevel Level) {
13840251feeSArthur Eubanks FPM.addPass(SimplifyCFGPass(SimplifyCFGOptions().hoistCommonInsts(true)));
13940251feeSArthur Eubanks });
14092a67e13SArthur Eubanks PB.registerPipelineEarlySimplificationEPCallback(
1417a797b29STarindu Jayatilaka [=](ModulePassManager &MPM, OptimizationLevel) {
14292a67e13SArthur Eubanks MPM.addPass(BPFAdjustOptPass());
14392a67e13SArthur Eubanks });
14440251feeSArthur Eubanks }
14540251feeSArthur Eubanks
addIRPasses()14687cba434SYonghong Song void BPFPassConfig::addIRPasses() {
14754d9f743SYonghong Song addPass(createBPFCheckAndAdjustIR());
148d3d88d08SYonghong Song TargetPassConfig::addIRPasses();
149d3d88d08SYonghong Song }
150d3d88d08SYonghong Song
151a260ae71SYonghong Song TargetTransformInfo
getTargetTransformInfo(const Function & F) const152c4b1a63aSJameson Nash BPFTargetMachine::getTargetTransformInfo(const Function &F) const {
153a260ae71SYonghong Song return TargetTransformInfo(BPFTTIImpl(this, F));
154a260ae71SYonghong Song }
155a260ae71SYonghong Song
156e4c8c807SAlexei Starovoitov // Install an instruction selector pass using
157e4c8c807SAlexei Starovoitov // the ISelDag to gen BPF code.
addInstSelector()158e4c8c807SAlexei Starovoitov bool BPFPassConfig::addInstSelector() {
159e4c8c807SAlexei Starovoitov addPass(createBPFISelDag(getBPFTargetMachine()));
160e4c8c807SAlexei Starovoitov
161e4c8c807SAlexei Starovoitov return false;
162e4c8c807SAlexei Starovoitov }
16360fed1feSYonghong Song
addMachineSSAOptimization()16460fed1feSYonghong Song void BPFPassConfig::addMachineSSAOptimization() {
165d3d88d08SYonghong Song addPass(createBPFMISimplifyPatchablePass());
166d3d88d08SYonghong Song
16760fed1feSYonghong Song // The default implementation must be called first as we want eBPF
16860fed1feSYonghong Song // Peephole ran at last.
16960fed1feSYonghong Song TargetPassConfig::addMachineSSAOptimization();
17060fed1feSYonghong Song
17160fed1feSYonghong Song const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl();
172ec518510SJiong Wang if (!DisableMIPeephole) {
173ec518510SJiong Wang if (Subtarget->getHasAlu32())
17460fed1feSYonghong Song addPass(createBPFMIPeepholePass());
175ec518510SJiong Wang addPass(createBPFMIPeepholeTruncElimPass());
176ec518510SJiong Wang }
17760fed1feSYonghong Song }
178e91802f3SYonghong Song
addPreEmitPass()179e91802f3SYonghong Song void BPFPassConfig::addPreEmitPass() {
180150ca514SYonghong Song addPass(createBPFMIPreEmitCheckingPass());
181e91802f3SYonghong Song if (getOptLevel() != CodeGenOpt::None)
182ec518510SJiong Wang if (!DisableMIPeephole)
183e91802f3SYonghong Song addPass(createBPFMIPreEmitPeepholePass());
184e91802f3SYonghong Song }
185