/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/ARMTargetMachine.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "ARM.h" |
14 | | #include "ARMSubtarget.h" |
15 | | #include "ARMMacroFusion.h" |
16 | | #include "ARMTargetMachine.h" |
17 | | #include "ARMTargetObjectFile.h" |
18 | | #include "ARMTargetTransformInfo.h" |
19 | | #include "MCTargetDesc/ARMMCTargetDesc.h" |
20 | | #include "llvm/ADT/Optional.h" |
21 | | #include "llvm/ADT/STLExtras.h" |
22 | | #include "llvm/ADT/StringRef.h" |
23 | | #include "llvm/ADT/Triple.h" |
24 | | #include "llvm/Analysis/TargetTransformInfo.h" |
25 | | #include "llvm/CodeGen/ExecutionDepsFix.h" |
26 | | #include "llvm/CodeGen/GlobalISel/CallLowering.h" |
27 | | #include "llvm/CodeGen/GlobalISel/IRTranslator.h" |
28 | | #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" |
29 | | #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" |
30 | | #include "llvm/CodeGen/GlobalISel/Legalizer.h" |
31 | | #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" |
32 | | #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" |
33 | | #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" |
34 | | #include "llvm/CodeGen/MachineFunction.h" |
35 | | #include "llvm/CodeGen/MachineScheduler.h" |
36 | | #include "llvm/CodeGen/Passes.h" |
37 | | #include "llvm/CodeGen/TargetPassConfig.h" |
38 | | #include "llvm/IR/Attributes.h" |
39 | | #include "llvm/IR/DataLayout.h" |
40 | | #include "llvm/IR/Function.h" |
41 | | #include "llvm/Pass.h" |
42 | | #include "llvm/Support/CodeGen.h" |
43 | | #include "llvm/Support/CommandLine.h" |
44 | | #include "llvm/Support/ErrorHandling.h" |
45 | | #include "llvm/Support/TargetParser.h" |
46 | | #include "llvm/Support/TargetRegistry.h" |
47 | | #include "llvm/Target/TargetLoweringObjectFile.h" |
48 | | #include "llvm/Target/TargetOptions.h" |
49 | | #include "llvm/Transforms/Scalar.h" |
50 | | #include <cassert> |
51 | | #include <memory> |
52 | | #include <string> |
53 | | |
54 | | using namespace llvm; |
55 | | |
56 | | static cl::opt<bool> |
57 | | DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, |
58 | | cl::desc("Inhibit optimization of S->D register accesses on A15"), |
59 | | cl::init(false)); |
60 | | |
61 | | static cl::opt<bool> |
62 | | EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden, |
63 | | cl::desc("Run SimplifyCFG after expanding atomic operations" |
64 | | " to make use of cmpxchg flow-based information"), |
65 | | cl::init(true)); |
66 | | |
67 | | static cl::opt<bool> |
68 | | EnableARMLoadStoreOpt("arm-load-store-opt", cl::Hidden, |
69 | | cl::desc("Enable ARM load/store optimization pass"), |
70 | | cl::init(true)); |
71 | | |
72 | | // FIXME: Unify control over GlobalMerge. |
73 | | static cl::opt<cl::boolOrDefault> |
74 | | EnableGlobalMerge("arm-global-merge", cl::Hidden, |
75 | | cl::desc("Enable the global merge pass")); |
76 | | |
77 | | namespace llvm { |
78 | | void initializeARMExecutionDepsFixPass(PassRegistry&); |
79 | | } |
80 | | |
81 | 123k | extern "C" void LLVMInitializeARMTarget() { |
82 | 123k | // Register the target. |
83 | 123k | RegisterTargetMachine<ARMLETargetMachine> X(getTheARMLETarget()); |
84 | 123k | RegisterTargetMachine<ARMLETargetMachine> A(getTheThumbLETarget()); |
85 | 123k | RegisterTargetMachine<ARMBETargetMachine> Y(getTheARMBETarget()); |
86 | 123k | RegisterTargetMachine<ARMBETargetMachine> B(getTheThumbBETarget()); |
87 | 123k | |
88 | 123k | PassRegistry &Registry = *PassRegistry::getPassRegistry(); |
89 | 123k | initializeGlobalISel(Registry); |
90 | 123k | initializeARMLoadStoreOptPass(Registry); |
91 | 123k | initializeARMPreAllocLoadStoreOptPass(Registry); |
92 | 123k | initializeARMConstantIslandsPass(Registry); |
93 | 123k | initializeARMExecutionDepsFixPass(Registry); |
94 | 123k | initializeARMExpandPseudoPass(Registry); |
95 | 123k | } |
96 | | |
97 | 4.88k | static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { |
98 | 4.88k | if (TT.isOSBinFormatMachO()) |
99 | 2.72k | return llvm::make_unique<TargetLoweringObjectFileMachO>(); |
100 | 2.15k | if (2.15k TT.isOSWindows()2.15k ) |
101 | 112 | return llvm::make_unique<TargetLoweringObjectFileCOFF>(); |
102 | 2.04k | return llvm::make_unique<ARMElfTargetObjectFile>(); |
103 | 2.04k | } |
104 | | |
105 | | static ARMBaseTargetMachine::ARMABI |
106 | | computeTargetABI(const Triple &TT, StringRef CPU, |
107 | 9.76k | const TargetOptions &Options) { |
108 | 9.76k | StringRef ABIName = Options.MCOptions.getABIName(); |
109 | 9.76k | |
110 | 9.76k | if (ABIName.empty()) |
111 | 5.94k | ABIName = ARM::computeDefaultTargetABI(TT, CPU); |
112 | 9.76k | |
113 | 9.76k | if (ABIName == "aapcs16") |
114 | 840 | return ARMBaseTargetMachine::ARM_ABI_AAPCS16; |
115 | 8.92k | else if (8.92k ABIName.startswith("aapcs")8.92k ) |
116 | 6.29k | return ARMBaseTargetMachine::ARM_ABI_AAPCS; |
117 | 2.63k | else if (2.63k ABIName.startswith("apcs")2.63k ) |
118 | 2.63k | return ARMBaseTargetMachine::ARM_ABI_APCS; |
119 | 0 |
|
120 | 0 | llvm_unreachable0 ("Unhandled/unknown ABI Name!"); |
121 | 0 | return ARMBaseTargetMachine::ARM_ABI_UNKNOWN; |
122 | 9.76k | } |
123 | | |
124 | | static std::string computeDataLayout(const Triple &TT, StringRef CPU, |
125 | | const TargetOptions &Options, |
126 | 4.88k | bool isLittle) { |
127 | 4.88k | auto ABI = computeTargetABI(TT, CPU, Options); |
128 | 4.88k | std::string Ret; |
129 | 4.88k | |
130 | 4.88k | if (isLittle) |
131 | 4.88k | // Little endian. |
132 | 4.84k | Ret += "e"; |
133 | 4.88k | else |
134 | 4.88k | // Big endian. |
135 | 41 | Ret += "E"; |
136 | 4.88k | |
137 | 4.88k | Ret += DataLayout::getManglingComponent(TT); |
138 | 4.88k | |
139 | 4.88k | // Pointers are 32 bits and aligned to 32 bits. |
140 | 4.88k | Ret += "-p:32:32"; |
141 | 4.88k | |
142 | 4.88k | // ABIs other than APCS have 64 bit integers with natural alignment. |
143 | 4.88k | if (ABI != ARMBaseTargetMachine::ARM_ABI_APCS) |
144 | 3.56k | Ret += "-i64:64"; |
145 | 4.88k | |
146 | 4.88k | // We have 64 bits floats. The APCS ABI requires them to be aligned to 32 |
147 | 4.88k | // bits, others to 64 bits. We always try to align to 64 bits. |
148 | 4.88k | if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS) |
149 | 1.31k | Ret += "-f64:32:64"; |
150 | 4.88k | |
151 | 4.88k | // We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others |
152 | 4.88k | // to 64. We always ty to give them natural alignment. |
153 | 4.88k | if (ABI == ARMBaseTargetMachine::ARM_ABI_APCS) |
154 | 1.31k | Ret += "-v64:32:64-v128:32:128"; |
155 | 3.56k | else if (3.56k ABI != ARMBaseTargetMachine::ARM_ABI_AAPCS163.56k ) |
156 | 3.14k | Ret += "-v128:64:128"; |
157 | 4.88k | |
158 | 4.88k | // Try to align aggregates to 32 bits (the default is 64 bits, which has no |
159 | 4.88k | // particular hardware support on 32-bit ARM). |
160 | 4.88k | Ret += "-a:0:32"; |
161 | 4.88k | |
162 | 4.88k | // Integer registers are 32 bits. |
163 | 4.88k | Ret += "-n32"; |
164 | 4.88k | |
165 | 4.88k | // The stack is 128 bit aligned on NaCl, 64 bit aligned on AAPCS and 32 bit |
166 | 4.88k | // aligned everywhere else. |
167 | 4.88k | if (TT.isOSNaCl() || 4.88k ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS164.87k ) |
168 | 426 | Ret += "-S128"; |
169 | 4.45k | else if (4.45k ABI == ARMBaseTargetMachine::ARM_ABI_AAPCS4.45k ) |
170 | 3.13k | Ret += "-S64"; |
171 | 4.45k | else |
172 | 1.31k | Ret += "-S32"; |
173 | 4.88k | |
174 | 4.88k | return Ret; |
175 | 4.88k | } |
176 | | |
177 | | static Reloc::Model getEffectiveRelocModel(const Triple &TT, |
178 | 4.88k | Optional<Reloc::Model> RM) { |
179 | 4.88k | if (!RM.hasValue()) |
180 | 4.88k | // Default relocation model on Darwin is PIC. |
181 | 2.40k | return TT.isOSBinFormatMachO() ? 2.40k Reloc::PIC_642 : Reloc::Static1.76k ; |
182 | 2.47k | |
183 | 2.47k | if (2.47k *RM == Reloc::ROPI || 2.47k *RM == Reloc::RWPI2.45k || *RM == Reloc::ROPI_RWPI2.44k ) |
184 | 2.47k | assert(TT.isOSBinFormatELF() && |
185 | 2.47k | "ROPI/RWPI currently only supported for ELF"); |
186 | 2.47k | |
187 | 2.47k | // DynamicNoPIC is only used on darwin. |
188 | 2.47k | if (*RM == Reloc::DynamicNoPIC && 2.47k !TT.isOSDarwin()104 ) |
189 | 37 | return Reloc::Static; |
190 | 2.44k | |
191 | 2.44k | return *RM; |
192 | 2.44k | } |
193 | | |
194 | 4.88k | static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) { |
195 | 4.88k | if (CM) |
196 | 4 | return *CM; |
197 | 4.88k | return CodeModel::Small; |
198 | 4.88k | } |
199 | | |
200 | | /// Create an ARM architecture model. |
201 | | /// |
202 | | ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT, |
203 | | StringRef CPU, StringRef FS, |
204 | | const TargetOptions &Options, |
205 | | Optional<Reloc::Model> RM, |
206 | | Optional<CodeModel::Model> CM, |
207 | | CodeGenOpt::Level OL, bool isLittle) |
208 | | : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT, |
209 | | CPU, FS, Options, getEffectiveRelocModel(TT, RM), |
210 | | getEffectiveCodeModel(CM), OL), |
211 | | TargetABI(computeTargetABI(TT, CPU, Options)), |
212 | 4.88k | TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) { |
213 | 4.88k | |
214 | 4.88k | // Default to triple-appropriate float ABI |
215 | 4.88k | if (Options.FloatABIType == FloatABI::Default4.88k ) { |
216 | 2.93k | if (TargetTriple.getEnvironment() == Triple::GNUEABIHF || |
217 | 2.81k | TargetTriple.getEnvironment() == Triple::MuslEABIHF || |
218 | 2.80k | TargetTriple.getEnvironment() == Triple::EABIHF || |
219 | 2.77k | TargetTriple.isOSWindows() || |
220 | 2.66k | TargetABI == ARMBaseTargetMachine::ARM_ABI_AAPCS16) |
221 | 300 | this->Options.FloatABIType = FloatABI::Hard; |
222 | 2.93k | else |
223 | 2.63k | this->Options.FloatABIType = FloatABI::Soft; |
224 | 2.93k | } |
225 | 4.88k | |
226 | 4.88k | // Default to triple-appropriate EABI |
227 | 4.88k | if (Options.EABIVersion == EABI::Default || |
228 | 4.88k | Options.EABIVersion == EABI::Unknown2.16k ) { |
229 | 4.84k | // musl is compatible with glibc with regard to EABI version |
230 | 4.84k | if ((TargetTriple.getEnvironment() == Triple::GNUEABI || |
231 | 4.28k | TargetTriple.getEnvironment() == Triple::GNUEABIHF || |
232 | 4.14k | TargetTriple.getEnvironment() == Triple::MuslEABI || |
233 | 4.12k | TargetTriple.getEnvironment() == Triple::MuslEABIHF) && |
234 | 719 | !(TargetTriple.isOSWindows() || 719 TargetTriple.isOSDarwin()719 )) |
235 | 719 | this->Options.EABIVersion = EABI::GNU; |
236 | 4.84k | else |
237 | 4.12k | this->Options.EABIVersion = EABI::EABI5; |
238 | 4.84k | } |
239 | 4.88k | |
240 | 4.88k | initAsmInfo(); |
241 | 4.88k | } |
242 | | |
243 | 3.01k | ARMBaseTargetMachine::~ARMBaseTargetMachine() = default; |
244 | | |
245 | | const ARMSubtarget * |
246 | 477k | ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const { |
247 | 477k | Attribute CPUAttr = F.getFnAttribute("target-cpu"); |
248 | 477k | Attribute FSAttr = F.getFnAttribute("target-features"); |
249 | 477k | |
250 | 477k | std::string CPU = !CPUAttr.hasAttribute(Attribute::None) |
251 | 336k | ? CPUAttr.getValueAsString().str() |
252 | 140k | : TargetCPU; |
253 | 477k | std::string FS = !FSAttr.hasAttribute(Attribute::None) |
254 | 372k | ? FSAttr.getValueAsString().str() |
255 | 104k | : TargetFS; |
256 | 477k | |
257 | 477k | // FIXME: This is related to the code below to reset the target options, |
258 | 477k | // we need to know whether or not the soft float flag is set on the |
259 | 477k | // function before we can generate a subtarget. We also need to use |
260 | 477k | // it as a key for the subtarget since that can be the only difference |
261 | 477k | // between two functions. |
262 | 477k | bool SoftFloat = |
263 | 477k | F.getFnAttribute("use-soft-float").getValueAsString() == "true"; |
264 | 477k | // If the soft float attribute is set on the function turn on the soft float |
265 | 477k | // subtarget feature. |
266 | 477k | if (SoftFloat) |
267 | 34.6k | FS += FS.empty() ? 34.6k "+soft-float"16 : ",+soft-float"34.6k ; |
268 | 477k | |
269 | 477k | auto &I = SubtargetMap[CPU + FS]; |
270 | 477k | if (!I477k ) { |
271 | 4.34k | // This needs to be done before we create a new subtarget since any |
272 | 4.34k | // creation will depend on the TM and the code generation flags on the |
273 | 4.34k | // function that reside in TargetOptions. |
274 | 4.34k | resetTargetOptions(F); |
275 | 4.34k | I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle); |
276 | 4.34k | |
277 | 4.34k | if (!I->isThumb() && 4.34k !I->hasARMOps()1.58k ) |
278 | 3 | F.getContext().emitError("Function '" + F.getName() + "' uses ARM " |
279 | 3 | "instructions, but the target does not support ARM mode execution."); |
280 | 4.34k | } |
281 | 477k | |
282 | 477k | return I.get(); |
283 | 477k | } |
284 | | |
285 | 10.9k | TargetIRAnalysis ARMBaseTargetMachine::getTargetIRAnalysis() { |
286 | 269k | return TargetIRAnalysis([this](const Function &F) { |
287 | 269k | return TargetTransformInfo(ARMTTIImpl(this, F)); |
288 | 269k | }); |
289 | 10.9k | } |
290 | | |
291 | | ARMLETargetMachine::ARMLETargetMachine(const Target &T, const Triple &TT, |
292 | | StringRef CPU, StringRef FS, |
293 | | const TargetOptions &Options, |
294 | | Optional<Reloc::Model> RM, |
295 | | Optional<CodeModel::Model> CM, |
296 | | CodeGenOpt::Level OL, bool JIT) |
297 | 4.84k | : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} |
298 | | |
299 | | ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT, |
300 | | StringRef CPU, StringRef FS, |
301 | | const TargetOptions &Options, |
302 | | Optional<Reloc::Model> RM, |
303 | | Optional<CodeModel::Model> CM, |
304 | | CodeGenOpt::Level OL, bool JIT) |
305 | 41 | : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} |
306 | | |
307 | | namespace { |
308 | | |
309 | | /// ARM Code Generator Pass Configuration Options. |
310 | | class ARMPassConfig : public TargetPassConfig { |
311 | | public: |
312 | | ARMPassConfig(ARMBaseTargetMachine &TM, PassManagerBase &PM) |
313 | 4.55k | : TargetPassConfig(TM, PM) {} |
314 | | |
315 | 4.36k | ARMBaseTargetMachine &getARMTargetMachine() const { |
316 | 4.36k | return getTM<ARMBaseTargetMachine>(); |
317 | 4.36k | } |
318 | | |
319 | | ScheduleDAGInstrs * |
320 | 1.55k | createMachineScheduler(MachineSchedContext *C) const override { |
321 | 1.55k | ScheduleDAGMILive *DAG = createGenericSchedLive(C); |
322 | 1.55k | // add DAG Mutations here. |
323 | 1.55k | const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>(); |
324 | 1.55k | if (ST.hasFusion()) |
325 | 3 | DAG->addMutation(createARMMacroFusionDAGMutation()); |
326 | 1.55k | return DAG; |
327 | 1.55k | } |
328 | | |
329 | | ScheduleDAGInstrs * |
330 | 2 | createPostMachineScheduler(MachineSchedContext *C) const override { |
331 | 2 | ScheduleDAGMI *DAG = createGenericSchedPostRA(C); |
332 | 2 | // add DAG Mutations here. |
333 | 2 | const ARMSubtarget &ST = C->MF->getSubtarget<ARMSubtarget>(); |
334 | 2 | if (ST.hasFusion()) |
335 | 0 | DAG->addMutation(createARMMacroFusionDAGMutation()); |
336 | 2 | return DAG; |
337 | 2 | } |
338 | | |
339 | | void addIRPasses() override; |
340 | | bool addPreISel() override; |
341 | | bool addInstSelector() override; |
342 | | bool addIRTranslator() override; |
343 | | bool addLegalizeMachineIR() override; |
344 | | bool addRegBankSelect() override; |
345 | | bool addGlobalInstructionSelect() override; |
346 | | void addPreRegAlloc() override; |
347 | | void addPreSched2() override; |
348 | | void addPreEmitPass() override; |
349 | | }; |
350 | | |
351 | | class ARMExecutionDepsFix : public ExecutionDepsFix { |
352 | | public: |
353 | | static char ID; |
354 | 4.12k | ARMExecutionDepsFix() : ExecutionDepsFix(ID, ARM::DPRRegClass) {} |
355 | 4.12k | StringRef getPassName() const override { |
356 | 4.12k | return "ARM Execution Dependency Fix"; |
357 | 4.12k | } |
358 | | }; |
359 | | char ARMExecutionDepsFix::ID; |
360 | | |
361 | | } // end anonymous namespace |
362 | | |
363 | | INITIALIZE_PASS(ARMExecutionDepsFix, "arm-execution-deps-fix", |
364 | | "ARM Execution Dependency Fix", false, false) |
365 | | |
366 | 4.55k | TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) { |
367 | 4.55k | return new ARMPassConfig(*this, PM); |
368 | 4.55k | } |
369 | | |
370 | 4.38k | void ARMPassConfig::addIRPasses() { |
371 | 4.38k | if (TM->Options.ThreadModel == ThreadModel::Single) |
372 | 1 | addPass(createLowerAtomicPass()); |
373 | 4.38k | else |
374 | 4.38k | addPass(createAtomicExpandPass()); |
375 | 4.38k | |
376 | 4.38k | // Cmpxchg instructions are often used with a subsequent comparison to |
377 | 4.38k | // determine whether it succeeded. We can exploit existing control-flow in |
378 | 4.38k | // ldrex/strex loops to simplify this, but it needs tidying up. |
379 | 4.38k | if (TM->getOptLevel() != CodeGenOpt::None && 4.38k EnableAtomicTidy4.12k ) |
380 | 4.07k | addPass(createCFGSimplificationPass(-1, [this](const Function &F) 4.07k { |
381 | 15.8k | const auto &ST = this->TM->getSubtarget<ARMSubtarget>(F); |
382 | 11.8k | return ST.hasAnyDataBarrier() && !ST.isThumb1Only(); |
383 | 4.07k | })); |
384 | 4.38k | |
385 | 4.38k | TargetPassConfig::addIRPasses(); |
386 | 4.38k | |
387 | 4.38k | // Match interleaved memory accesses to ldN/stN intrinsics. |
388 | 4.38k | if (TM->getOptLevel() != CodeGenOpt::None) |
389 | 4.12k | addPass(createInterleavedAccessPass()); |
390 | 4.38k | } |
391 | | |
392 | 4.38k | bool ARMPassConfig::addPreISel() { |
393 | 4.38k | if ((TM->getOptLevel() != CodeGenOpt::None && |
394 | 4.12k | EnableGlobalMerge == cl::BOU_UNSET) || |
395 | 4.38k | EnableGlobalMerge == cl::BOU_TRUE274 ) { |
396 | 4.12k | // FIXME: This is using the thumb1 only constant value for |
397 | 4.12k | // maximal global offset for merging globals. We may want |
398 | 4.12k | // to look into using the old value for non-thumb1 code of |
399 | 4.12k | // 4095 based on the TargetMachine, but this starts to become |
400 | 4.12k | // tricky when doing code gen per function. |
401 | 4.12k | bool OnlyOptimizeForSize = (TM->getOptLevel() < CodeGenOpt::Aggressive) && |
402 | 3.21k | (EnableGlobalMerge == cl::BOU_UNSET); |
403 | 4.12k | // Merging of extern globals is enabled by default on non-Mach-O as we |
404 | 4.12k | // expect it to be generally either beneficial or harmless. On Mach-O it |
405 | 4.12k | // is disabled as we emit the .subsections_via_symbols directive which |
406 | 4.12k | // means that merging extern globals is not safe. |
407 | 4.12k | bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO(); |
408 | 4.12k | addPass(createGlobalMergePass(TM, 127, OnlyOptimizeForSize, |
409 | 4.12k | MergeExternalByDefault)); |
410 | 4.12k | } |
411 | 4.38k | |
412 | 4.38k | return false; |
413 | 4.38k | } |
414 | | |
415 | 4.36k | bool ARMPassConfig::addInstSelector() { |
416 | 4.36k | addPass(createARMISelDag(getARMTargetMachine(), getOptLevel())); |
417 | 4.36k | return false; |
418 | 4.36k | } |
419 | | |
420 | 29 | bool ARMPassConfig::addIRTranslator() { |
421 | 29 | addPass(new IRTranslator()); |
422 | 29 | return false; |
423 | 29 | } |
424 | | |
425 | 29 | bool ARMPassConfig::addLegalizeMachineIR() { |
426 | 29 | addPass(new Legalizer()); |
427 | 29 | return false; |
428 | 29 | } |
429 | | |
430 | 29 | bool ARMPassConfig::addRegBankSelect() { |
431 | 29 | addPass(new RegBankSelect()); |
432 | 29 | return false; |
433 | 29 | } |
434 | | |
435 | 29 | bool ARMPassConfig::addGlobalInstructionSelect() { |
436 | 29 | addPass(new InstructionSelect()); |
437 | 29 | return false; |
438 | 29 | } |
439 | | |
440 | 4.38k | void ARMPassConfig::addPreRegAlloc() { |
441 | 4.38k | if (getOptLevel() != CodeGenOpt::None4.38k ) { |
442 | 4.12k | addPass(createMLxExpansionPass()); |
443 | 4.12k | |
444 | 4.12k | if (EnableARMLoadStoreOpt) |
445 | 4.12k | addPass(createARMLoadStoreOptimizationPass(/* pre-register alloc */ true)); |
446 | 4.12k | |
447 | 4.12k | if (!DisableA15SDOptimization) |
448 | 4.12k | addPass(createA15SDOptimizerPass()); |
449 | 4.12k | } |
450 | 4.38k | } |
451 | | |
452 | 4.38k | void ARMPassConfig::addPreSched2() { |
453 | 4.38k | if (getOptLevel() != CodeGenOpt::None4.38k ) { |
454 | 4.12k | if (EnableARMLoadStoreOpt) |
455 | 4.12k | addPass(createARMLoadStoreOptimizationPass()); |
456 | 4.12k | |
457 | 4.12k | addPass(new ARMExecutionDepsFix()); |
458 | 4.12k | } |
459 | 4.38k | |
460 | 4.38k | // Expand some pseudo instructions into multiple instructions to allow |
461 | 4.38k | // proper scheduling. |
462 | 4.38k | addPass(createARMExpandPseudoPass()); |
463 | 4.38k | |
464 | 4.38k | if (getOptLevel() != CodeGenOpt::None4.38k ) { |
465 | 4.12k | // in v8, IfConversion depends on Thumb instruction widths |
466 | 15.8k | addPass(createThumb2SizeReductionPass([this](const Function &F) { |
467 | 15.8k | return this->TM->getSubtarget<ARMSubtarget>(F).restrictIT(); |
468 | 15.8k | })); |
469 | 4.12k | |
470 | 15.8k | addPass(createIfConverter([](const MachineFunction &MF) { |
471 | 15.8k | return !MF.getSubtarget<ARMSubtarget>().isThumb1Only(); |
472 | 15.8k | })); |
473 | 4.12k | } |
474 | 4.38k | addPass(createThumb2ITBlockPass()); |
475 | 4.38k | } |
476 | | |
477 | 4.38k | void ARMPassConfig::addPreEmitPass() { |
478 | 4.38k | addPass(createThumb2SizeReductionPass()); |
479 | 4.38k | |
480 | 4.38k | // Constant island pass work on unbundled instructions. |
481 | 17.0k | addPass(createUnpackMachineBundles([](const MachineFunction &MF) { |
482 | 17.0k | return MF.getSubtarget<ARMSubtarget>().isThumb2(); |
483 | 17.0k | })); |
484 | 4.38k | |
485 | 4.38k | // Don't optimize barriers at -O0. |
486 | 4.38k | if (getOptLevel() != CodeGenOpt::None) |
487 | 4.12k | addPass(createARMOptimizeBarriersPass()); |
488 | 4.38k | |
489 | 4.38k | addPass(createARMConstantIslandPass()); |
490 | 4.38k | } |