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 "MCTargetDesc/BPFMCAsmInfo.h" 16 #include "TargetInfo/BPFTargetInfo.h" 17 #include "llvm/CodeGen/Passes.h" 18 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 19 #include "llvm/CodeGen/TargetPassConfig.h" 20 #include "llvm/IR/LegacyPassManager.h" 21 #include "llvm/Support/FormattedStream.h" 22 #include "llvm/Support/TargetRegistry.h" 23 #include "llvm/Target/TargetOptions.h" 24 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 25 #include "llvm/Transforms/Scalar.h" 26 #include "llvm/Transforms/Utils/SimplifyCFGOptions.h" 27 using namespace llvm; 28 29 static cl:: 30 opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden, 31 cl::desc("Disable machine peepholes for BPF")); 32 33 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() { 34 // Register the target. 35 RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget()); 36 RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget()); 37 RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget()); 38 39 PassRegistry &PR = *PassRegistry::getPassRegistry(); 40 initializeBPFAbstractMemberAccessPass(PR); 41 initializeBPFPreserveDITypePass(PR); 42 initializeBPFCheckAndAdjustIRPass(PR); 43 initializeBPFMIPeepholePass(PR); 44 initializeBPFMIPeepholeTruncElimPass(PR); 45 } 46 47 // DataLayout: little or big endian 48 static std::string computeDataLayout(const Triple &TT) { 49 if (TT.getArch() == Triple::bpfeb) 50 return "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128"; 51 else 52 return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"; 53 } 54 55 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 56 if (!RM.hasValue()) 57 return Reloc::PIC_; 58 return *RM; 59 } 60 61 BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT, 62 StringRef CPU, StringRef FS, 63 const TargetOptions &Options, 64 Optional<Reloc::Model> RM, 65 Optional<CodeModel::Model> CM, 66 CodeGenOpt::Level OL, bool JIT) 67 : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, 68 getEffectiveRelocModel(RM), 69 getEffectiveCodeModel(CM, CodeModel::Small), OL), 70 TLOF(std::make_unique<TargetLoweringObjectFileELF>()), 71 Subtarget(TT, std::string(CPU), std::string(FS), *this) { 72 initAsmInfo(); 73 74 BPFMCAsmInfo *MAI = 75 static_cast<BPFMCAsmInfo *>(const_cast<MCAsmInfo *>(AsmInfo.get())); 76 MAI->setDwarfUsesRelocationsAcrossSections(!Subtarget.getUseDwarfRIS()); 77 } 78 79 namespace { 80 // BPF Code Generator Pass Configuration Options. 81 class BPFPassConfig : public TargetPassConfig { 82 public: 83 BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM) 84 : TargetPassConfig(TM, PM) {} 85 86 BPFTargetMachine &getBPFTargetMachine() const { 87 return getTM<BPFTargetMachine>(); 88 } 89 90 void addIRPasses() override; 91 bool addInstSelector() override; 92 void addMachineSSAOptimization() override; 93 void addPreEmitPass() override; 94 }; 95 } 96 97 TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) { 98 return new BPFPassConfig(*this, PM); 99 } 100 101 void BPFTargetMachine::adjustPassManager(PassManagerBuilder &Builder) { 102 Builder.addExtension( 103 PassManagerBuilder::EP_EarlyAsPossible, 104 [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 105 PM.add(createBPFAbstractMemberAccess(this)); 106 PM.add(createBPFPreserveDIType()); 107 }); 108 109 Builder.addExtension( 110 PassManagerBuilder::EP_Peephole, 111 [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 112 PM.add(createCFGSimplificationPass( 113 SimplifyCFGOptions().hoistCommonInsts(true))); 114 }); 115 } 116 117 void BPFPassConfig::addIRPasses() { 118 addPass(createBPFCheckAndAdjustIR()); 119 TargetPassConfig::addIRPasses(); 120 } 121 122 // Install an instruction selector pass using 123 // the ISelDag to gen BPF code. 124 bool BPFPassConfig::addInstSelector() { 125 addPass(createBPFISelDag(getBPFTargetMachine())); 126 127 return false; 128 } 129 130 void BPFPassConfig::addMachineSSAOptimization() { 131 addPass(createBPFMISimplifyPatchablePass()); 132 133 // The default implementation must be called first as we want eBPF 134 // Peephole ran at last. 135 TargetPassConfig::addMachineSSAOptimization(); 136 137 const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl(); 138 if (!DisableMIPeephole) { 139 if (Subtarget->getHasAlu32()) 140 addPass(createBPFMIPeepholePass()); 141 addPass(createBPFMIPeepholeTruncElimPass()); 142 } 143 } 144 145 void BPFPassConfig::addPreEmitPass() { 146 addPass(createBPFMIPreEmitCheckingPass()); 147 if (getOptLevel() != CodeGenOpt::None) 148 if (!DisableMIPeephole) 149 addPass(createBPFMIPreEmitPeepholePass()); 150 } 151