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