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/MIRParser/MIParser.h"
24#include "llvm/CodeGen/Passes.h"
25#include "llvm/CodeGen/TargetPassConfig.h"
26#include "llvm/CodeGen/VLIWMachineScheduler.h"
27#include "llvm/MC/TargetRegistry.h"
28#include "llvm/Passes/PassBuilder.h"
29#include "llvm/Support/CommandLine.h"
30#include "llvm/Support/Compiler.h"
31#include "llvm/Transforms/Scalar.h"
32#include <optional>
33
34using namespace llvm;
35
36static cl::opt<bool>
37 EnableCExtOpt("hexagon-cext", cl::Hidden, cl::init(Val: true),
38 cl::desc("Enable Hexagon constant-extender optimization"));
39
40static cl::opt<bool> EnableRDFOpt("rdf-opt", cl::Hidden, cl::init(Val: true),
41 cl::desc("Enable RDF-based optimizations"));
42
43static cl::opt<bool> EnablePostRAHandleQFP(
44 "hexagon-handle-qfloat", cl::init(Val: true), cl::Hidden,
45 cl::desc("Fix up QFloat spills and reloads after register allocation"));
46
47cl::opt<unsigned> RDFFuncBlockLimit(
48 "rdf-bb-limit", cl::Hidden, cl::init(Val: 1000),
49 cl::desc("Basic block limit for a function for RDF optimizations"));
50
51static cl::opt<bool>
52 DisableHardwareLoops("disable-hexagon-hwloops", cl::Hidden,
53 cl::desc("Disable Hardware Loops for Hexagon target"));
54
55static cl::opt<bool> EnableMCR("hexagon-mcr", cl::Hidden, cl::init(Val: true),
56 cl::desc("Enable the machine combiner pass"));
57
58static cl::opt<bool>
59 DisableAModeOpt("disable-hexagon-amodeopt", cl::Hidden,
60 cl::desc("Disable Hexagon Addressing Mode Optimization"));
61
62static cl::opt<bool>
63 DisableHexagonCFGOpt("disable-hexagon-cfgopt", cl::Hidden,
64 cl::desc("Disable Hexagon CFG Optimization"));
65
66static cl::opt<bool>
67 DisableHCP("disable-hcp", cl::Hidden,
68 cl::desc("Disable Hexagon constant propagation"));
69
70static cl::opt<bool> DisableHexagonMask(
71 "disable-mask", cl::Hidden,
72 cl::desc("Disable Hexagon specific Mask generation pass"));
73
74static cl::opt<bool> DisableHexagonLiveVars(
75 "disable-hlv", cl::Hidden,
76 cl::desc("Disable Hexagon specific post-RA live-variable analysis"));
77static cl::opt<bool> DisableStoreWidening("disable-store-widen", cl::Hidden,
78 cl::init(Val: false),
79 cl::desc("Disable store widening"));
80
81static cl::opt<bool> DisableLoadWidening("disable-load-widen", cl::Hidden,
82 cl::desc("Disable load widening"));
83
84static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets",
85 cl::init(Val: true), cl::Hidden,
86 cl::desc("Early expansion of MUX"));
87
88static cl::opt<bool> EnableTfrCleanup("hexagon-tfr-cleanup", cl::init(Val: true),
89 cl::Hidden,
90 cl::desc("Cleanup of TFRs/COPYs"));
91
92static cl::opt<bool> EnableEarlyIf("hexagon-eif", cl::init(Val: true), cl::Hidden,
93 cl::desc("Enable early if-conversion"));
94
95static cl::opt<bool> EnableCopyHoist("hexagon-copy-hoist", cl::init(Val: true),
96 cl::Hidden,
97 cl::desc("Enable Hexagon copy hoisting"));
98
99static cl::opt<bool>
100 EnableGenInsert("hexagon-insert", cl::init(Val: true), cl::Hidden,
101 cl::desc("Generate \"insert\" instructions"));
102
103static cl::opt<bool>
104 EnableCommGEP("hexagon-commgep", cl::init(Val: true), cl::Hidden,
105 cl::desc("Enable commoning of GEP instructions"));
106
107static cl::opt<bool>
108 EnableGenExtract("hexagon-extract", cl::init(Val: true), cl::Hidden,
109 cl::desc("Generate \"extract\" instructions"));
110
111static cl::opt<bool> EnableGenMux(
112 "hexagon-mux", cl::init(Val: true), cl::Hidden,
113 cl::desc("Enable converting conditional transfers into MUX instructions"));
114
115static cl::opt<bool>
116 EnableGenPred("hexagon-gen-pred", cl::init(Val: true), cl::Hidden,
117 cl::desc("Enable conversion of arithmetic operations to "
118 "predicate instructions"));
119
120static cl::opt<bool>
121 EnableLoopPrefetch("hexagon-loop-prefetch", cl::Hidden,
122 cl::desc("Enable loop data prefetch on Hexagon"));
123
124static cl::opt<bool>
125 DisableHSDR("disable-hsdr", cl::init(Val: false), cl::Hidden,
126 cl::desc("Disable splitting double registers"));
127
128static cl::opt<bool>
129 EnableGenMemAbs("hexagon-mem-abs", cl::init(Val: true), cl::Hidden,
130 cl::desc("Generate absolute set instructions"));
131
132static cl::opt<bool> EnableBitSimplify("hexagon-bit", cl::init(Val: true),
133 cl::Hidden,
134 cl::desc("Bit simplification"));
135
136static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(Val: true),
137 cl::Hidden,
138 cl::desc("Loop rescheduling"));
139
140static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(Val: false), cl::Hidden,
141 cl::desc("Disable backend optimizations"));
142
143static cl::opt<bool>
144 EnableVectorPrint("enable-hexagon-vector-print", cl::Hidden,
145 cl::desc("Enable Hexagon Vector print instr pass"));
146
147static cl::opt<bool>
148 EnableVExtractOpt("hexagon-opt-vextract", cl::Hidden, cl::init(Val: true),
149 cl::desc("Enable vextract optimization"));
150
151static cl::opt<bool>
152 EnableVectorCombine("hexagon-vector-combine", cl::Hidden, cl::init(Val: true),
153 cl::desc("Enable HVX vector combining"));
154
155static cl::opt<bool> EnableInitialCFGCleanup(
156 "hexagon-initial-cfg-cleanup", cl::Hidden, cl::init(Val: true),
157 cl::desc("Simplify the CFG after atomic expansion pass"));
158
159static cl::opt<bool> EnableInstSimplify("hexagon-instsimplify", cl::Hidden,
160 cl::init(Val: true),
161 cl::desc("Enable instsimplify"));
162
163cl::opt<QFloatMode> QFloatModeValue(
164 "hexagon-qfloat-mode", cl::desc("Specify the qfloat mode to operate on."),
165 cl::Hidden, cl::init(Val: QFloatMode::Legacy),
166 cl::values(
167 clEnumValN(QFloatMode::StrictIEEE, "strict-ieee",
168 "Enable code generation for qfloat strict IEEE-754 mode"),
169 clEnumValN(QFloatMode::IEEE, "ieee",
170 "Enable code generation for qfloat IEEE-754 mode"),
171 clEnumValN(QFloatMode::Lossy, "lossy",
172 "Enable code generation for qfloat lossy-subnormals mode"),
173 clEnumValN(QFloatMode::Legacy, "legacy",
174 "Enable code generation for qfloat legacy mode")));
175
176/// HexagonTargetMachineModule - Note that this is used on hosts that
177/// cannot link in a library unless there are references into the
178/// library. In particular, it seems that it is not possible to get
179/// things to work on Win32 without this. Though it is unused, do not
180/// remove it.
181extern "C" int HexagonTargetMachineModule;
182int HexagonTargetMachineModule = 0;
183
184static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) {
185 ScheduleDAGMILive *DAG = new VLIWMachineScheduler(
186 C, std::make_unique<HexagonConvergingVLIWScheduler>());
187 DAG->addMutation(Mutation: std::make_unique<HexagonSubtarget::UsrOverflowMutation>());
188 DAG->addMutation(Mutation: std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
189 DAG->addMutation(Mutation: std::make_unique<HexagonSubtarget::CallMutation>());
190 DAG->addMutation(Mutation: createCopyConstrainDAGMutation(TII: DAG->TII, TRI: DAG->TRI));
191 return DAG;
192}
193
194static MachineSchedRegistry
195 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler",
196 createVLIWMachineSched);
197
198static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
199 return RM.value_or(u: Reloc::Static);
200}
201
202extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
203LLVMInitializeHexagonTarget() {
204 // Register the target.
205 RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget());
206
207 PassRegistry &PR = *PassRegistry::getPassRegistry();
208 initializeHexagonAsmPrinterPass(PR);
209 initializeHexagonBitSimplifyPass(PR);
210 initializeHexagonConstExtendersPass(PR);
211 initializeHexagonConstPropagationPass(PR);
212 initializeHexagonCopyToCombinePass(PR);
213 initializeHexagonEarlyIfConversionPass(PR);
214 initializeHexagonGenMemAbsolutePass(PR);
215 initializeHexagonGenMuxPass(PR);
216 initializeHexagonGlobalSchedulerPass(PR);
217 initializeHexagonLiveVariablesPass(PR);
218 initializeHexagonHardwareLoopsPass(PR);
219 initializeHexagonHVXSaveRemarkPass(PR);
220 initializeHexagonLoopIdiomRecognizeLegacyPassPass(PR);
221 initializeHexagonNewValueJumpPass(PR);
222 initializeHexagonOptAddrModePass(PR);
223 initializeHexagonPacketizerPass(PR);
224 initializeHexagonRDFOptPass(PR);
225 initializeHexagonSplitDoubleRegsPass(PR);
226 initializeHexagonVectorCombineLegacyPass(PR);
227 initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR);
228 initializeHexagonVExtractPass(PR);
229 initializeHexagonDAGToDAGISelLegacyPass(PR);
230 initializeHexagonLoopReschedulingPass(PR);
231 initializeHexagonBranchRelaxationPass(PR);
232 initializeHexagonCFGOptimizerPass(PR);
233 initializeHexagonCommonGEPPass(PR);
234 initializeHexagonCopyHoistingPass(PR);
235 initializeHexagonExpandCondsetsPass(PR);
236 initializeHexagonLoopAlignPass(PR);
237 initializeHexagonTfrCleanupPass(PR);
238 initializeHexagonFixupHwLoopsPass(PR);
239 initializeHexagonCallFrameInformationPass(PR);
240 initializeHexagonGenExtractPass(PR);
241 initializeHexagonGenInsertPass(PR);
242 initializeHexagonGenPredicatePass(PR);
243 initializeHexagonLoadWideningPass(PR);
244 initializeHexagonStoreWideningPass(PR);
245 initializeHexagonMaskPass(PR);
246 initializeHexagonOptimizeSZextendsPass(PR);
247 initializeHexagonPeepholePass(PR);
248 initializeHexagonSplitConst32AndConst64Pass(PR);
249 initializeHexagonVectorPrintPass(PR);
250 initializeHexagonQFPOptimizerPass(PR);
251 initializeHexagonXQFloatGeneratorPass(PR);
252 initializeHexagonPostRAHandleQFPPass(PR);
253}
254
255HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT,
256 StringRef CPU, StringRef FS,
257 const TargetOptions &Options,
258 std::optional<Reloc::Model> RM,
259 std::optional<CodeModel::Model> CM,
260 CodeGenOptLevel OL, bool JIT)
261 // Specify the vector alignment explicitly. For v512x1, the calculated
262 // alignment would be 512*alignment(i1), which is 512 bytes, instead of
263 // the required minimum of 64 bytes.
264 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
265 getEffectiveRelocModel(RM),
266 getEffectiveCodeModel(CM, Default: CodeModel::Small),
267 (HexagonNoOpt ? CodeGenOptLevel::None : OL)),
268 TLOF(std::make_unique<HexagonTargetObjectFile>()),
269 Subtarget(Triple(TT), CPU, FS, *this) {
270 initAsmInfo();
271}
272
273const HexagonSubtarget *
274HexagonTargetMachine::getSubtargetImpl(const Function &F) const {
275 AttributeList FnAttrs = F.getAttributes();
276 Attribute CPUAttr = FnAttrs.getFnAttr(Kind: "target-cpu");
277 Attribute FSAttr = FnAttrs.getFnAttr(Kind: "target-features");
278
279 std::string CPU =
280 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
281 std::string FS =
282 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
283
284 auto &I = SubtargetMap[CPU + FS];
285 if (!I)
286 I = std::make_unique<HexagonSubtarget>(args: TargetTriple, args&: CPU, args&: FS, args: *this);
287 return I.get();
288}
289
290void HexagonTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
291#define GET_PASS_REGISTRY "HexagonPassRegistry.def"
292#include "llvm/Passes/TargetPassRegistry.inc"
293
294 PB.registerLateLoopOptimizationsEPCallback(
295 C: [=](LoopPassManager &LPM, OptimizationLevel Level) {
296 if (Level.getSpeedupLevel() > 0)
297 LPM.addPass(Pass: HexagonLoopIdiomRecognitionPass());
298 });
299 PB.registerLoopOptimizerEndEPCallback(
300 C: [=](LoopPassManager &LPM, OptimizationLevel Level) {
301 if (Level.getSpeedupLevel() > 0)
302 LPM.addPass(Pass: HexagonVectorLoopCarriedReusePass());
303 });
304}
305
306TargetTransformInfo
307HexagonTargetMachine::getTargetTransformInfo(const Function &F) const {
308 return TargetTransformInfo(std::make_unique<HexagonTTIImpl>(args: this, args: F));
309}
310
311MachineFunctionInfo *HexagonTargetMachine::createMachineFunctionInfo(
312 BumpPtrAllocator &Allocator, const Function &F,
313 const TargetSubtargetInfo *STI) const {
314 return HexagonMachineFunctionInfo::create<HexagonMachineFunctionInfo>(
315 Allocator, F, STI);
316}
317
318yaml::MachineFunctionInfo *
319HexagonTargetMachine::createDefaultFuncInfoYAML() const {
320 return new yaml::HexagonFunctionInfo();
321}
322
323yaml::MachineFunctionInfo *
324HexagonTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const {
325 const auto *MFI = MF.getInfo<HexagonMachineFunctionInfo>();
326 const auto &TRI = *MF.getSubtarget().getRegisterInfo();
327 return new yaml::HexagonFunctionInfo(*MFI, TRI);
328}
329
330bool HexagonTargetMachine::parseMachineFunctionInfo(
331 const yaml::MachineFunctionInfo &MFI_, PerFunctionMIParsingState &PFS,
332 SMDiagnostic &Error, SMRange &SourceRange) const {
333 const auto &YamlMFI = static_cast<const yaml::HexagonFunctionInfo &>(MFI_);
334 MachineFunction &MF = PFS.MF;
335 HexagonMachineFunctionInfo *MFI = MF.getInfo<HexagonMachineFunctionInfo>();
336
337 MFI->initializeBaseYamlFields(YamlMFI);
338
339 // Parse StackAlignBaseReg register name
340 if (!YamlMFI.StackAlignBaseReg.Value.empty()) {
341 Register Reg;
342 if (parseNamedRegisterReference(PFS, Reg, Src: YamlMFI.StackAlignBaseReg.Value,
343 Error)) {
344 SourceRange = YamlMFI.StackAlignBaseReg.SourceRange;
345 return true;
346 }
347 MFI->setStackAlignBaseReg(Reg);
348 }
349
350 return false;
351}
352
353HexagonTargetMachine::~HexagonTargetMachine() = default;
354
355ScheduleDAGInstrs *
356HexagonTargetMachine::createMachineScheduler(MachineSchedContext *C) const {
357 return createVLIWMachineSched(C);
358}
359
360namespace {
361/// Hexagon Code Generator Pass Configuration Options.
362class HexagonPassConfig : public TargetPassConfig {
363public:
364 HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM)
365 : TargetPassConfig(TM, PM) {}
366
367 HexagonTargetMachine &getHexagonTargetMachine() const {
368 return getTM<HexagonTargetMachine>();
369 }
370
371 void addIRPasses() override;
372 bool addInstSelector() override;
373 bool addILPOpts() override;
374 void addPreRegAlloc() override;
375 void addPostRegAlloc() override;
376 void addPreSched2() override;
377 void addPreEmitPass() override;
378};
379} // namespace
380
381TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
382 return new HexagonPassConfig(*this, PM);
383}
384
385void HexagonPassConfig::addIRPasses() {
386 TargetPassConfig::addIRPasses();
387 bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
388
389 if (!NoOpt) {
390 if (EnableInstSimplify)
391 addPass(P: createInstSimplifyLegacyPass());
392 addPass(P: createDeadCodeEliminationPass());
393 }
394
395 addPass(P: createAtomicExpandLegacyPass());
396
397 if (!NoOpt) {
398 if (EnableInitialCFGCleanup)
399 addPass(P: createCFGSimplificationPass(Options: SimplifyCFGOptions()
400 .forwardSwitchCondToPhi(B: true)
401 .convertSwitchRangeToICmp(B: true)
402 .convertSwitchToLookupTable(B: true)
403 .needCanonicalLoops(B: false)
404 .hoistCommonInsts(B: true)
405 .sinkCommonInsts(B: true)));
406 if (EnableLoopPrefetch)
407 addPass(P: createLoopDataPrefetchPass());
408 if (EnableVectorCombine)
409 addPass(P: createHexagonVectorCombineLegacyPass());
410 if (EnableCommGEP)
411 addPass(P: createHexagonCommonGEP());
412 // Replace certain combinations of shifts and ands with extracts.
413 if (EnableGenExtract)
414 addPass(P: createHexagonGenExtract());
415 }
416}
417
418bool HexagonPassConfig::addInstSelector() {
419 HexagonTargetMachine &TM = getHexagonTargetMachine();
420 const HexagonSubtarget *HST = TM.getHexagonSubtarget();
421 bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
422
423 if (!NoOpt)
424 addPass(P: createHexagonOptimizeSZextends());
425
426 addPass(P: createHexagonISelDag(TM, OptLevel: getOptLevel()));
427 // Run the QFloat mode code generation pass only if v79 or greater.
428 // Do not run this pass, if legacy mode is passed on command line.
429 if (HST->useHVXV79Ops() && (QFloatModeValue != QFloatMode::Legacy))
430 addPass(P: createHexagonXQFloatGenerator());
431
432 if (!NoOpt) {
433 if (EnableVExtractOpt)
434 addPass(P: createHexagonVExtract());
435 // Create logical operations on predicate registers.
436 if (EnableGenPred)
437 addPass(P: createHexagonGenPredicate());
438 // Rotate loops to expose bit-simplification opportunities.
439 if (EnableLoopResched)
440 addPass(P: createHexagonLoopRescheduling());
441 // Split double registers.
442 if (!DisableHSDR)
443 addPass(P: createHexagonSplitDoubleRegs());
444 // Bit simplification.
445 if (EnableBitSimplify)
446 addPass(P: createHexagonBitSimplify());
447 addPass(P: createHexagonPeephole());
448 // Constant propagation.
449 if (!DisableHCP) {
450 addPass(P: createHexagonConstPropagationPass());
451 addPass(PassID: &UnreachableMachineBlockElimID);
452 }
453 if (EnableGenInsert)
454 addPass(P: createHexagonGenInsert());
455 if (EnableEarlyIf)
456 addPass(P: createHexagonEarlyIfConversion());
457 // For v75 or below, or if legacy mode is requested, run QFPOptizer pass
458 // to preserve backward compatibility.
459 if (!HST->useHVXV79Ops() || (QFloatModeValue == QFloatMode::Legacy))
460 addPass(P: createHexagonQFPOptimizer());
461 }
462
463 return false;
464}
465
466bool HexagonPassConfig::addILPOpts() {
467 if (EnableMCR)
468 addPass(PassID: &MachineCombinerID);
469
470 return true;
471}
472
473void HexagonPassConfig::addPreRegAlloc() {
474 if (getOptLevel() != CodeGenOptLevel::None) {
475 if (EnableCExtOpt)
476 addPass(P: createHexagonConstExtenders());
477 if (EnableExpandCondsets)
478 insertPass(TargetPassID: &RegisterCoalescerID, InsertedPassID: &HexagonExpandCondsetsID);
479 if (EnableCopyHoist)
480 insertPass(TargetPassID: &RegisterCoalescerID, InsertedPassID: &HexagonCopyHoistingID);
481 if (EnableTfrCleanup)
482 insertPass(TargetPassID: &VirtRegRewriterID, InsertedPassID: &HexagonTfrCleanupID);
483 if (!DisableStoreWidening)
484 addPass(P: createHexagonStoreWidening());
485 if (!DisableLoadWidening)
486 addPass(P: createHexagonLoadWidening());
487 if (EnableGenMemAbs)
488 addPass(P: createHexagonGenMemAbsolute());
489 if (!DisableHardwareLoops)
490 addPass(P: createHexagonHardwareLoops());
491 }
492 if (TM->getOptLevel() >= CodeGenOptLevel::Default)
493 addPass(PassID: &MachinePipelinerID);
494 addPass(P: createHexagonHVXSaveRemark());
495}
496
497void HexagonPassConfig::addPostRegAlloc() {
498 HexagonTargetMachine &HTM = getHexagonTargetMachine();
499 const HexagonSubtarget *HST = HTM.getHexagonSubtarget();
500 // Run PostRAQFP on v79 and above.
501 if (EnablePostRAHandleQFP && HST->useHVXV79Ops())
502 addPass(P: createHexagonPostRAHandleQFP());
503
504 if (getOptLevel() != CodeGenOptLevel::None) {
505 if (EnableRDFOpt)
506 addPass(P: createHexagonRDFOpt());
507 if (!DisableHexagonCFGOpt)
508 addPass(P: createHexagonCFGOptimizer());
509 if (!DisableAModeOpt)
510 addPass(P: createHexagonOptAddrMode());
511 }
512}
513
514void HexagonPassConfig::addPreSched2() {
515 bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
516 addPass(P: createHexagonCopyToCombine());
517 if (getOptLevel() != CodeGenOptLevel::None)
518 addPass(PassID: &IfConverterID);
519 addPass(P: createHexagonSplitConst32AndConst64());
520 if (!NoOpt && !DisableHexagonMask)
521 addPass(P: createHexagonMask());
522
523 if (!NoOpt && !DisableHexagonLiveVars) {
524 addPass(PassID: &HexagonLiveVariablesID);
525 }
526}
527
528void HexagonPassConfig::addPreEmitPass() {
529 bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
530
531 if (!NoOpt)
532 addPass(P: createHexagonNewValueJump());
533
534 addPass(P: createHexagonBranchRelaxation());
535
536 if (!NoOpt) {
537 if (!DisableHardwareLoops)
538 addPass(P: createHexagonFixupHwLoops());
539 // Generate MUX from pairs of conditional transfers.
540 if (EnableGenMux)
541 addPass(P: createHexagonGenMux());
542 if (!DisableHexagonLiveVars)
543 addPass(PassID: &HexagonLiveVariablesID);
544 }
545
546 // Emit KCFI checks for indirect calls. Must run before packetization so
547 // the check and call can be bundled together into a VLIW packet.
548 addPass(P: createKCFIPass());
549
550 // Packetization is mandatory: it handles gather/scatter at all opt levels.
551 addPass(P: createHexagonPacketizer(Minimal: NoOpt));
552
553 if (!NoOpt) {
554 // Global pull-up scheduler
555 addPass(P: createHexagonGlobalScheduler());
556
557 addPass(P: createHexagonLoopAlign());
558 }
559
560 if (EnableVectorPrint)
561 addPass(P: createHexagonVectorPrint());
562
563 // Add CFI instructions if necessary.
564 addPass(P: createHexagonCallFrameInformation());
565}
566