/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MipsTargetMachine.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===// |
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 Mips target spec. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "MipsTargetMachine.h" |
14 | | #include "MCTargetDesc/MipsABIInfo.h" |
15 | | #include "MCTargetDesc/MipsMCTargetDesc.h" |
16 | | #include "Mips.h" |
17 | | #include "Mips16ISelDAGToDAG.h" |
18 | | #include "MipsSEISelDAGToDAG.h" |
19 | | #include "MipsSubtarget.h" |
20 | | #include "MipsTargetObjectFile.h" |
21 | | #include "TargetInfo/MipsTargetInfo.h" |
22 | | #include "llvm/ADT/Optional.h" |
23 | | #include "llvm/ADT/STLExtras.h" |
24 | | #include "llvm/ADT/StringRef.h" |
25 | | #include "llvm/Analysis/TargetTransformInfo.h" |
26 | | #include "llvm/CodeGen/GlobalISel/IRTranslator.h" |
27 | | #include "llvm/CodeGen/GlobalISel/Legalizer.h" |
28 | | #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" |
29 | | #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" |
30 | | #include "llvm/CodeGen/BasicTTIImpl.h" |
31 | | #include "llvm/CodeGen/MachineFunction.h" |
32 | | #include "llvm/CodeGen/Passes.h" |
33 | | #include "llvm/CodeGen/TargetPassConfig.h" |
34 | | #include "llvm/IR/Attributes.h" |
35 | | #include "llvm/IR/Function.h" |
36 | | #include "llvm/Support/CodeGen.h" |
37 | | #include "llvm/Support/Debug.h" |
38 | | #include "llvm/Support/TargetRegistry.h" |
39 | | #include "llvm/Support/raw_ostream.h" |
40 | | #include "llvm/Target/TargetOptions.h" |
41 | | #include <string> |
42 | | |
43 | | using namespace llvm; |
44 | | |
45 | | #define DEBUG_TYPE "mips" |
46 | | |
47 | 139k | extern "C" void LLVMInitializeMipsTarget() { |
48 | 139k | // Register the target. |
49 | 139k | RegisterTargetMachine<MipsebTargetMachine> X(getTheMipsTarget()); |
50 | 139k | RegisterTargetMachine<MipselTargetMachine> Y(getTheMipselTarget()); |
51 | 139k | RegisterTargetMachine<MipsebTargetMachine> A(getTheMips64Target()); |
52 | 139k | RegisterTargetMachine<MipselTargetMachine> B(getTheMips64elTarget()); |
53 | 139k | |
54 | 139k | PassRegistry *PR = PassRegistry::getPassRegistry(); |
55 | 139k | initializeGlobalISel(*PR); |
56 | 139k | initializeMipsDelaySlotFillerPass(*PR); |
57 | 139k | initializeMipsBranchExpansionPass(*PR); |
58 | 139k | initializeMicroMipsSizeReducePass(*PR); |
59 | 139k | initializeMipsPreLegalizerCombinerPass(*PR); |
60 | 139k | } |
61 | | |
62 | | static std::string computeDataLayout(const Triple &TT, StringRef CPU, |
63 | | const TargetOptions &Options, |
64 | 2.38k | bool isLittle) { |
65 | 2.38k | std::string Ret; |
66 | 2.38k | MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions); |
67 | 2.38k | |
68 | 2.38k | // There are both little and big endian mips. |
69 | 2.38k | if (isLittle) |
70 | 1.20k | Ret += "e"; |
71 | 1.17k | else |
72 | 1.17k | Ret += "E"; |
73 | 2.38k | |
74 | 2.38k | if (ABI.IsO32()) |
75 | 1.57k | Ret += "-m:m"; |
76 | 806 | else |
77 | 806 | Ret += "-m:e"; |
78 | 2.38k | |
79 | 2.38k | // Pointers are 32 bit on some ABIs. |
80 | 2.38k | if (!ABI.IsN64()) |
81 | 1.69k | Ret += "-p:32:32"; |
82 | 2.38k | |
83 | 2.38k | // 8 and 16 bit integers only need to have natural alignment, but try to |
84 | 2.38k | // align them to 32 bits. 64 bit integers have natural alignment. |
85 | 2.38k | Ret += "-i8:8:32-i16:16:32-i64:64"; |
86 | 2.38k | |
87 | 2.38k | // 32 bit registers are always available and the stack is at least 64 bit |
88 | 2.38k | // aligned. On N64 64 bit registers are also available and the stack is |
89 | 2.38k | // 128 bit aligned. |
90 | 2.38k | if (ABI.IsN64() || ABI.IsN32()1.69k ) |
91 | 806 | Ret += "-n32:64-S128"; |
92 | 1.57k | else |
93 | 1.57k | Ret += "-n32-S64"; |
94 | 2.38k | |
95 | 2.38k | return Ret; |
96 | 2.38k | } |
97 | | |
98 | | static Reloc::Model getEffectiveRelocModel(bool JIT, |
99 | 2.38k | Optional<Reloc::Model> RM) { |
100 | 2.38k | if (!RM.hasValue() || JIT1.18k ) |
101 | 1.20k | return Reloc::Static; |
102 | 1.18k | return *RM; |
103 | 1.18k | } |
104 | | |
105 | | // On function prologue, the stack is created by decrementing |
106 | | // its pointer. Once decremented, all references are done with positive |
107 | | // offset from the stack/frame pointer, using StackGrowsUp enables |
108 | | // an easier handling. |
109 | | // Using CodeModel::Large enables different CALL behavior. |
110 | | MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT, |
111 | | StringRef CPU, StringRef FS, |
112 | | const TargetOptions &Options, |
113 | | Optional<Reloc::Model> RM, |
114 | | Optional<CodeModel::Model> CM, |
115 | | CodeGenOpt::Level OL, bool JIT, |
116 | | bool isLittle) |
117 | | : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT, |
118 | | CPU, FS, Options, getEffectiveRelocModel(JIT, RM), |
119 | | getEffectiveCodeModel(CM, CodeModel::Small), OL), |
120 | | isLittle(isLittle), TLOF(llvm::make_unique<MipsTargetObjectFile>()), |
121 | | ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)), |
122 | | Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this, |
123 | | Options.StackAlignmentOverride), |
124 | | NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", |
125 | | isLittle, *this, Options.StackAlignmentOverride), |
126 | | Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", |
127 | 2.38k | isLittle, *this, Options.StackAlignmentOverride) { |
128 | 2.38k | Subtarget = &DefaultSubtarget; |
129 | 2.38k | initAsmInfo(); |
130 | 2.38k | } |
131 | | |
132 | 2.31k | MipsTargetMachine::~MipsTargetMachine() = default; |
133 | | |
134 | 0 | void MipsebTargetMachine::anchor() {} |
135 | | |
136 | | MipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT, |
137 | | StringRef CPU, StringRef FS, |
138 | | const TargetOptions &Options, |
139 | | Optional<Reloc::Model> RM, |
140 | | Optional<CodeModel::Model> CM, |
141 | | CodeGenOpt::Level OL, bool JIT) |
142 | 1.17k | : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {} |
143 | | |
144 | 0 | void MipselTargetMachine::anchor() {} |
145 | | |
146 | | MipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT, |
147 | | StringRef CPU, StringRef FS, |
148 | | const TargetOptions &Options, |
149 | | Optional<Reloc::Model> RM, |
150 | | Optional<CodeModel::Model> CM, |
151 | | CodeGenOpt::Level OL, bool JIT) |
152 | 1.20k | : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {} |
153 | | |
154 | | const MipsSubtarget * |
155 | 180k | MipsTargetMachine::getSubtargetImpl(const Function &F) const { |
156 | 180k | Attribute CPUAttr = F.getFnAttribute("target-cpu"); |
157 | 180k | Attribute FSAttr = F.getFnAttribute("target-features"); |
158 | 180k | |
159 | 180k | std::string CPU = !CPUAttr.hasAttribute(Attribute::None) |
160 | 180k | ? CPUAttr.getValueAsString().str()115k |
161 | 180k | : TargetCPU65.0k ; |
162 | 180k | std::string FS = !FSAttr.hasAttribute(Attribute::None) |
163 | 180k | ? FSAttr.getValueAsString().str()80.2k |
164 | 180k | : TargetFS100k ; |
165 | 180k | bool hasMips16Attr = |
166 | 180k | !F.getFnAttribute("mips16").hasAttribute(Attribute::None); |
167 | 180k | bool hasNoMips16Attr = |
168 | 180k | !F.getFnAttribute("nomips16").hasAttribute(Attribute::None); |
169 | 180k | |
170 | 180k | bool HasMicroMipsAttr = |
171 | 180k | !F.getFnAttribute("micromips").hasAttribute(Attribute::None); |
172 | 180k | bool HasNoMicroMipsAttr = |
173 | 180k | !F.getFnAttribute("nomicromips").hasAttribute(Attribute::None); |
174 | 180k | |
175 | 180k | // FIXME: This is related to the code below to reset the target options, |
176 | 180k | // we need to know whether or not the soft float flag is set on the |
177 | 180k | // function, so we can enable it as a subtarget feature. |
178 | 180k | bool softFloat = |
179 | 180k | F.hasFnAttribute("use-soft-float") && |
180 | 180k | F.getFnAttribute("use-soft-float").getValueAsString() == "true"3.37k ; |
181 | 180k | |
182 | 180k | if (hasMips16Attr) |
183 | 148 | FS += FS.empty() ? "+mips16"99 : ",+mips16"49 ; |
184 | 180k | else if (hasNoMips16Attr) |
185 | 524 | FS += FS.empty() ? "-mips16"92 : ",-mips16"432 ; |
186 | 180k | if (HasMicroMipsAttr) |
187 | 28 | FS += FS.empty() ? "+micromips"14 : ",+micromips"14 ; |
188 | 180k | else if (HasNoMicroMipsAttr) |
189 | 0 | FS += FS.empty() ? "-micromips" : ",-micromips"; |
190 | 180k | if (softFloat) |
191 | 328 | FS += FS.empty() ? "+soft-float"0 : ",+soft-float"; |
192 | 180k | |
193 | 180k | auto &I = SubtargetMap[CPU + FS]; |
194 | 180k | if (!I) { |
195 | 2.20k | // This needs to be done before we create a new subtarget since any |
196 | 2.20k | // creation will depend on the TM and the code generation flags on the |
197 | 2.20k | // function that reside in TargetOptions. |
198 | 2.20k | resetTargetOptions(F); |
199 | 2.20k | I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle, *this, |
200 | 2.20k | Options.StackAlignmentOverride); |
201 | 2.20k | } |
202 | 180k | return I.get(); |
203 | 180k | } |
204 | | |
205 | 12.8k | void MipsTargetMachine::resetSubtarget(MachineFunction *MF) { |
206 | 12.8k | LLVM_DEBUG(dbgs() << "resetSubtarget\n"); |
207 | 12.8k | |
208 | 12.8k | Subtarget = &MF->getSubtarget<MipsSubtarget>(); |
209 | 12.8k | } |
210 | | |
211 | | namespace { |
212 | | |
213 | | /// Mips Code Generator Pass Configuration Options. |
214 | | class MipsPassConfig : public TargetPassConfig { |
215 | | public: |
216 | | MipsPassConfig(MipsTargetMachine &TM, PassManagerBase &PM) |
217 | 2.22k | : TargetPassConfig(TM, PM) { |
218 | 2.22k | // The current implementation of long branch pass requires a scratch |
219 | 2.22k | // register ($at) to be available before branch instructions. Tail merging |
220 | 2.22k | // can break this requirement, so disable it when long branch pass is |
221 | 2.22k | // enabled. |
222 | 2.22k | EnableTailMerge = !getMipsSubtarget().enableLongBranchPass(); |
223 | 2.22k | } |
224 | | |
225 | 10.4k | MipsTargetMachine &getMipsTargetMachine() const { |
226 | 10.4k | return getTM<MipsTargetMachine>(); |
227 | 10.4k | } |
228 | | |
229 | 6.40k | const MipsSubtarget &getMipsSubtarget() const { |
230 | 6.40k | return *getMipsTargetMachine().getSubtargetImpl(); |
231 | 6.40k | } |
232 | | |
233 | | void addIRPasses() override; |
234 | | bool addInstSelector() override; |
235 | | void addPreEmitPass() override; |
236 | | void addPreRegAlloc() override; |
237 | | bool addIRTranslator() override; |
238 | | void addPreLegalizeMachineIR() override; |
239 | | bool addLegalizeMachineIR() override; |
240 | | bool addRegBankSelect() override; |
241 | | bool addGlobalInstructionSelect() override; |
242 | | |
243 | | std::unique_ptr<CSEConfigBase> getCSEConfig() const override; |
244 | | }; |
245 | | |
246 | | } // end anonymous namespace |
247 | | |
248 | 2.22k | TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { |
249 | 2.22k | return new MipsPassConfig(*this, PM); |
250 | 2.22k | } |
251 | | |
252 | 962 | std::unique_ptr<CSEConfigBase> MipsPassConfig::getCSEConfig() const { |
253 | 962 | return getStandardCSEConfigForOpt(TM->getOptLevel()); |
254 | 962 | } |
255 | | |
256 | 2.09k | void MipsPassConfig::addIRPasses() { |
257 | 2.09k | TargetPassConfig::addIRPasses(); |
258 | 2.09k | addPass(createAtomicExpandPass()); |
259 | 2.09k | if (getMipsSubtarget().os16()) |
260 | 7 | addPass(createMipsOs16Pass()); |
261 | 2.09k | if (getMipsSubtarget().inMips16HardFloat()) |
262 | 174 | addPass(createMips16HardFloatPass()); |
263 | 2.09k | } |
264 | | // Install an instruction selector pass using |
265 | | // the ISelDag to gen Mips code. |
266 | 2.03k | bool MipsPassConfig::addInstSelector() { |
267 | 2.03k | addPass(createMipsModuleISelDagPass()); |
268 | 2.03k | addPass(createMips16ISelDag(getMipsTargetMachine(), getOptLevel())); |
269 | 2.03k | addPass(createMipsSEISelDag(getMipsTargetMachine(), getOptLevel())); |
270 | 2.03k | return false; |
271 | 2.03k | } |
272 | | |
273 | 2.09k | void MipsPassConfig::addPreRegAlloc() { |
274 | 2.09k | addPass(createMipsOptimizePICCallPass()); |
275 | 2.09k | } |
276 | | |
277 | | TargetTransformInfo |
278 | 90.4k | MipsTargetMachine::getTargetTransformInfo(const Function &F) { |
279 | 90.4k | if (Subtarget->allowMixed16_32()) { |
280 | 3.10k | LLVM_DEBUG(errs() << "No Target Transform Info Pass Added\n"); |
281 | 3.10k | // FIXME: This is no longer necessary as the TTI returned is per-function. |
282 | 3.10k | return TargetTransformInfo(F.getParent()->getDataLayout()); |
283 | 3.10k | } |
284 | 87.3k | |
285 | 87.3k | LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n"); |
286 | 87.3k | return TargetTransformInfo(BasicTTIImpl(this, F)); |
287 | 87.3k | } |
288 | | |
289 | | // Implemented by targets that want to run passes immediately before |
290 | | // machine code is emitted. return true if -print-machineinstrs should |
291 | | // print out the code after the passes. |
292 | 2.09k | void MipsPassConfig::addPreEmitPass() { |
293 | 2.09k | // Expand pseudo instructions that are sensitive to register allocation. |
294 | 2.09k | addPass(createMipsExpandPseudoPass()); |
295 | 2.09k | |
296 | 2.09k | // The microMIPS size reduction pass performs instruction reselection for |
297 | 2.09k | // instructions which can be remapped to a 16 bit instruction. |
298 | 2.09k | addPass(createMicroMipsSizeReducePass()); |
299 | 2.09k | |
300 | 2.09k | // The delay slot filler pass can potientially create forbidden slot hazards |
301 | 2.09k | // for MIPSR6 and therefore it should go before MipsBranchExpansion pass. |
302 | 2.09k | addPass(createMipsDelaySlotFillerPass()); |
303 | 2.09k | |
304 | 2.09k | // This pass expands branches and takes care about the forbidden slot hazards. |
305 | 2.09k | // Expanding branches may potentially create forbidden slot hazards for |
306 | 2.09k | // MIPSR6, and fixing such hazard may potentially break a branch by extending |
307 | 2.09k | // its offset out of range. That's why this pass combine these two tasks, and |
308 | 2.09k | // runs them alternately until one of them finishes without any changes. Only |
309 | 2.09k | // then we can be sure that all branches are expanded properly and no hazards |
310 | 2.09k | // exists. |
311 | 2.09k | // Any new pass should go before this pass. |
312 | 2.09k | addPass(createMipsBranchExpansion()); |
313 | 2.09k | |
314 | 2.09k | addPass(createMipsConstantIslandPass()); |
315 | 2.09k | } |
316 | | |
317 | 57 | bool MipsPassConfig::addIRTranslator() { |
318 | 57 | addPass(new IRTranslator()); |
319 | 57 | return false; |
320 | 57 | } |
321 | | |
322 | 57 | void MipsPassConfig::addPreLegalizeMachineIR() { |
323 | 57 | addPass(createMipsPreLegalizeCombiner()); |
324 | 57 | } |
325 | | |
326 | 57 | bool MipsPassConfig::addLegalizeMachineIR() { |
327 | 57 | addPass(new Legalizer()); |
328 | 57 | return false; |
329 | 57 | } |
330 | | |
331 | 57 | bool MipsPassConfig::addRegBankSelect() { |
332 | 57 | addPass(new RegBankSelect()); |
333 | 57 | return false; |
334 | 57 | } |
335 | | |
336 | 57 | bool MipsPassConfig::addGlobalInstructionSelect() { |
337 | 57 | addPass(new InstructionSelect()); |
338 | 57 | return false; |
339 | 57 | } |