1 | //===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===// |
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 Hexagon target spec. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "HexagonTargetMachine.h" |
14 | #include "Hexagon.h" |
15 | #include "HexagonISelLowering.h" |
16 | #include "HexagonLoopIdiomRecognition.h" |
17 | #include "HexagonMachineFunctionInfo.h" |
18 | #include "HexagonMachineScheduler.h" |
19 | #include "HexagonTargetObjectFile.h" |
20 | #include "HexagonTargetTransformInfo.h" |
21 | #include "HexagonVectorLoopCarriedReuse.h" |
22 | #include "TargetInfo/HexagonTargetInfo.h" |
23 | #include "llvm/CodeGen/Passes.h" |
24 | #include "llvm/CodeGen/TargetPassConfig.h" |
25 | #include "llvm/CodeGen/VLIWMachineScheduler.h" |
26 | #include "llvm/IR/Module.h" |
27 | #include "llvm/MC/TargetRegistry.h" |
28 | #include "llvm/Passes/PassBuilder.h" |
29 | #include "llvm/Support/CommandLine.h" |
30 | #include "llvm/Transforms/Scalar.h" |
31 | #include <optional> |
32 | |
33 | using namespace llvm; |
34 | |
35 | static cl::opt<bool> |
36 | EnableCExtOpt("hexagon-cext" , cl::Hidden, cl::init(Val: true), |
37 | cl::desc("Enable Hexagon constant-extender optimization" )); |
38 | |
39 | static cl::opt<bool> EnableRDFOpt("rdf-opt" , cl::Hidden, cl::init(Val: true), |
40 | cl::desc("Enable RDF-based optimizations" )); |
41 | |
42 | cl::opt<unsigned> RDFFuncBlockLimit( |
43 | "rdf-bb-limit" , cl::Hidden, cl::init(Val: 1000), |
44 | cl::desc("Basic block limit for a function for RDF optimizations" )); |
45 | |
46 | static cl::opt<bool> DisableHardwareLoops("disable-hexagon-hwloops" , |
47 | cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target" )); |
48 | |
49 | static cl::opt<bool> |
50 | DisableAModeOpt("disable-hexagon-amodeopt" , cl::Hidden, |
51 | cl::desc("Disable Hexagon Addressing Mode Optimization" )); |
52 | |
53 | static cl::opt<bool> |
54 | DisableHexagonCFGOpt("disable-hexagon-cfgopt" , cl::Hidden, |
55 | cl::desc("Disable Hexagon CFG Optimization" )); |
56 | |
57 | static cl::opt<bool> |
58 | DisableHCP("disable-hcp" , cl::Hidden, |
59 | cl::desc("Disable Hexagon constant propagation" )); |
60 | |
61 | static cl::opt<bool> DisableStoreWidening("disable-store-widen" , |
62 | cl::Hidden, cl::init(Val: false), cl::desc("Disable store widening" )); |
63 | |
64 | static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets" , |
65 | cl::init(Val: true), cl::Hidden, |
66 | cl::desc("Early expansion of MUX" )); |
67 | |
68 | static cl::opt<bool> EnableTfrCleanup("hexagon-tfr-cleanup" , cl::init(Val: true), |
69 | cl::Hidden, |
70 | cl::desc("Cleanup of TFRs/COPYs" )); |
71 | |
72 | static cl::opt<bool> EnableEarlyIf("hexagon-eif" , cl::init(Val: true), cl::Hidden, |
73 | cl::desc("Enable early if-conversion" )); |
74 | |
75 | static cl::opt<bool> EnableGenInsert("hexagon-insert" , cl::init(Val: true), |
76 | cl::Hidden, cl::desc("Generate \"insert\" instructions" )); |
77 | |
78 | static cl::opt<bool> |
79 | EnableCommGEP("hexagon-commgep" , cl::init(Val: true), cl::Hidden, |
80 | cl::desc("Enable commoning of GEP instructions" )); |
81 | |
82 | static cl::opt<bool> ("hexagon-extract" , cl::init(Val: true), |
83 | cl::Hidden, cl::desc("Generate \"extract\" instructions" )); |
84 | |
85 | static cl::opt<bool> EnableGenMux("hexagon-mux" , cl::init(Val: true), cl::Hidden, |
86 | cl::desc("Enable converting conditional transfers into MUX instructions" )); |
87 | |
88 | static cl::opt<bool> EnableGenPred("hexagon-gen-pred" , cl::init(Val: true), |
89 | cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " |
90 | "predicate instructions" )); |
91 | |
92 | static cl::opt<bool> |
93 | EnableLoopPrefetch("hexagon-loop-prefetch" , cl::Hidden, |
94 | cl::desc("Enable loop data prefetch on Hexagon" )); |
95 | |
96 | static cl::opt<bool> DisableHSDR("disable-hsdr" , cl::init(Val: false), cl::Hidden, |
97 | cl::desc("Disable splitting double registers" )); |
98 | |
99 | static cl::opt<bool> |
100 | EnableGenMemAbs("hexagon-mem-abs" , cl::init(Val: true), cl::Hidden, |
101 | cl::desc("Generate absolute set instructions" )); |
102 | |
103 | static cl::opt<bool> EnableBitSimplify("hexagon-bit" , cl::init(Val: true), |
104 | cl::Hidden, cl::desc("Bit simplification" )); |
105 | |
106 | static cl::opt<bool> EnableLoopResched("hexagon-loop-resched" , cl::init(Val: true), |
107 | cl::Hidden, cl::desc("Loop rescheduling" )); |
108 | |
109 | static cl::opt<bool> HexagonNoOpt("hexagon-noopt" , cl::init(Val: false), |
110 | cl::Hidden, cl::desc("Disable backend optimizations" )); |
111 | |
112 | static cl::opt<bool> |
113 | EnableVectorPrint("enable-hexagon-vector-print" , cl::Hidden, |
114 | cl::desc("Enable Hexagon Vector print instr pass" )); |
115 | |
116 | static cl::opt<bool> |
117 | ("hexagon-opt-vextract" , cl::Hidden, cl::init(Val: true), |
118 | cl::desc("Enable vextract optimization" )); |
119 | |
120 | static cl::opt<bool> |
121 | EnableVectorCombine("hexagon-vector-combine" , cl::Hidden, cl::init(Val: true), |
122 | cl::desc("Enable HVX vector combining" )); |
123 | |
124 | static cl::opt<bool> EnableInitialCFGCleanup( |
125 | "hexagon-initial-cfg-cleanup" , cl::Hidden, cl::init(Val: true), |
126 | cl::desc("Simplify the CFG after atomic expansion pass" )); |
127 | |
128 | static cl::opt<bool> EnableInstSimplify("hexagon-instsimplify" , cl::Hidden, |
129 | cl::init(Val: true), |
130 | cl::desc("Enable instsimplify" )); |
131 | |
132 | /// HexagonTargetMachineModule - Note that this is used on hosts that |
133 | /// cannot link in a library unless there are references into the |
134 | /// library. In particular, it seems that it is not possible to get |
135 | /// things to work on Win32 without this. Though it is unused, do not |
136 | /// remove it. |
137 | extern "C" int HexagonTargetMachineModule; |
138 | int HexagonTargetMachineModule = 0; |
139 | |
140 | static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { |
141 | ScheduleDAGMILive *DAG = new VLIWMachineScheduler( |
142 | C, std::make_unique<HexagonConvergingVLIWScheduler>()); |
143 | DAG->addMutation(Mutation: std::make_unique<HexagonSubtarget::UsrOverflowMutation>()); |
144 | DAG->addMutation(Mutation: std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>()); |
145 | DAG->addMutation(Mutation: std::make_unique<HexagonSubtarget::CallMutation>()); |
146 | DAG->addMutation(Mutation: createCopyConstrainDAGMutation(TII: DAG->TII, TRI: DAG->TRI)); |
147 | return DAG; |
148 | } |
149 | |
150 | static MachineSchedRegistry |
151 | SchedCustomRegistry("hexagon" , "Run Hexagon's custom scheduler" , |
152 | createVLIWMachineSched); |
153 | |
154 | namespace llvm { |
155 | extern char &HexagonExpandCondsetsID; |
156 | extern char &HexagonTfrCleanupID; |
157 | void initializeHexagonBitSimplifyPass(PassRegistry&); |
158 | void initializeHexagonConstExtendersPass(PassRegistry&); |
159 | void initializeHexagonConstPropagationPass(PassRegistry&); |
160 | void initializeHexagonCopyToCombinePass(PassRegistry&); |
161 | void initializeHexagonEarlyIfConversionPass(PassRegistry&); |
162 | void initializeHexagonExpandCondsetsPass(PassRegistry&); |
163 | void initializeHexagonGenMemAbsolutePass(PassRegistry &); |
164 | void initializeHexagonGenMuxPass(PassRegistry&); |
165 | void initializeHexagonHardwareLoopsPass(PassRegistry&); |
166 | void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &); |
167 | void initializeHexagonLoopAlignPass(PassRegistry &); |
168 | void initializeHexagonNewValueJumpPass(PassRegistry&); |
169 | void initializeHexagonOptAddrModePass(PassRegistry&); |
170 | void initializeHexagonPacketizerPass(PassRegistry&); |
171 | void initializeHexagonRDFOptPass(PassRegistry&); |
172 | void initializeHexagonSplitDoubleRegsPass(PassRegistry&); |
173 | void initializeHexagonTfrCleanupPass(PassRegistry &); |
174 | void (PassRegistry &); |
175 | void initializeHexagonVectorCombineLegacyPass(PassRegistry&); |
176 | void initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PassRegistry &); |
177 | Pass *createHexagonLoopIdiomPass(); |
178 | Pass *createHexagonVectorLoopCarriedReuseLegacyPass(); |
179 | |
180 | FunctionPass *createHexagonBitSimplify(); |
181 | FunctionPass *createHexagonBranchRelaxation(); |
182 | FunctionPass *createHexagonCallFrameInformation(); |
183 | FunctionPass *createHexagonCFGOptimizer(); |
184 | FunctionPass *createHexagonCommonGEP(); |
185 | FunctionPass *createHexagonConstExtenders(); |
186 | FunctionPass *createHexagonConstPropagationPass(); |
187 | FunctionPass *createHexagonCopyToCombine(); |
188 | FunctionPass *createHexagonEarlyIfConversion(); |
189 | FunctionPass *createHexagonFixupHwLoops(); |
190 | FunctionPass *(); |
191 | FunctionPass *createHexagonGenInsert(); |
192 | FunctionPass *createHexagonGenMemAbsolute(); |
193 | FunctionPass *createHexagonGenMux(); |
194 | FunctionPass *createHexagonGenPredicate(); |
195 | FunctionPass *createHexagonHardwareLoops(); |
196 | FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, |
197 | CodeGenOptLevel OptLevel); |
198 | FunctionPass *createHexagonLoopAlign(); |
199 | FunctionPass *createHexagonLoopRescheduling(); |
200 | FunctionPass *createHexagonNewValueJump(); |
201 | FunctionPass *createHexagonOptAddrMode(); |
202 | FunctionPass *createHexagonOptimizeSZextends(); |
203 | FunctionPass *createHexagonPacketizer(bool Minimal); |
204 | FunctionPass *createHexagonPeephole(); |
205 | FunctionPass *createHexagonRDFOpt(); |
206 | FunctionPass *createHexagonSplitConst32AndConst64(); |
207 | FunctionPass *createHexagonSplitDoubleRegs(); |
208 | FunctionPass *createHexagonStoreWidening(); |
209 | FunctionPass *createHexagonTfrCleanup(); |
210 | FunctionPass *createHexagonVectorCombineLegacyPass(); |
211 | FunctionPass *createHexagonVectorPrint(); |
212 | FunctionPass *(); |
213 | } // end namespace llvm; |
214 | |
215 | static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { |
216 | return RM.value_or(u: Reloc::Static); |
217 | } |
218 | |
219 | extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTarget() { |
220 | // Register the target. |
221 | RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget()); |
222 | |
223 | PassRegistry &PR = *PassRegistry::getPassRegistry(); |
224 | initializeHexagonBitSimplifyPass(PR); |
225 | initializeHexagonConstExtendersPass(PR); |
226 | initializeHexagonConstPropagationPass(PR); |
227 | initializeHexagonCopyToCombinePass(PR); |
228 | initializeHexagonEarlyIfConversionPass(PR); |
229 | initializeHexagonGenMemAbsolutePass(PR); |
230 | initializeHexagonGenMuxPass(PR); |
231 | initializeHexagonHardwareLoopsPass(PR); |
232 | initializeHexagonLoopIdiomRecognizeLegacyPassPass(PR); |
233 | initializeHexagonNewValueJumpPass(PR); |
234 | initializeHexagonOptAddrModePass(PR); |
235 | initializeHexagonPacketizerPass(PR); |
236 | initializeHexagonRDFOptPass(PR); |
237 | initializeHexagonSplitDoubleRegsPass(PR); |
238 | initializeHexagonVectorCombineLegacyPass(PR); |
239 | initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR); |
240 | initializeHexagonVExtractPass(PR); |
241 | initializeHexagonDAGToDAGISelPass(PR); |
242 | } |
243 | |
244 | HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, |
245 | StringRef CPU, StringRef FS, |
246 | const TargetOptions &Options, |
247 | std::optional<Reloc::Model> RM, |
248 | std::optional<CodeModel::Model> CM, |
249 | CodeGenOptLevel OL, bool JIT) |
250 | // Specify the vector alignment explicitly. For v512x1, the calculated |
251 | // alignment would be 512*alignment(i1), which is 512 bytes, instead of |
252 | // the required minimum of 64 bytes. |
253 | : LLVMTargetMachine( |
254 | T, |
255 | "e-m:e-p:32:32:32-a:0-n16:32-" |
256 | "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" |
257 | "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048" , |
258 | TT, CPU, FS, Options, getEffectiveRelocModel(RM), |
259 | getEffectiveCodeModel(CM, Default: CodeModel::Small), |
260 | (HexagonNoOpt ? CodeGenOptLevel::None : OL)), |
261 | TLOF(std::make_unique<HexagonTargetObjectFile>()), |
262 | Subtarget(Triple(TT), CPU, FS, *this) { |
263 | initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry()); |
264 | initializeHexagonLoopAlignPass(*PassRegistry::getPassRegistry()); |
265 | initializeHexagonTfrCleanupPass(*PassRegistry::getPassRegistry()); |
266 | initAsmInfo(); |
267 | } |
268 | |
269 | const HexagonSubtarget * |
270 | HexagonTargetMachine::getSubtargetImpl(const Function &F) const { |
271 | AttributeList FnAttrs = F.getAttributes(); |
272 | Attribute CPUAttr = |
273 | FnAttrs.getFnAttr(Kind: "target-cpu" ); |
274 | Attribute FSAttr = |
275 | FnAttrs.getFnAttr(Kind: "target-features" ); |
276 | |
277 | std::string CPU = |
278 | CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; |
279 | std::string FS = |
280 | FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; |
281 | // Append the preexisting target features last, so that +mattr overrides |
282 | // the "unsafe-fp-math" function attribute. |
283 | // Creating a separate target feature is not strictly necessary, it only |
284 | // exists to make "unsafe-fp-math" force creating a new subtarget. |
285 | |
286 | if (F.getFnAttribute(Kind: "unsafe-fp-math" ).getValueAsBool()) |
287 | FS = FS.empty() ? "+unsafe-fp" : "+unsafe-fp," + FS; |
288 | |
289 | auto &I = SubtargetMap[CPU + FS]; |
290 | if (!I) { |
291 | // This needs to be done before we create a new subtarget since any |
292 | // creation will depend on the TM and the code generation flags on the |
293 | // function that reside in TargetOptions. |
294 | resetTargetOptions(F); |
295 | I = std::make_unique<HexagonSubtarget>(args: TargetTriple, args&: CPU, args&: FS, args: *this); |
296 | } |
297 | return I.get(); |
298 | } |
299 | |
300 | void HexagonTargetMachine::registerPassBuilderCallbacks( |
301 | PassBuilder &PB, bool PopulateClassToPassNames) { |
302 | #define GET_PASS_REGISTRY "HexagonPassRegistry.def" |
303 | #include "llvm/Passes/TargetPassRegistry.inc" |
304 | |
305 | PB.registerLateLoopOptimizationsEPCallback( |
306 | C: [=](LoopPassManager &LPM, OptimizationLevel Level) { |
307 | LPM.addPass(Pass: HexagonLoopIdiomRecognitionPass()); |
308 | }); |
309 | PB.registerLoopOptimizerEndEPCallback( |
310 | C: [=](LoopPassManager &LPM, OptimizationLevel Level) { |
311 | LPM.addPass(Pass: HexagonVectorLoopCarriedReusePass()); |
312 | }); |
313 | } |
314 | |
315 | TargetTransformInfo |
316 | HexagonTargetMachine::getTargetTransformInfo(const Function &F) const { |
317 | return TargetTransformInfo(HexagonTTIImpl(this, F)); |
318 | } |
319 | |
320 | MachineFunctionInfo *HexagonTargetMachine::createMachineFunctionInfo( |
321 | BumpPtrAllocator &Allocator, const Function &F, |
322 | const TargetSubtargetInfo *STI) const { |
323 | return HexagonMachineFunctionInfo::create<HexagonMachineFunctionInfo>( |
324 | Allocator, F, STI); |
325 | } |
326 | |
327 | HexagonTargetMachine::~HexagonTargetMachine() = default; |
328 | |
329 | namespace { |
330 | /// Hexagon Code Generator Pass Configuration Options. |
331 | class HexagonPassConfig : public TargetPassConfig { |
332 | public: |
333 | HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM) |
334 | : TargetPassConfig(TM, PM) {} |
335 | |
336 | HexagonTargetMachine &getHexagonTargetMachine() const { |
337 | return getTM<HexagonTargetMachine>(); |
338 | } |
339 | |
340 | ScheduleDAGInstrs * |
341 | createMachineScheduler(MachineSchedContext *C) const override { |
342 | return createVLIWMachineSched(C); |
343 | } |
344 | |
345 | void addIRPasses() override; |
346 | bool addInstSelector() override; |
347 | void addPreRegAlloc() override; |
348 | void addPostRegAlloc() override; |
349 | void addPreSched2() override; |
350 | void addPreEmitPass() override; |
351 | }; |
352 | } // namespace |
353 | |
354 | TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { |
355 | return new HexagonPassConfig(*this, PM); |
356 | } |
357 | |
358 | void HexagonPassConfig::addIRPasses() { |
359 | TargetPassConfig::addIRPasses(); |
360 | bool NoOpt = (getOptLevel() == CodeGenOptLevel::None); |
361 | |
362 | if (!NoOpt) { |
363 | if (EnableInstSimplify) |
364 | addPass(P: createInstSimplifyLegacyPass()); |
365 | addPass(P: createDeadCodeEliminationPass()); |
366 | } |
367 | |
368 | addPass(P: createAtomicExpandLegacyPass()); |
369 | |
370 | if (!NoOpt) { |
371 | if (EnableInitialCFGCleanup) |
372 | addPass(P: createCFGSimplificationPass(Options: SimplifyCFGOptions() |
373 | .forwardSwitchCondToPhi(B: true) |
374 | .convertSwitchRangeToICmp(B: true) |
375 | .convertSwitchToLookupTable(B: true) |
376 | .needCanonicalLoops(B: false) |
377 | .hoistCommonInsts(B: true) |
378 | .sinkCommonInsts(B: true))); |
379 | if (EnableLoopPrefetch) |
380 | addPass(P: createLoopDataPrefetchPass()); |
381 | if (EnableVectorCombine) |
382 | addPass(P: createHexagonVectorCombineLegacyPass()); |
383 | if (EnableCommGEP) |
384 | addPass(P: createHexagonCommonGEP()); |
385 | // Replace certain combinations of shifts and ands with extracts. |
386 | if (EnableGenExtract) |
387 | addPass(P: createHexagonGenExtract()); |
388 | } |
389 | } |
390 | |
391 | bool HexagonPassConfig::addInstSelector() { |
392 | HexagonTargetMachine &TM = getHexagonTargetMachine(); |
393 | bool NoOpt = (getOptLevel() == CodeGenOptLevel::None); |
394 | |
395 | if (!NoOpt) |
396 | addPass(P: createHexagonOptimizeSZextends()); |
397 | |
398 | addPass(P: createHexagonISelDag(TM, OptLevel: getOptLevel())); |
399 | |
400 | if (!NoOpt) { |
401 | if (EnableVExtractOpt) |
402 | addPass(P: createHexagonVExtract()); |
403 | // Create logical operations on predicate registers. |
404 | if (EnableGenPred) |
405 | addPass(P: createHexagonGenPredicate()); |
406 | // Rotate loops to expose bit-simplification opportunities. |
407 | if (EnableLoopResched) |
408 | addPass(P: createHexagonLoopRescheduling()); |
409 | // Split double registers. |
410 | if (!DisableHSDR) |
411 | addPass(P: createHexagonSplitDoubleRegs()); |
412 | // Bit simplification. |
413 | if (EnableBitSimplify) |
414 | addPass(P: createHexagonBitSimplify()); |
415 | addPass(P: createHexagonPeephole()); |
416 | // Constant propagation. |
417 | if (!DisableHCP) { |
418 | addPass(P: createHexagonConstPropagationPass()); |
419 | addPass(PassID: &UnreachableMachineBlockElimID); |
420 | } |
421 | if (EnableGenInsert) |
422 | addPass(P: createHexagonGenInsert()); |
423 | if (EnableEarlyIf) |
424 | addPass(P: createHexagonEarlyIfConversion()); |
425 | } |
426 | |
427 | return false; |
428 | } |
429 | |
430 | void HexagonPassConfig::addPreRegAlloc() { |
431 | if (getOptLevel() != CodeGenOptLevel::None) { |
432 | if (EnableCExtOpt) |
433 | addPass(P: createHexagonConstExtenders()); |
434 | if (EnableExpandCondsets) |
435 | insertPass(TargetPassID: &RegisterCoalescerID, InsertedPassID: &HexagonExpandCondsetsID); |
436 | if (EnableTfrCleanup) |
437 | insertPass(TargetPassID: &VirtRegRewriterID, InsertedPassID: &HexagonTfrCleanupID); |
438 | if (!DisableStoreWidening) |
439 | addPass(P: createHexagonStoreWidening()); |
440 | if (EnableGenMemAbs) |
441 | addPass(P: createHexagonGenMemAbsolute()); |
442 | if (!DisableHardwareLoops) |
443 | addPass(P: createHexagonHardwareLoops()); |
444 | } |
445 | if (TM->getOptLevel() >= CodeGenOptLevel::Default) |
446 | addPass(PassID: &MachinePipelinerID); |
447 | } |
448 | |
449 | void HexagonPassConfig::addPostRegAlloc() { |
450 | if (getOptLevel() != CodeGenOptLevel::None) { |
451 | if (EnableRDFOpt) |
452 | addPass(P: createHexagonRDFOpt()); |
453 | if (!DisableHexagonCFGOpt) |
454 | addPass(P: createHexagonCFGOptimizer()); |
455 | if (!DisableAModeOpt) |
456 | addPass(P: createHexagonOptAddrMode()); |
457 | } |
458 | } |
459 | |
460 | void HexagonPassConfig::addPreSched2() { |
461 | addPass(P: createHexagonCopyToCombine()); |
462 | if (getOptLevel() != CodeGenOptLevel::None) |
463 | addPass(PassID: &IfConverterID); |
464 | addPass(P: createHexagonSplitConst32AndConst64()); |
465 | } |
466 | |
467 | void HexagonPassConfig::addPreEmitPass() { |
468 | bool NoOpt = (getOptLevel() == CodeGenOptLevel::None); |
469 | |
470 | if (!NoOpt) |
471 | addPass(P: createHexagonNewValueJump()); |
472 | |
473 | addPass(P: createHexagonBranchRelaxation()); |
474 | |
475 | if (!NoOpt) { |
476 | if (!DisableHardwareLoops) |
477 | addPass(P: createHexagonFixupHwLoops()); |
478 | // Generate MUX from pairs of conditional transfers. |
479 | if (EnableGenMux) |
480 | addPass(P: createHexagonGenMux()); |
481 | } |
482 | |
483 | // Packetization is mandatory: it handles gather/scatter at all opt levels. |
484 | addPass(P: createHexagonPacketizer(Minimal: NoOpt)); |
485 | |
486 | if (!NoOpt) |
487 | addPass(P: createHexagonLoopAlign()); |
488 | |
489 | if (EnableVectorPrint) |
490 | addPass(P: createHexagonVectorPrint()); |
491 | |
492 | // Add CFI instructions if necessary. |
493 | addPass(P: createHexagonCallFrameInformation()); |
494 | } |
495 | |