/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/BPF/BPFTargetMachine.cpp
Line | Count | Source |
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 | | using namespace llvm; |
25 | | |
26 | | static cl:: |
27 | | opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden, |
28 | | cl::desc("Disable machine peepholes for BPF")); |
29 | | |
30 | 139k | extern "C" void LLVMInitializeBPFTarget() { |
31 | 139k | // Register the target. |
32 | 139k | RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget()); |
33 | 139k | RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget()); |
34 | 139k | RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget()); |
35 | 139k | |
36 | 139k | PassRegistry &PR = *PassRegistry::getPassRegistry(); |
37 | 139k | initializeBPFAbstractMemberAccessPass(PR); |
38 | 139k | initializeBPFMIPeepholePass(PR); |
39 | 139k | } |
40 | | |
41 | | // DataLayout: little or big endian |
42 | 212 | static std::string computeDataLayout(const Triple &TT) { |
43 | 212 | if (TT.getArch() == Triple::bpfeb) |
44 | 83 | return "E-m:e-p:64:64-i64:64-n32:64-S128"; |
45 | 129 | else |
46 | 129 | return "e-m:e-p:64:64-i64:64-n32:64-S128"; |
47 | 212 | } |
48 | | |
49 | 212 | static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { |
50 | 212 | if (!RM.hasValue()) |
51 | 206 | return Reloc::PIC_; |
52 | 6 | return *RM; |
53 | 6 | } |
54 | | |
55 | | BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT, |
56 | | StringRef CPU, StringRef FS, |
57 | | const TargetOptions &Options, |
58 | | Optional<Reloc::Model> RM, |
59 | | Optional<CodeModel::Model> CM, |
60 | | CodeGenOpt::Level OL, bool JIT) |
61 | | : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, |
62 | | getEffectiveRelocModel(RM), |
63 | | getEffectiveCodeModel(CM, CodeModel::Small), OL), |
64 | | TLOF(make_unique<TargetLoweringObjectFileELF>()), |
65 | 212 | Subtarget(TT, CPU, FS, *this) { |
66 | 212 | initAsmInfo(); |
67 | 212 | |
68 | 212 | BPFMCAsmInfo *MAI = |
69 | 212 | static_cast<BPFMCAsmInfo *>(const_cast<MCAsmInfo *>(AsmInfo.get())); |
70 | 212 | MAI->setDwarfUsesRelocationsAcrossSections(!Subtarget.getUseDwarfRIS()); |
71 | 212 | } |
72 | | |
73 | | namespace { |
74 | | // BPF Code Generator Pass Configuration Options. |
75 | | class BPFPassConfig : public TargetPassConfig { |
76 | | public: |
77 | | BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM) |
78 | 206 | : TargetPassConfig(TM, PM) {} |
79 | | |
80 | 618 | BPFTargetMachine &getBPFTargetMachine() const { |
81 | 618 | return getTM<BPFTargetMachine>(); |
82 | 618 | } |
83 | | |
84 | | void addIRPasses() override; |
85 | | bool addInstSelector() override; |
86 | | void addMachineSSAOptimization() override; |
87 | | void addPreEmitPass() override; |
88 | | }; |
89 | | } |
90 | | |
91 | 206 | TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) { |
92 | 206 | return new BPFPassConfig(*this, PM); |
93 | 206 | } |
94 | | |
95 | 206 | void BPFPassConfig::addIRPasses() { |
96 | 206 | |
97 | 206 | addPass(createBPFAbstractMemberAccess()); |
98 | 206 | |
99 | 206 | TargetPassConfig::addIRPasses(); |
100 | 206 | } |
101 | | |
102 | | // Install an instruction selector pass using |
103 | | // the ISelDag to gen BPF code. |
104 | 206 | bool BPFPassConfig::addInstSelector() { |
105 | 206 | addPass(createBPFISelDag(getBPFTargetMachine())); |
106 | 206 | |
107 | 206 | return false; |
108 | 206 | } |
109 | | |
110 | 206 | void BPFPassConfig::addMachineSSAOptimization() { |
111 | 206 | addPass(createBPFMISimplifyPatchablePass()); |
112 | 206 | |
113 | 206 | // The default implementation must be called first as we want eBPF |
114 | 206 | // Peephole ran at last. |
115 | 206 | TargetPassConfig::addMachineSSAOptimization(); |
116 | 206 | |
117 | 206 | const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl(); |
118 | 206 | if (Subtarget->getHasAlu32() && !DisableMIPeephole8 ) |
119 | 8 | addPass(createBPFMIPeepholePass()); |
120 | 206 | } |
121 | | |
122 | 206 | void BPFPassConfig::addPreEmitPass() { |
123 | 206 | const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl(); |
124 | 206 | |
125 | 206 | addPass(createBPFMIPreEmitCheckingPass()); |
126 | 206 | if (getOptLevel() != CodeGenOpt::None) |
127 | 206 | if (Subtarget->getHasAlu32() && !DisableMIPeephole8 ) |
128 | 8 | addPass(createBPFMIPreEmitPeepholePass()); |
129 | 206 | } |