212 lines · cpp
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-exception6//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 38static cl::39opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden,40 cl::desc("Disable machine peepholes for BPF"));41 42static cl::opt<bool>43 DisableCheckUnreachable("bpf-disable-trap-unreachable", cl::Hidden,44 cl::desc("Disable Trap Unreachable for BPF"));45 46extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() {47 // Register the target.48 RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget());49 RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget());50 RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget());51 52 PassRegistry &PR = *PassRegistry::getPassRegistry();53 initializeGlobalISel(PR);54 initializeBPFAsmPrinterPass(PR);55 initializeBPFCheckAndAdjustIRPass(PR);56 initializeBPFMIPeepholePass(PR);57 initializeBPFMIPreEmitPeepholePass(PR);58 initializeBPFDAGToDAGISelLegacyPass(PR);59 initializeBPFMISimplifyPatchablePass(PR);60 initializeBPFMIPreEmitCheckingPass(PR);61}62 63static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {64 return RM.value_or(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, 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 117static Expected<bool> parseBPFPreserveStaticOffsetOptions(StringRef Params) {118 return PassBuilder::parseSinglePassOption(Params, "allow-partial",119 "BPFPreserveStaticOffsetPass");120}121 122void BPFTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {123#define GET_PASS_REGISTRY "BPFPassRegistry.def"124#include "llvm/Passes/TargetPassRegistry.inc"125 126 PB.registerPipelineStartEPCallback(127 [=](ModulePassManager &MPM, OptimizationLevel) {128 FunctionPassManager FPM;129 FPM.addPass(BPFPreserveStaticOffsetPass(true));130 FPM.addPass(BPFAbstractMemberAccessPass(this));131 FPM.addPass(BPFPreserveDITypePass());132 FPM.addPass(BPFIRPeepholePass());133 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));134 });135 PB.registerPeepholeEPCallback([=](FunctionPassManager &FPM,136 OptimizationLevel Level) {137 FPM.addPass(SimplifyCFGPass(SimplifyCFGOptions().hoistCommonInsts(true)));138 FPM.addPass(BPFASpaceCastSimplifyPass());139 });140 PB.registerScalarOptimizerLateEPCallback(141 [=](FunctionPassManager &FPM, OptimizationLevel Level) {142 // Run this after loop unrolling but before143 // SimplifyCFGPass(... .sinkCommonInsts(true))144 FPM.addPass(BPFPreserveStaticOffsetPass(false));145 });146 PB.registerPipelineEarlySimplificationEPCallback(147 [=](ModulePassManager &MPM, OptimizationLevel, ThinOrFullLTOPhase) {148 MPM.addPass(BPFAdjustOptPass());149 });150}151 152void BPFPassConfig::addIRPasses() {153 addPass(createAtomicExpandLegacyPass());154 addPass(createBPFCheckAndAdjustIR());155 156 TargetPassConfig::addIRPasses();157}158 159TargetTransformInfo160BPFTargetMachine::getTargetTransformInfo(const Function &F) const {161 return TargetTransformInfo(std::make_unique<BPFTTIImpl>(this, F));162}163 164// Install an instruction selector pass using165// the ISelDag to gen BPF code.166bool BPFPassConfig::addInstSelector() {167 addPass(createBPFISelDag(getBPFTargetMachine()));168 169 return false;170}171 172void BPFPassConfig::addMachineSSAOptimization() {173 addPass(createBPFMISimplifyPatchablePass());174 175 // The default implementation must be called first as we want eBPF176 // Peephole ran at last.177 TargetPassConfig::addMachineSSAOptimization();178 179 const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl();180 if (!DisableMIPeephole) {181 if (Subtarget->getHasAlu32())182 addPass(createBPFMIPeepholePass());183 }184}185 186void BPFPassConfig::addPreEmitPass() {187 addPass(createBPFMIPreEmitCheckingPass());188 if (getOptLevel() != CodeGenOptLevel::None)189 if (!DisableMIPeephole)190 addPass(createBPFMIPreEmitPeepholePass());191}192 193bool BPFPassConfig::addIRTranslator() {194 addPass(new IRTranslator());195 return false;196}197 198bool BPFPassConfig::addLegalizeMachineIR() {199 addPass(new Legalizer());200 return false;201}202 203bool BPFPassConfig::addRegBankSelect() {204 addPass(new RegBankSelect());205 return false;206}207 208bool BPFPassConfig::addGlobalInstructionSelect() {209 addPass(new InstructionSelect(getOptLevel()));210 return false;211}212