brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · ad3df2c Raw
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