| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 1 | //===-- BPFTargetMachine.cpp - Define TargetMachine for BPF ---------------===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | // | 
|  | 9 | // Implements the info about BPF target spec. | 
|  | 10 | // | 
|  | 11 | //===----------------------------------------------------------------------===// | 
|  | 12 |  | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 13 | #include "BPFTargetMachine.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 14 | #include "BPF.h" | 
| Yonghong Song | 03e1c8b | 2018-03-01 23:04:59 +0000 | [diff] [blame] | 15 | #include "MCTargetDesc/BPFMCAsmInfo.h" | 
| Richard Trieu | a68ee93 | 2019-05-14 22:54:06 +0000 | [diff] [blame] | 16 | #include "TargetInfo/BPFTargetInfo.h" | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 17 | #include "llvm/CodeGen/Passes.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" | 
| Matthias Braun | 31d19d4 | 2016-05-10 03:21:59 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/TargetPassConfig.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 20 | #include "llvm/IR/LegacyPassManager.h" | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 21 | #include "llvm/Support/FormattedStream.h" | 
|  | 22 | #include "llvm/Support/TargetRegistry.h" | 
|  | 23 | #include "llvm/Target/TargetOptions.h" | 
|  | 24 | using namespace llvm; | 
|  | 25 |  | 
| Yonghong Song | 60fed1f | 2018-02-23 23:49:32 +0000 | [diff] [blame] | 26 | static cl:: | 
|  | 27 | opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden, | 
|  | 28 | cl::desc("Disable machine peepholes for BPF")); | 
|  | 29 |  | 
| Tom Stellard | 4b0b261 | 2019-06-11 03:21:13 +0000 | [diff] [blame] | 30 | extern "C" void LLVMInitializeBPFTarget() { | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 31 | // Register the target. | 
| Mehdi Amini | f42454b | 2016-10-09 23:00:34 +0000 | [diff] [blame] | 32 | RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget()); | 
|  | 33 | RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget()); | 
|  | 34 | RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget()); | 
| Yonghong Song | 60fed1f | 2018-02-23 23:49:32 +0000 | [diff] [blame] | 35 |  | 
|  | 36 | PassRegistry &PR = *PassRegistry::getPassRegistry(); | 
| Yonghong Song | d3d88d0 | 2019-07-09 15:28:41 +0000 | [diff] [blame] | 37 | initializeBPFAbstractMemberAccessPass(PR); | 
| Yonghong Song | 60fed1f | 2018-02-23 23:49:32 +0000 | [diff] [blame] | 38 | initializeBPFMIPeepholePass(PR); | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 39 | } | 
|  | 40 |  | 
| Alexei Starovoitov | 310dead | 2015-06-04 19:15:05 +0000 | [diff] [blame] | 41 | // DataLayout: little or big endian | 
| Daniel Sanders | 3e5de88 | 2015-06-11 19:41:26 +0000 | [diff] [blame] | 42 | static std::string computeDataLayout(const Triple &TT) { | 
|  | 43 | if (TT.getArch() == Triple::bpfeb) | 
| Alexei Starovoitov | 310dead | 2015-06-04 19:15:05 +0000 | [diff] [blame] | 44 | return "E-m:e-p:64:64-i64:64-n32:64-S128"; | 
|  | 45 | else | 
|  | 46 | return "e-m:e-p:64:64-i64:64-n32:64-S128"; | 
|  | 47 | } | 
|  | 48 |  | 
| Rafael Espindola | 8c34dd8 | 2016-05-18 22:04:49 +0000 | [diff] [blame] | 49 | static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { | 
|  | 50 | if (!RM.hasValue()) | 
|  | 51 | return Reloc::PIC_; | 
|  | 52 | return *RM; | 
|  | 53 | } | 
|  | 54 |  | 
| Daniel Sanders | 3e5de88 | 2015-06-11 19:41:26 +0000 | [diff] [blame] | 55 | BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT, | 
|  | 56 | StringRef CPU, StringRef FS, | 
|  | 57 | const TargetOptions &Options, | 
| Rafael Espindola | 8c34dd8 | 2016-05-18 22:04:49 +0000 | [diff] [blame] | 58 | Optional<Reloc::Model> RM, | 
| Rafael Espindola | 79e238a | 2017-08-03 02:16:21 +0000 | [diff] [blame] | 59 | Optional<CodeModel::Model> CM, | 
|  | 60 | CodeGenOpt::Level OL, bool JIT) | 
| Matthias Braun | bb8507e | 2017-10-12 22:57:28 +0000 | [diff] [blame] | 61 | : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, | 
| David Green | ca29c27 | 2018-12-07 12:10:23 +0000 | [diff] [blame] | 62 | getEffectiveRelocModel(RM), | 
|  | 63 | getEffectiveCodeModel(CM, CodeModel::Small), OL), | 
| Jonas Devlieghere | 0eaee54 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 64 | TLOF(std::make_unique<TargetLoweringObjectFileELF>()), | 
| Daniel Sanders | c81f450 | 2015-06-16 15:44:21 +0000 | [diff] [blame] | 65 | Subtarget(TT, CPU, FS, *this) { | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 66 | initAsmInfo(); | 
| Yonghong Song | 03e1c8b | 2018-03-01 23:04:59 +0000 | [diff] [blame] | 67 |  | 
| Fangrui Song | 10a2162 | 2018-09-25 06:19:31 +0000 | [diff] [blame] | 68 | BPFMCAsmInfo *MAI = | 
|  | 69 | static_cast<BPFMCAsmInfo *>(const_cast<MCAsmInfo *>(AsmInfo.get())); | 
| Yonghong Song | 03e1c8b | 2018-03-01 23:04:59 +0000 | [diff] [blame] | 70 | MAI->setDwarfUsesRelocationsAcrossSections(!Subtarget.getUseDwarfRIS()); | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 71 | } | 
| Yonghong Song | d3d88d0 | 2019-07-09 15:28:41 +0000 | [diff] [blame] | 72 |  | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 73 | namespace { | 
|  | 74 | // BPF Code Generator Pass Configuration Options. | 
|  | 75 | class BPFPassConfig : public TargetPassConfig { | 
|  | 76 | public: | 
| Matthias Braun | 5e394c3 | 2017-05-30 21:36:41 +0000 | [diff] [blame] | 77 | BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM) | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 78 | : TargetPassConfig(TM, PM) {} | 
|  | 79 |  | 
|  | 80 | BPFTargetMachine &getBPFTargetMachine() const { | 
|  | 81 | return getTM<BPFTargetMachine>(); | 
|  | 82 | } | 
|  | 83 |  | 
| Yonghong Song | d3d88d0 | 2019-07-09 15:28:41 +0000 | [diff] [blame] | 84 | void addIRPasses() override; | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 85 | bool addInstSelector() override; | 
| Yonghong Song | 60fed1f | 2018-02-23 23:49:32 +0000 | [diff] [blame] | 86 | void addMachineSSAOptimization() override; | 
| Yonghong Song | e91802f | 2018-03-13 06:47:06 +0000 | [diff] [blame] | 87 | void addPreEmitPass() override; | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 88 | }; | 
| Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 89 | } | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 90 |  | 
|  | 91 | TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) { | 
| Matthias Braun | 5e394c3 | 2017-05-30 21:36:41 +0000 | [diff] [blame] | 92 | return new BPFPassConfig(*this, PM); | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 93 | } | 
|  | 94 |  | 
| Yonghong Song | d3d88d0 | 2019-07-09 15:28:41 +0000 | [diff] [blame] | 95 | void BPFPassConfig::addIRPasses() { | 
|  | 96 |  | 
|  | 97 | addPass(createBPFAbstractMemberAccess()); | 
|  | 98 |  | 
|  | 99 | TargetPassConfig::addIRPasses(); | 
|  | 100 | } | 
|  | 101 |  | 
| Alexei Starovoitov | e4c8c80 | 2015-01-24 17:51:26 +0000 | [diff] [blame] | 102 | // Install an instruction selector pass using | 
|  | 103 | // the ISelDag to gen BPF code. | 
|  | 104 | bool BPFPassConfig::addInstSelector() { | 
|  | 105 | addPass(createBPFISelDag(getBPFTargetMachine())); | 
|  | 106 |  | 
|  | 107 | return false; | 
|  | 108 | } | 
| Yonghong Song | 60fed1f | 2018-02-23 23:49:32 +0000 | [diff] [blame] | 109 |  | 
|  | 110 | void BPFPassConfig::addMachineSSAOptimization() { | 
| Yonghong Song | d3d88d0 | 2019-07-09 15:28:41 +0000 | [diff] [blame] | 111 | addPass(createBPFMISimplifyPatchablePass()); | 
|  | 112 |  | 
| Yonghong Song | 60fed1f | 2018-02-23 23:49:32 +0000 | [diff] [blame] | 113 | // The default implementation must be called first as we want eBPF | 
|  | 114 | // Peephole ran at last. | 
|  | 115 | TargetPassConfig::addMachineSSAOptimization(); | 
|  | 116 |  | 
|  | 117 | const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl(); | 
|  | 118 | if (Subtarget->getHasAlu32() && !DisableMIPeephole) | 
|  | 119 | addPass(createBPFMIPeepholePass()); | 
|  | 120 | } | 
| Yonghong Song | e91802f | 2018-03-13 06:47:06 +0000 | [diff] [blame] | 121 |  | 
|  | 122 | void BPFPassConfig::addPreEmitPass() { | 
|  | 123 | const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl(); | 
|  | 124 |  | 
| Yonghong Song | 150ca51 | 2018-09-20 22:24:27 +0000 | [diff] [blame] | 125 | addPass(createBPFMIPreEmitCheckingPass()); | 
| Yonghong Song | e91802f | 2018-03-13 06:47:06 +0000 | [diff] [blame] | 126 | if (getOptLevel() != CodeGenOpt::None) | 
|  | 127 | if (Subtarget->getHasAlu32() && !DisableMIPeephole) | 
|  | 128 | addPass(createBPFMIPreEmitPeepholePass()); | 
|  | 129 | } |