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