10b57cec5SDimitry Andric //===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Implements the info about Hexagon target spec. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "HexagonTargetMachine.h" 140b57cec5SDimitry Andric #include "Hexagon.h" 150b57cec5SDimitry Andric #include "HexagonISelLowering.h" 16e8d8bef9SDimitry Andric #include "HexagonLoopIdiomRecognition.h" 170b57cec5SDimitry Andric #include "HexagonMachineScheduler.h" 180b57cec5SDimitry Andric #include "HexagonTargetObjectFile.h" 190b57cec5SDimitry Andric #include "HexagonTargetTransformInfo.h" 20e8d8bef9SDimitry Andric #include "HexagonVectorLoopCarriedReuse.h" 210b57cec5SDimitry Andric #include "TargetInfo/HexagonTargetInfo.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 240eae32dcSDimitry Andric #include "llvm/CodeGen/VLIWMachineScheduler.h" 250b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h" 260b57cec5SDimitry Andric #include "llvm/IR/Module.h" 27349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 28e8d8bef9SDimitry Andric #include "llvm/Passes/PassBuilder.h" 290b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 300b57cec5SDimitry Andric #include "llvm/Transforms/IPO/PassManagerBuilder.h" 310b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric using namespace llvm; 340b57cec5SDimitry Andric 35*81ad6265SDimitry Andric static cl::opt<bool> 36*81ad6265SDimitry Andric EnableCExtOpt("hexagon-cext", cl::Hidden, cl::init(true), 37*81ad6265SDimitry Andric cl::desc("Enable Hexagon constant-extender optimization")); 380b57cec5SDimitry Andric 39*81ad6265SDimitry Andric static cl::opt<bool> EnableRDFOpt("rdf-opt", cl::Hidden, cl::init(true), 40*81ad6265SDimitry Andric cl::desc("Enable RDF-based optimizations")); 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric static cl::opt<bool> DisableHardwareLoops("disable-hexagon-hwloops", 430b57cec5SDimitry Andric cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target")); 440b57cec5SDimitry Andric 45*81ad6265SDimitry Andric static cl::opt<bool> 46*81ad6265SDimitry Andric DisableAModeOpt("disable-hexagon-amodeopt", cl::Hidden, 470b57cec5SDimitry Andric cl::desc("Disable Hexagon Addressing Mode Optimization")); 480b57cec5SDimitry Andric 49*81ad6265SDimitry Andric static cl::opt<bool> 50*81ad6265SDimitry Andric DisableHexagonCFGOpt("disable-hexagon-cfgopt", cl::Hidden, 510b57cec5SDimitry Andric cl::desc("Disable Hexagon CFG Optimization")); 520b57cec5SDimitry Andric 53*81ad6265SDimitry Andric static cl::opt<bool> 54*81ad6265SDimitry Andric DisableHCP("disable-hcp", cl::Hidden, 55*81ad6265SDimitry Andric cl::desc("Disable Hexagon constant propagation")); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric static cl::opt<bool> DisableStoreWidening("disable-store-widen", 580b57cec5SDimitry Andric cl::Hidden, cl::init(false), cl::desc("Disable store widening")); 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets", 61*81ad6265SDimitry Andric cl::init(true), cl::Hidden, 620b57cec5SDimitry Andric cl::desc("Early expansion of MUX")); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric static cl::opt<bool> EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden, 65*81ad6265SDimitry Andric cl::desc("Enable early if-conversion")); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric static cl::opt<bool> EnableGenInsert("hexagon-insert", cl::init(true), 680b57cec5SDimitry Andric cl::Hidden, cl::desc("Generate \"insert\" instructions")); 690b57cec5SDimitry Andric 70*81ad6265SDimitry Andric static cl::opt<bool> 71*81ad6265SDimitry Andric EnableCommGEP("hexagon-commgep", cl::init(true), cl::Hidden, 72*81ad6265SDimitry Andric cl::desc("Enable commoning of GEP instructions")); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric static cl::opt<bool> EnableGenExtract("hexagon-extract", cl::init(true), 750b57cec5SDimitry Andric cl::Hidden, cl::desc("Generate \"extract\" instructions")); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric static cl::opt<bool> EnableGenMux("hexagon-mux", cl::init(true), cl::Hidden, 780b57cec5SDimitry Andric cl::desc("Enable converting conditional transfers into MUX instructions")); 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric static cl::opt<bool> EnableGenPred("hexagon-gen-pred", cl::init(true), 810b57cec5SDimitry Andric cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " 820b57cec5SDimitry Andric "predicate instructions")); 830b57cec5SDimitry Andric 84*81ad6265SDimitry Andric static cl::opt<bool> 85*81ad6265SDimitry Andric EnableLoopPrefetch("hexagon-loop-prefetch", cl::Hidden, 860b57cec5SDimitry Andric cl::desc("Enable loop data prefetch on Hexagon")); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric static cl::opt<bool> DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden, 890b57cec5SDimitry Andric cl::desc("Disable splitting double registers")); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric static cl::opt<bool> EnableBitSimplify("hexagon-bit", cl::init(true), 920b57cec5SDimitry Andric cl::Hidden, cl::desc("Bit simplification")); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(true), 950b57cec5SDimitry Andric cl::Hidden, cl::desc("Loop rescheduling")); 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(false), 980b57cec5SDimitry Andric cl::Hidden, cl::desc("Disable backend optimizations")); 990b57cec5SDimitry Andric 100*81ad6265SDimitry Andric static cl::opt<bool> 101*81ad6265SDimitry Andric EnableVectorPrint("enable-hexagon-vector-print", cl::Hidden, 1020b57cec5SDimitry Andric cl::desc("Enable Hexagon Vector print instr pass")); 1030b57cec5SDimitry Andric 104*81ad6265SDimitry Andric static cl::opt<bool> 105*81ad6265SDimitry Andric EnableVExtractOpt("hexagon-opt-vextract", cl::Hidden, cl::init(true), 106*81ad6265SDimitry Andric cl::desc("Enable vextract optimization")); 1070b57cec5SDimitry Andric 108*81ad6265SDimitry Andric static cl::opt<bool> 109*81ad6265SDimitry Andric EnableVectorCombine("hexagon-vector-combine", cl::Hidden, cl::init(true), 110*81ad6265SDimitry Andric cl::desc("Enable HVX vector combining")); 111e8d8bef9SDimitry Andric 112*81ad6265SDimitry Andric static cl::opt<bool> EnableInitialCFGCleanup( 113*81ad6265SDimitry Andric "hexagon-initial-cfg-cleanup", cl::Hidden, cl::init(true), 1140b57cec5SDimitry Andric cl::desc("Simplify the CFG after atomic expansion pass")); 1150b57cec5SDimitry Andric 116e8d8bef9SDimitry Andric static cl::opt<bool> EnableInstSimplify("hexagon-instsimplify", cl::Hidden, 117*81ad6265SDimitry Andric cl::init(true), 118e8d8bef9SDimitry Andric cl::desc("Enable instsimplify")); 119e8d8bef9SDimitry Andric 1200b57cec5SDimitry Andric /// HexagonTargetMachineModule - Note that this is used on hosts that 1210b57cec5SDimitry Andric /// cannot link in a library unless there are references into the 1220b57cec5SDimitry Andric /// library. In particular, it seems that it is not possible to get 1230b57cec5SDimitry Andric /// things to work on Win32 without this. Though it is unused, do not 1240b57cec5SDimitry Andric /// remove it. 1250b57cec5SDimitry Andric extern "C" int HexagonTargetMachineModule; 1260b57cec5SDimitry Andric int HexagonTargetMachineModule = 0; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 1290eae32dcSDimitry Andric ScheduleDAGMILive *DAG = new VLIWMachineScheduler( 1300eae32dcSDimitry Andric C, std::make_unique<HexagonConvergingVLIWScheduler>()); 1318bcb0991SDimitry Andric DAG->addMutation(std::make_unique<HexagonSubtarget::UsrOverflowMutation>()); 1328bcb0991SDimitry Andric DAG->addMutation(std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>()); 1338bcb0991SDimitry Andric DAG->addMutation(std::make_unique<HexagonSubtarget::CallMutation>()); 1340b57cec5SDimitry Andric DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI)); 1350b57cec5SDimitry Andric return DAG; 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric static MachineSchedRegistry 1390b57cec5SDimitry Andric SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 1400b57cec5SDimitry Andric createVLIWMachineSched); 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric namespace llvm { 1430b57cec5SDimitry Andric extern char &HexagonExpandCondsetsID; 1440b57cec5SDimitry Andric void initializeHexagonBitSimplifyPass(PassRegistry&); 1450b57cec5SDimitry Andric void initializeHexagonConstExtendersPass(PassRegistry&); 1460b57cec5SDimitry Andric void initializeHexagonConstPropagationPass(PassRegistry&); 14704eeddc0SDimitry Andric void initializeHexagonCopyToCombinePass(PassRegistry&); 1480b57cec5SDimitry Andric void initializeHexagonEarlyIfConversionPass(PassRegistry&); 1490b57cec5SDimitry Andric void initializeHexagonExpandCondsetsPass(PassRegistry&); 1500b57cec5SDimitry Andric void initializeHexagonGenMuxPass(PassRegistry&); 1510b57cec5SDimitry Andric void initializeHexagonHardwareLoopsPass(PassRegistry&); 152e8d8bef9SDimitry Andric void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &); 1530b57cec5SDimitry Andric void initializeHexagonNewValueJumpPass(PassRegistry&); 1540b57cec5SDimitry Andric void initializeHexagonOptAddrModePass(PassRegistry&); 1550b57cec5SDimitry Andric void initializeHexagonPacketizerPass(PassRegistry&); 1560b57cec5SDimitry Andric void initializeHexagonRDFOptPass(PassRegistry&); 1570b57cec5SDimitry Andric void initializeHexagonSplitDoubleRegsPass(PassRegistry&); 158e8d8bef9SDimitry Andric void initializeHexagonVectorCombineLegacyPass(PassRegistry&); 159e8d8bef9SDimitry Andric void initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PassRegistry &); 1600b57cec5SDimitry Andric void initializeHexagonVExtractPass(PassRegistry&); 1610b57cec5SDimitry Andric Pass *createHexagonLoopIdiomPass(); 162e8d8bef9SDimitry Andric Pass *createHexagonVectorLoopCarriedReuseLegacyPass(); 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric FunctionPass *createHexagonBitSimplify(); 1650b57cec5SDimitry Andric FunctionPass *createHexagonBranchRelaxation(); 1660b57cec5SDimitry Andric FunctionPass *createHexagonCallFrameInformation(); 1670b57cec5SDimitry Andric FunctionPass *createHexagonCFGOptimizer(); 1680b57cec5SDimitry Andric FunctionPass *createHexagonCommonGEP(); 1690b57cec5SDimitry Andric FunctionPass *createHexagonConstExtenders(); 1700b57cec5SDimitry Andric FunctionPass *createHexagonConstPropagationPass(); 1710b57cec5SDimitry Andric FunctionPass *createHexagonCopyToCombine(); 1720b57cec5SDimitry Andric FunctionPass *createHexagonEarlyIfConversion(); 1730b57cec5SDimitry Andric FunctionPass *createHexagonFixupHwLoops(); 1740b57cec5SDimitry Andric FunctionPass *createHexagonGenExtract(); 1750b57cec5SDimitry Andric FunctionPass *createHexagonGenInsert(); 1760b57cec5SDimitry Andric FunctionPass *createHexagonGenMux(); 1770b57cec5SDimitry Andric FunctionPass *createHexagonGenPredicate(); 1780b57cec5SDimitry Andric FunctionPass *createHexagonHardwareLoops(); 1790b57cec5SDimitry Andric FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, 1800b57cec5SDimitry Andric CodeGenOpt::Level OptLevel); 1810b57cec5SDimitry Andric FunctionPass *createHexagonLoopRescheduling(); 1820b57cec5SDimitry Andric FunctionPass *createHexagonNewValueJump(); 1830b57cec5SDimitry Andric FunctionPass *createHexagonOptAddrMode(); 184e8d8bef9SDimitry Andric FunctionPass *createHexagonOptimizeSZextends(); 1850b57cec5SDimitry Andric FunctionPass *createHexagonPacketizer(bool Minimal); 1860b57cec5SDimitry Andric FunctionPass *createHexagonPeephole(); 1870b57cec5SDimitry Andric FunctionPass *createHexagonRDFOpt(); 1880b57cec5SDimitry Andric FunctionPass *createHexagonSplitConst32AndConst64(); 1890b57cec5SDimitry Andric FunctionPass *createHexagonSplitDoubleRegs(); 1900b57cec5SDimitry Andric FunctionPass *createHexagonStoreWidening(); 191e8d8bef9SDimitry Andric FunctionPass *createHexagonVectorCombineLegacyPass(); 1920b57cec5SDimitry Andric FunctionPass *createHexagonVectorPrint(); 1930b57cec5SDimitry Andric FunctionPass *createHexagonVExtract(); 1940b57cec5SDimitry Andric } // end namespace llvm; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 197*81ad6265SDimitry Andric return RM.value_or(Reloc::Static); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 200480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTarget() { 2010b57cec5SDimitry Andric // Register the target. 2020b57cec5SDimitry Andric RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget()); 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric PassRegistry &PR = *PassRegistry::getPassRegistry(); 2050b57cec5SDimitry Andric initializeHexagonBitSimplifyPass(PR); 2060b57cec5SDimitry Andric initializeHexagonConstExtendersPass(PR); 2070b57cec5SDimitry Andric initializeHexagonConstPropagationPass(PR); 20804eeddc0SDimitry Andric initializeHexagonCopyToCombinePass(PR); 2090b57cec5SDimitry Andric initializeHexagonEarlyIfConversionPass(PR); 2100b57cec5SDimitry Andric initializeHexagonGenMuxPass(PR); 2110b57cec5SDimitry Andric initializeHexagonHardwareLoopsPass(PR); 212e8d8bef9SDimitry Andric initializeHexagonLoopIdiomRecognizeLegacyPassPass(PR); 2130b57cec5SDimitry Andric initializeHexagonNewValueJumpPass(PR); 2140b57cec5SDimitry Andric initializeHexagonOptAddrModePass(PR); 2150b57cec5SDimitry Andric initializeHexagonPacketizerPass(PR); 2160b57cec5SDimitry Andric initializeHexagonRDFOptPass(PR); 2170b57cec5SDimitry Andric initializeHexagonSplitDoubleRegsPass(PR); 218e8d8bef9SDimitry Andric initializeHexagonVectorCombineLegacyPass(PR); 219e8d8bef9SDimitry Andric initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR); 2200b57cec5SDimitry Andric initializeHexagonVExtractPass(PR); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, 2240b57cec5SDimitry Andric StringRef CPU, StringRef FS, 2250b57cec5SDimitry Andric const TargetOptions &Options, 2260b57cec5SDimitry Andric Optional<Reloc::Model> RM, 2270b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 2280b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT) 2290b57cec5SDimitry Andric // Specify the vector alignment explicitly. For v512x1, the calculated 2300b57cec5SDimitry Andric // alignment would be 512*alignment(i1), which is 512 bytes, instead of 2310b57cec5SDimitry Andric // the required minimum of 64 bytes. 2320b57cec5SDimitry Andric : LLVMTargetMachine( 2330b57cec5SDimitry Andric T, 2340b57cec5SDimitry Andric "e-m:e-p:32:32:32-a:0-n16:32-" 2350b57cec5SDimitry Andric "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" 2360b57cec5SDimitry Andric "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048", 2370b57cec5SDimitry Andric TT, CPU, FS, Options, getEffectiveRelocModel(RM), 2380b57cec5SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), 2390b57cec5SDimitry Andric (HexagonNoOpt ? CodeGenOpt::None : OL)), 2408bcb0991SDimitry Andric TLOF(std::make_unique<HexagonTargetObjectFile>()) { 2410b57cec5SDimitry Andric initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry()); 2420b57cec5SDimitry Andric initAsmInfo(); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric const HexagonSubtarget * 2460b57cec5SDimitry Andric HexagonTargetMachine::getSubtargetImpl(const Function &F) const { 2470b57cec5SDimitry Andric AttributeList FnAttrs = F.getAttributes(); 2480b57cec5SDimitry Andric Attribute CPUAttr = 249349cc55cSDimitry Andric FnAttrs.getFnAttr("target-cpu"); 2500b57cec5SDimitry Andric Attribute FSAttr = 251349cc55cSDimitry Andric FnAttrs.getFnAttr("target-features"); 2520b57cec5SDimitry Andric 253e8d8bef9SDimitry Andric std::string CPU = 254e8d8bef9SDimitry Andric CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 255e8d8bef9SDimitry Andric std::string FS = 256e8d8bef9SDimitry Andric FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 2575ffd83dbSDimitry Andric // Append the preexisting target features last, so that +mattr overrides 2585ffd83dbSDimitry Andric // the "unsafe-fp-math" function attribute. 2595ffd83dbSDimitry Andric // Creating a separate target feature is not strictly necessary, it only 2605ffd83dbSDimitry Andric // exists to make "unsafe-fp-math" force creating a new subtarget. 2615ffd83dbSDimitry Andric 262fe6060f1SDimitry Andric if (F.getFnAttribute("unsafe-fp-math").getValueAsBool()) 2635ffd83dbSDimitry Andric FS = FS.empty() ? "+unsafe-fp" : "+unsafe-fp," + FS; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric auto &I = SubtargetMap[CPU + FS]; 2660b57cec5SDimitry Andric if (!I) { 2670b57cec5SDimitry Andric // This needs to be done before we create a new subtarget since any 2680b57cec5SDimitry Andric // creation will depend on the TM and the code generation flags on the 2690b57cec5SDimitry Andric // function that reside in TargetOptions. 2700b57cec5SDimitry Andric resetTargetOptions(F); 2718bcb0991SDimitry Andric I = std::make_unique<HexagonSubtarget>(TargetTriple, CPU, FS, *this); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric return I.get(); 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric void HexagonTargetMachine::adjustPassManager(PassManagerBuilder &PMB) { 2770b57cec5SDimitry Andric PMB.addExtension( 2780b57cec5SDimitry Andric PassManagerBuilder::EP_LateLoopOptimizations, 2790b57cec5SDimitry Andric [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 2800b57cec5SDimitry Andric PM.add(createHexagonLoopIdiomPass()); 2810b57cec5SDimitry Andric }); 2820b57cec5SDimitry Andric PMB.addExtension( 2830b57cec5SDimitry Andric PassManagerBuilder::EP_LoopOptimizerEnd, 2840b57cec5SDimitry Andric [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 285e8d8bef9SDimitry Andric PM.add(createHexagonVectorLoopCarriedReuseLegacyPass()); 286e8d8bef9SDimitry Andric }); 287e8d8bef9SDimitry Andric } 288e8d8bef9SDimitry Andric 289fe6060f1SDimitry Andric void HexagonTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { 290e8d8bef9SDimitry Andric PB.registerLateLoopOptimizationsEPCallback( 291349cc55cSDimitry Andric [=](LoopPassManager &LPM, OptimizationLevel Level) { 292e8d8bef9SDimitry Andric LPM.addPass(HexagonLoopIdiomRecognitionPass()); 293e8d8bef9SDimitry Andric }); 294e8d8bef9SDimitry Andric PB.registerLoopOptimizerEndEPCallback( 295349cc55cSDimitry Andric [=](LoopPassManager &LPM, OptimizationLevel Level) { 296e8d8bef9SDimitry Andric LPM.addPass(HexagonVectorLoopCarriedReusePass()); 2970b57cec5SDimitry Andric }); 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric TargetTransformInfo 301*81ad6265SDimitry Andric HexagonTargetMachine::getTargetTransformInfo(const Function &F) const { 3020b57cec5SDimitry Andric return TargetTransformInfo(HexagonTTIImpl(this, F)); 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 305*81ad6265SDimitry Andric HexagonTargetMachine::~HexagonTargetMachine() = default; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric namespace { 3080b57cec5SDimitry Andric /// Hexagon Code Generator Pass Configuration Options. 3090b57cec5SDimitry Andric class HexagonPassConfig : public TargetPassConfig { 3100b57cec5SDimitry Andric public: 3110b57cec5SDimitry Andric HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM) 3120b57cec5SDimitry Andric : TargetPassConfig(TM, PM) {} 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric HexagonTargetMachine &getHexagonTargetMachine() const { 3150b57cec5SDimitry Andric return getTM<HexagonTargetMachine>(); 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric ScheduleDAGInstrs * 3190b57cec5SDimitry Andric createMachineScheduler(MachineSchedContext *C) const override { 3200b57cec5SDimitry Andric return createVLIWMachineSched(C); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric void addIRPasses() override; 3240b57cec5SDimitry Andric bool addInstSelector() override; 3250b57cec5SDimitry Andric void addPreRegAlloc() override; 3260b57cec5SDimitry Andric void addPostRegAlloc() override; 3270b57cec5SDimitry Andric void addPreSched2() override; 3280b57cec5SDimitry Andric void addPreEmitPass() override; 3290b57cec5SDimitry Andric }; 3300b57cec5SDimitry Andric } // namespace 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 3330b57cec5SDimitry Andric return new HexagonPassConfig(*this, PM); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric void HexagonPassConfig::addIRPasses() { 3370b57cec5SDimitry Andric TargetPassConfig::addIRPasses(); 3380b57cec5SDimitry Andric bool NoOpt = (getOptLevel() == CodeGenOpt::None); 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric if (!NoOpt) { 341e8d8bef9SDimitry Andric if (EnableInstSimplify) 342e8d8bef9SDimitry Andric addPass(createInstSimplifyLegacyPass()); 3430b57cec5SDimitry Andric addPass(createDeadCodeEliminationPass()); 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric addPass(createAtomicExpandPass()); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric if (!NoOpt) { 3490b57cec5SDimitry Andric if (EnableInitialCFGCleanup) 350e8d8bef9SDimitry Andric addPass(createCFGSimplificationPass(SimplifyCFGOptions() 351e8d8bef9SDimitry Andric .forwardSwitchCondToPhi(true) 352fb03ea46SDimitry Andric .convertSwitchRangeToICmp(true) 353e8d8bef9SDimitry Andric .convertSwitchToLookupTable(true) 354e8d8bef9SDimitry Andric .needCanonicalLoops(false) 355e8d8bef9SDimitry Andric .hoistCommonInsts(true) 356e8d8bef9SDimitry Andric .sinkCommonInsts(true))); 3570b57cec5SDimitry Andric if (EnableLoopPrefetch) 3580b57cec5SDimitry Andric addPass(createLoopDataPrefetchPass()); 359e8d8bef9SDimitry Andric if (EnableVectorCombine) 360e8d8bef9SDimitry Andric addPass(createHexagonVectorCombineLegacyPass()); 3610b57cec5SDimitry Andric if (EnableCommGEP) 3620b57cec5SDimitry Andric addPass(createHexagonCommonGEP()); 3630b57cec5SDimitry Andric // Replace certain combinations of shifts and ands with extracts. 3640b57cec5SDimitry Andric if (EnableGenExtract) 3650b57cec5SDimitry Andric addPass(createHexagonGenExtract()); 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric bool HexagonPassConfig::addInstSelector() { 3700b57cec5SDimitry Andric HexagonTargetMachine &TM = getHexagonTargetMachine(); 3710b57cec5SDimitry Andric bool NoOpt = (getOptLevel() == CodeGenOpt::None); 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric if (!NoOpt) 3740b57cec5SDimitry Andric addPass(createHexagonOptimizeSZextends()); 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric addPass(createHexagonISelDag(TM, getOptLevel())); 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric if (!NoOpt) { 3790b57cec5SDimitry Andric if (EnableVExtractOpt) 3800b57cec5SDimitry Andric addPass(createHexagonVExtract()); 3810b57cec5SDimitry Andric // Create logical operations on predicate registers. 3820b57cec5SDimitry Andric if (EnableGenPred) 3830b57cec5SDimitry Andric addPass(createHexagonGenPredicate()); 3840b57cec5SDimitry Andric // Rotate loops to expose bit-simplification opportunities. 3850b57cec5SDimitry Andric if (EnableLoopResched) 3860b57cec5SDimitry Andric addPass(createHexagonLoopRescheduling()); 3870b57cec5SDimitry Andric // Split double registers. 3880b57cec5SDimitry Andric if (!DisableHSDR) 3890b57cec5SDimitry Andric addPass(createHexagonSplitDoubleRegs()); 3900b57cec5SDimitry Andric // Bit simplification. 3910b57cec5SDimitry Andric if (EnableBitSimplify) 3920b57cec5SDimitry Andric addPass(createHexagonBitSimplify()); 3930b57cec5SDimitry Andric addPass(createHexagonPeephole()); 3940b57cec5SDimitry Andric // Constant propagation. 3950b57cec5SDimitry Andric if (!DisableHCP) { 3960b57cec5SDimitry Andric addPass(createHexagonConstPropagationPass()); 3970b57cec5SDimitry Andric addPass(&UnreachableMachineBlockElimID); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric if (EnableGenInsert) 4000b57cec5SDimitry Andric addPass(createHexagonGenInsert()); 4010b57cec5SDimitry Andric if (EnableEarlyIf) 4020b57cec5SDimitry Andric addPass(createHexagonEarlyIfConversion()); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric return false; 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric void HexagonPassConfig::addPreRegAlloc() { 4090b57cec5SDimitry Andric if (getOptLevel() != CodeGenOpt::None) { 4100b57cec5SDimitry Andric if (EnableCExtOpt) 4110b57cec5SDimitry Andric addPass(createHexagonConstExtenders()); 4120b57cec5SDimitry Andric if (EnableExpandCondsets) 4130b57cec5SDimitry Andric insertPass(&RegisterCoalescerID, &HexagonExpandCondsetsID); 4140b57cec5SDimitry Andric if (!DisableStoreWidening) 4150b57cec5SDimitry Andric addPass(createHexagonStoreWidening()); 4160b57cec5SDimitry Andric if (!DisableHardwareLoops) 4170b57cec5SDimitry Andric addPass(createHexagonHardwareLoops()); 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric if (TM->getOptLevel() >= CodeGenOpt::Default) 4200b57cec5SDimitry Andric addPass(&MachinePipelinerID); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric void HexagonPassConfig::addPostRegAlloc() { 4240b57cec5SDimitry Andric if (getOptLevel() != CodeGenOpt::None) { 4250b57cec5SDimitry Andric if (EnableRDFOpt) 4260b57cec5SDimitry Andric addPass(createHexagonRDFOpt()); 4270b57cec5SDimitry Andric if (!DisableHexagonCFGOpt) 4280b57cec5SDimitry Andric addPass(createHexagonCFGOptimizer()); 4290b57cec5SDimitry Andric if (!DisableAModeOpt) 4300b57cec5SDimitry Andric addPass(createHexagonOptAddrMode()); 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric void HexagonPassConfig::addPreSched2() { 4350b57cec5SDimitry Andric addPass(createHexagonCopyToCombine()); 4360b57cec5SDimitry Andric if (getOptLevel() != CodeGenOpt::None) 4370b57cec5SDimitry Andric addPass(&IfConverterID); 4380b57cec5SDimitry Andric addPass(createHexagonSplitConst32AndConst64()); 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric void HexagonPassConfig::addPreEmitPass() { 4420b57cec5SDimitry Andric bool NoOpt = (getOptLevel() == CodeGenOpt::None); 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric if (!NoOpt) 4450b57cec5SDimitry Andric addPass(createHexagonNewValueJump()); 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric addPass(createHexagonBranchRelaxation()); 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric if (!NoOpt) { 4500b57cec5SDimitry Andric if (!DisableHardwareLoops) 4510b57cec5SDimitry Andric addPass(createHexagonFixupHwLoops()); 4520b57cec5SDimitry Andric // Generate MUX from pairs of conditional transfers. 4530b57cec5SDimitry Andric if (EnableGenMux) 4540b57cec5SDimitry Andric addPass(createHexagonGenMux()); 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric // Packetization is mandatory: it handles gather/scatter at all opt levels. 458349cc55cSDimitry Andric addPass(createHexagonPacketizer(NoOpt)); 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric if (EnableVectorPrint) 461349cc55cSDimitry Andric addPass(createHexagonVectorPrint()); 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric // Add CFI instructions if necessary. 464349cc55cSDimitry Andric addPass(createHexagonCallFrameInformation()); 4650b57cec5SDimitry Andric } 466