|  | //===-- BPFTargetMachine.cpp - Define TargetMachine for BPF ---------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // Implements the info about BPF target spec. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "BPFTargetMachine.h" | 
|  | #include "BPF.h" | 
|  | #include "MCTargetDesc/BPFMCAsmInfo.h" | 
|  | #include "llvm/CodeGen/Passes.h" | 
|  | #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" | 
|  | #include "llvm/CodeGen/TargetPassConfig.h" | 
|  | #include "llvm/IR/LegacyPassManager.h" | 
|  | #include "llvm/Support/FormattedStream.h" | 
|  | #include "llvm/Support/TargetRegistry.h" | 
|  | #include "llvm/Target/TargetOptions.h" | 
|  | using namespace llvm; | 
|  |  | 
|  | static cl:: | 
|  | opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden, | 
|  | cl::desc("Disable machine peepholes for BPF")); | 
|  |  | 
|  | extern "C" void LLVMInitializeBPFTarget() { | 
|  | // Register the target. | 
|  | RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget()); | 
|  | RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget()); | 
|  | RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget()); | 
|  |  | 
|  | PassRegistry &PR = *PassRegistry::getPassRegistry(); | 
|  | initializeBPFMIPeepholePass(PR); | 
|  | } | 
|  |  | 
|  | // DataLayout: little or big endian | 
|  | static std::string computeDataLayout(const Triple &TT) { | 
|  | if (TT.getArch() == Triple::bpfeb) | 
|  | return "E-m:e-p:64:64-i64:64-n32:64-S128"; | 
|  | else | 
|  | return "e-m:e-p:64:64-i64:64-n32:64-S128"; | 
|  | } | 
|  |  | 
|  | static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { | 
|  | if (!RM.hasValue()) | 
|  | return Reloc::PIC_; | 
|  | return *RM; | 
|  | } | 
|  |  | 
|  | BPFTargetMachine::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) | 
|  | : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, | 
|  | getEffectiveRelocModel(RM), | 
|  | getEffectiveCodeModel(CM, CodeModel::Small), OL), | 
|  | TLOF(make_unique<TargetLoweringObjectFileELF>()), | 
|  | Subtarget(TT, CPU, FS, *this) { | 
|  | initAsmInfo(); | 
|  |  | 
|  | BPFMCAsmInfo *MAI = | 
|  | static_cast<BPFMCAsmInfo *>(const_cast<MCAsmInfo *>(AsmInfo.get())); | 
|  | MAI->setDwarfUsesRelocationsAcrossSections(!Subtarget.getUseDwarfRIS()); | 
|  | } | 
|  | namespace { | 
|  | // BPF Code Generator Pass Configuration Options. | 
|  | class BPFPassConfig : public TargetPassConfig { | 
|  | public: | 
|  | BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM) | 
|  | : TargetPassConfig(TM, PM) {} | 
|  |  | 
|  | BPFTargetMachine &getBPFTargetMachine() const { | 
|  | return getTM<BPFTargetMachine>(); | 
|  | } | 
|  |  | 
|  | bool addInstSelector() override; | 
|  | void addMachineSSAOptimization() override; | 
|  | void addPreEmitPass() override; | 
|  | }; | 
|  | } | 
|  |  | 
|  | TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) { | 
|  | return new BPFPassConfig(*this, PM); | 
|  | } | 
|  |  | 
|  | // Install an instruction selector pass using | 
|  | // the ISelDag to gen BPF code. | 
|  | bool BPFPassConfig::addInstSelector() { | 
|  | addPass(createBPFISelDag(getBPFTargetMachine())); | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void BPFPassConfig::addMachineSSAOptimization() { | 
|  | // The default implementation must be called first as we want eBPF | 
|  | // Peephole ran at last. | 
|  | TargetPassConfig::addMachineSSAOptimization(); | 
|  |  | 
|  | const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl(); | 
|  | if (Subtarget->getHasAlu32() && !DisableMIPeephole) | 
|  | addPass(createBPFMIPeepholePass()); | 
|  | } | 
|  |  | 
|  | void BPFPassConfig::addPreEmitPass() { | 
|  | const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl(); | 
|  |  | 
|  | addPass(createBPFMIPreEmitCheckingPass()); | 
|  | if (getOptLevel() != CodeGenOpt::None) | 
|  | if (Subtarget->getHasAlu32() && !DisableMIPeephole) | 
|  | addPass(createBPFMIPreEmitPeepholePass()); | 
|  | } |