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 350b57cec5SDimitry Andric static cl::opt<bool> EnableCExtOpt("hexagon-cext", cl::Hidden, cl::ZeroOrMore, 360b57cec5SDimitry Andric cl::init(true), cl::desc("Enable Hexagon constant-extender optimization")); 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric static cl::opt<bool> EnableRDFOpt("rdf-opt", cl::Hidden, cl::ZeroOrMore, 390b57cec5SDimitry Andric cl::init(true), cl::desc("Enable RDF-based optimizations")); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric static cl::opt<bool> DisableHardwareLoops("disable-hexagon-hwloops", 420b57cec5SDimitry Andric cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target")); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric static cl::opt<bool> DisableAModeOpt("disable-hexagon-amodeopt", 450b57cec5SDimitry Andric cl::Hidden, cl::ZeroOrMore, cl::init(false), 460b57cec5SDimitry Andric cl::desc("Disable Hexagon Addressing Mode Optimization")); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt", 490b57cec5SDimitry Andric cl::Hidden, cl::ZeroOrMore, cl::init(false), 500b57cec5SDimitry Andric cl::desc("Disable Hexagon CFG Optimization")); 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric static cl::opt<bool> DisableHCP("disable-hcp", cl::init(false), cl::Hidden, 530b57cec5SDimitry Andric cl::ZeroOrMore, cl::desc("Disable Hexagon constant propagation")); 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric static cl::opt<bool> DisableStoreWidening("disable-store-widen", 560b57cec5SDimitry Andric cl::Hidden, cl::init(false), cl::desc("Disable store widening")); 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets", 590b57cec5SDimitry Andric cl::init(true), cl::Hidden, cl::ZeroOrMore, 600b57cec5SDimitry Andric cl::desc("Early expansion of MUX")); 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric static cl::opt<bool> EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden, 630b57cec5SDimitry Andric cl::ZeroOrMore, cl::desc("Enable early if-conversion")); 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric static cl::opt<bool> EnableGenInsert("hexagon-insert", cl::init(true), 660b57cec5SDimitry Andric cl::Hidden, cl::desc("Generate \"insert\" instructions")); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric static cl::opt<bool> EnableCommGEP("hexagon-commgep", cl::init(true), 690b57cec5SDimitry Andric cl::Hidden, cl::ZeroOrMore, cl::desc("Enable commoning of GEP instructions")); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric static cl::opt<bool> EnableGenExtract("hexagon-extract", cl::init(true), 720b57cec5SDimitry Andric cl::Hidden, cl::desc("Generate \"extract\" instructions")); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric static cl::opt<bool> EnableGenMux("hexagon-mux", cl::init(true), cl::Hidden, 750b57cec5SDimitry Andric cl::desc("Enable converting conditional transfers into MUX instructions")); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric static cl::opt<bool> EnableGenPred("hexagon-gen-pred", cl::init(true), 780b57cec5SDimitry Andric cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " 790b57cec5SDimitry Andric "predicate instructions")); 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric static cl::opt<bool> EnableLoopPrefetch("hexagon-loop-prefetch", 820b57cec5SDimitry Andric cl::init(false), cl::Hidden, cl::ZeroOrMore, 830b57cec5SDimitry Andric cl::desc("Enable loop data prefetch on Hexagon")); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric static cl::opt<bool> DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden, 860b57cec5SDimitry Andric cl::desc("Disable splitting double registers")); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric static cl::opt<bool> EnableBitSimplify("hexagon-bit", cl::init(true), 890b57cec5SDimitry Andric cl::Hidden, cl::desc("Bit simplification")); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(true), 920b57cec5SDimitry Andric cl::Hidden, cl::desc("Loop rescheduling")); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(false), 950b57cec5SDimitry Andric cl::Hidden, cl::desc("Disable backend optimizations")); 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric static cl::opt<bool> EnableVectorPrint("enable-hexagon-vector-print", 980b57cec5SDimitry Andric cl::Hidden, cl::ZeroOrMore, cl::init(false), 990b57cec5SDimitry Andric cl::desc("Enable Hexagon Vector print instr pass")); 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric static cl::opt<bool> EnableVExtractOpt("hexagon-opt-vextract", cl::Hidden, 1020b57cec5SDimitry Andric cl::ZeroOrMore, cl::init(true), cl::desc("Enable vextract optimization")); 1030b57cec5SDimitry Andric 104e8d8bef9SDimitry Andric static cl::opt<bool> EnableVectorCombine("hexagon-vector-combine", cl::Hidden, 105e8d8bef9SDimitry Andric cl::ZeroOrMore, cl::init(true), cl::desc("Enable HVX vector combining")); 106e8d8bef9SDimitry Andric 1070b57cec5SDimitry Andric static cl::opt<bool> EnableInitialCFGCleanup("hexagon-initial-cfg-cleanup", 1080b57cec5SDimitry Andric cl::Hidden, cl::ZeroOrMore, cl::init(true), 1090b57cec5SDimitry Andric cl::desc("Simplify the CFG after atomic expansion pass")); 1100b57cec5SDimitry Andric 111e8d8bef9SDimitry Andric static cl::opt<bool> EnableInstSimplify("hexagon-instsimplify", cl::Hidden, 112e8d8bef9SDimitry Andric cl::ZeroOrMore, cl::init(true), 113e8d8bef9SDimitry Andric cl::desc("Enable instsimplify")); 114e8d8bef9SDimitry Andric 1150b57cec5SDimitry Andric /// HexagonTargetMachineModule - Note that this is used on hosts that 1160b57cec5SDimitry Andric /// cannot link in a library unless there are references into the 1170b57cec5SDimitry Andric /// library. In particular, it seems that it is not possible to get 1180b57cec5SDimitry Andric /// things to work on Win32 without this. Though it is unused, do not 1190b57cec5SDimitry Andric /// remove it. 1200b57cec5SDimitry Andric extern "C" int HexagonTargetMachineModule; 1210b57cec5SDimitry Andric int HexagonTargetMachineModule = 0; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 1240eae32dcSDimitry Andric ScheduleDAGMILive *DAG = new VLIWMachineScheduler( 1250eae32dcSDimitry Andric C, std::make_unique<HexagonConvergingVLIWScheduler>()); 1268bcb0991SDimitry Andric DAG->addMutation(std::make_unique<HexagonSubtarget::UsrOverflowMutation>()); 1278bcb0991SDimitry Andric DAG->addMutation(std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>()); 1288bcb0991SDimitry Andric DAG->addMutation(std::make_unique<HexagonSubtarget::CallMutation>()); 1290b57cec5SDimitry Andric DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI)); 1300b57cec5SDimitry Andric return DAG; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric static MachineSchedRegistry 1340b57cec5SDimitry Andric SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 1350b57cec5SDimitry Andric createVLIWMachineSched); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric namespace llvm { 1380b57cec5SDimitry Andric extern char &HexagonExpandCondsetsID; 1390b57cec5SDimitry Andric void initializeHexagonBitSimplifyPass(PassRegistry&); 1400b57cec5SDimitry Andric void initializeHexagonConstExtendersPass(PassRegistry&); 1410b57cec5SDimitry Andric void initializeHexagonConstPropagationPass(PassRegistry&); 14204eeddc0SDimitry Andric void initializeHexagonCopyToCombinePass(PassRegistry&); 1430b57cec5SDimitry Andric void initializeHexagonEarlyIfConversionPass(PassRegistry&); 1440b57cec5SDimitry Andric void initializeHexagonExpandCondsetsPass(PassRegistry&); 1450b57cec5SDimitry Andric void initializeHexagonGenMuxPass(PassRegistry&); 1460b57cec5SDimitry Andric void initializeHexagonHardwareLoopsPass(PassRegistry&); 147e8d8bef9SDimitry Andric void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &); 1480b57cec5SDimitry Andric void initializeHexagonNewValueJumpPass(PassRegistry&); 1490b57cec5SDimitry Andric void initializeHexagonOptAddrModePass(PassRegistry&); 1500b57cec5SDimitry Andric void initializeHexagonPacketizerPass(PassRegistry&); 1510b57cec5SDimitry Andric void initializeHexagonRDFOptPass(PassRegistry&); 1520b57cec5SDimitry Andric void initializeHexagonSplitDoubleRegsPass(PassRegistry&); 153e8d8bef9SDimitry Andric void initializeHexagonVectorCombineLegacyPass(PassRegistry&); 154e8d8bef9SDimitry Andric void initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PassRegistry &); 1550b57cec5SDimitry Andric void initializeHexagonVExtractPass(PassRegistry&); 1560b57cec5SDimitry Andric Pass *createHexagonLoopIdiomPass(); 157e8d8bef9SDimitry Andric Pass *createHexagonVectorLoopCarriedReuseLegacyPass(); 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric FunctionPass *createHexagonBitSimplify(); 1600b57cec5SDimitry Andric FunctionPass *createHexagonBranchRelaxation(); 1610b57cec5SDimitry Andric FunctionPass *createHexagonCallFrameInformation(); 1620b57cec5SDimitry Andric FunctionPass *createHexagonCFGOptimizer(); 1630b57cec5SDimitry Andric FunctionPass *createHexagonCommonGEP(); 1640b57cec5SDimitry Andric FunctionPass *createHexagonConstExtenders(); 1650b57cec5SDimitry Andric FunctionPass *createHexagonConstPropagationPass(); 1660b57cec5SDimitry Andric FunctionPass *createHexagonCopyToCombine(); 1670b57cec5SDimitry Andric FunctionPass *createHexagonEarlyIfConversion(); 1680b57cec5SDimitry Andric FunctionPass *createHexagonFixupHwLoops(); 1690b57cec5SDimitry Andric FunctionPass *createHexagonGenExtract(); 1700b57cec5SDimitry Andric FunctionPass *createHexagonGenInsert(); 1710b57cec5SDimitry Andric FunctionPass *createHexagonGenMux(); 1720b57cec5SDimitry Andric FunctionPass *createHexagonGenPredicate(); 1730b57cec5SDimitry Andric FunctionPass *createHexagonHardwareLoops(); 1740b57cec5SDimitry Andric FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, 1750b57cec5SDimitry Andric CodeGenOpt::Level OptLevel); 1760b57cec5SDimitry Andric FunctionPass *createHexagonLoopRescheduling(); 1770b57cec5SDimitry Andric FunctionPass *createHexagonNewValueJump(); 1780b57cec5SDimitry Andric FunctionPass *createHexagonOptAddrMode(); 179e8d8bef9SDimitry Andric FunctionPass *createHexagonOptimizeSZextends(); 1800b57cec5SDimitry Andric FunctionPass *createHexagonPacketizer(bool Minimal); 1810b57cec5SDimitry Andric FunctionPass *createHexagonPeephole(); 1820b57cec5SDimitry Andric FunctionPass *createHexagonRDFOpt(); 1830b57cec5SDimitry Andric FunctionPass *createHexagonSplitConst32AndConst64(); 1840b57cec5SDimitry Andric FunctionPass *createHexagonSplitDoubleRegs(); 1850b57cec5SDimitry Andric FunctionPass *createHexagonStoreWidening(); 186e8d8bef9SDimitry Andric FunctionPass *createHexagonVectorCombineLegacyPass(); 1870b57cec5SDimitry Andric FunctionPass *createHexagonVectorPrint(); 1880b57cec5SDimitry Andric FunctionPass *createHexagonVExtract(); 1890b57cec5SDimitry Andric } // end namespace llvm; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 192e8d8bef9SDimitry Andric return RM.getValueOr(Reloc::Static); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 195480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonTarget() { 1960b57cec5SDimitry Andric // Register the target. 1970b57cec5SDimitry Andric RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget()); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric PassRegistry &PR = *PassRegistry::getPassRegistry(); 2000b57cec5SDimitry Andric initializeHexagonBitSimplifyPass(PR); 2010b57cec5SDimitry Andric initializeHexagonConstExtendersPass(PR); 2020b57cec5SDimitry Andric initializeHexagonConstPropagationPass(PR); 20304eeddc0SDimitry Andric initializeHexagonCopyToCombinePass(PR); 2040b57cec5SDimitry Andric initializeHexagonEarlyIfConversionPass(PR); 2050b57cec5SDimitry Andric initializeHexagonGenMuxPass(PR); 2060b57cec5SDimitry Andric initializeHexagonHardwareLoopsPass(PR); 207e8d8bef9SDimitry Andric initializeHexagonLoopIdiomRecognizeLegacyPassPass(PR); 2080b57cec5SDimitry Andric initializeHexagonNewValueJumpPass(PR); 2090b57cec5SDimitry Andric initializeHexagonOptAddrModePass(PR); 2100b57cec5SDimitry Andric initializeHexagonPacketizerPass(PR); 2110b57cec5SDimitry Andric initializeHexagonRDFOptPass(PR); 2120b57cec5SDimitry Andric initializeHexagonSplitDoubleRegsPass(PR); 213e8d8bef9SDimitry Andric initializeHexagonVectorCombineLegacyPass(PR); 214e8d8bef9SDimitry Andric initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PR); 2150b57cec5SDimitry Andric initializeHexagonVExtractPass(PR); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, 2190b57cec5SDimitry Andric StringRef CPU, StringRef FS, 2200b57cec5SDimitry Andric const TargetOptions &Options, 2210b57cec5SDimitry Andric Optional<Reloc::Model> RM, 2220b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 2230b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT) 2240b57cec5SDimitry Andric // Specify the vector alignment explicitly. For v512x1, the calculated 2250b57cec5SDimitry Andric // alignment would be 512*alignment(i1), which is 512 bytes, instead of 2260b57cec5SDimitry Andric // the required minimum of 64 bytes. 2270b57cec5SDimitry Andric : LLVMTargetMachine( 2280b57cec5SDimitry Andric T, 2290b57cec5SDimitry Andric "e-m:e-p:32:32:32-a:0-n16:32-" 2300b57cec5SDimitry Andric "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" 2310b57cec5SDimitry Andric "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048", 2320b57cec5SDimitry Andric TT, CPU, FS, Options, getEffectiveRelocModel(RM), 2330b57cec5SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), 2340b57cec5SDimitry Andric (HexagonNoOpt ? CodeGenOpt::None : OL)), 2358bcb0991SDimitry Andric TLOF(std::make_unique<HexagonTargetObjectFile>()) { 2360b57cec5SDimitry Andric initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry()); 2370b57cec5SDimitry Andric initAsmInfo(); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric const HexagonSubtarget * 2410b57cec5SDimitry Andric HexagonTargetMachine::getSubtargetImpl(const Function &F) const { 2420b57cec5SDimitry Andric AttributeList FnAttrs = F.getAttributes(); 2430b57cec5SDimitry Andric Attribute CPUAttr = 244349cc55cSDimitry Andric FnAttrs.getFnAttr("target-cpu"); 2450b57cec5SDimitry Andric Attribute FSAttr = 246349cc55cSDimitry Andric FnAttrs.getFnAttr("target-features"); 2470b57cec5SDimitry Andric 248e8d8bef9SDimitry Andric std::string CPU = 249e8d8bef9SDimitry Andric CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 250e8d8bef9SDimitry Andric std::string FS = 251e8d8bef9SDimitry Andric FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 2525ffd83dbSDimitry Andric // Append the preexisting target features last, so that +mattr overrides 2535ffd83dbSDimitry Andric // the "unsafe-fp-math" function attribute. 2545ffd83dbSDimitry Andric // Creating a separate target feature is not strictly necessary, it only 2555ffd83dbSDimitry Andric // exists to make "unsafe-fp-math" force creating a new subtarget. 2565ffd83dbSDimitry Andric 257fe6060f1SDimitry Andric if (F.getFnAttribute("unsafe-fp-math").getValueAsBool()) 2585ffd83dbSDimitry Andric FS = FS.empty() ? "+unsafe-fp" : "+unsafe-fp," + FS; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric auto &I = SubtargetMap[CPU + FS]; 2610b57cec5SDimitry Andric if (!I) { 2620b57cec5SDimitry Andric // This needs to be done before we create a new subtarget since any 2630b57cec5SDimitry Andric // creation will depend on the TM and the code generation flags on the 2640b57cec5SDimitry Andric // function that reside in TargetOptions. 2650b57cec5SDimitry Andric resetTargetOptions(F); 2668bcb0991SDimitry Andric I = std::make_unique<HexagonSubtarget>(TargetTriple, CPU, FS, *this); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric return I.get(); 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric void HexagonTargetMachine::adjustPassManager(PassManagerBuilder &PMB) { 2720b57cec5SDimitry Andric PMB.addExtension( 2730b57cec5SDimitry Andric PassManagerBuilder::EP_LateLoopOptimizations, 2740b57cec5SDimitry Andric [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 2750b57cec5SDimitry Andric PM.add(createHexagonLoopIdiomPass()); 2760b57cec5SDimitry Andric }); 2770b57cec5SDimitry Andric PMB.addExtension( 2780b57cec5SDimitry Andric PassManagerBuilder::EP_LoopOptimizerEnd, 2790b57cec5SDimitry Andric [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 280e8d8bef9SDimitry Andric PM.add(createHexagonVectorLoopCarriedReuseLegacyPass()); 281e8d8bef9SDimitry Andric }); 282e8d8bef9SDimitry Andric } 283e8d8bef9SDimitry Andric 284fe6060f1SDimitry Andric void HexagonTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { 285e8d8bef9SDimitry Andric PB.registerLateLoopOptimizationsEPCallback( 286349cc55cSDimitry Andric [=](LoopPassManager &LPM, OptimizationLevel Level) { 287e8d8bef9SDimitry Andric LPM.addPass(HexagonLoopIdiomRecognitionPass()); 288e8d8bef9SDimitry Andric }); 289e8d8bef9SDimitry Andric PB.registerLoopOptimizerEndEPCallback( 290349cc55cSDimitry Andric [=](LoopPassManager &LPM, OptimizationLevel Level) { 291e8d8bef9SDimitry Andric LPM.addPass(HexagonVectorLoopCarriedReusePass()); 2920b57cec5SDimitry Andric }); 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric TargetTransformInfo 2960b57cec5SDimitry Andric HexagonTargetMachine::getTargetTransformInfo(const Function &F) { 2970b57cec5SDimitry Andric return TargetTransformInfo(HexagonTTIImpl(this, F)); 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric HexagonTargetMachine::~HexagonTargetMachine() {} 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric namespace { 3040b57cec5SDimitry Andric /// Hexagon Code Generator Pass Configuration Options. 3050b57cec5SDimitry Andric class HexagonPassConfig : public TargetPassConfig { 3060b57cec5SDimitry Andric public: 3070b57cec5SDimitry Andric HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM) 3080b57cec5SDimitry Andric : TargetPassConfig(TM, PM) {} 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric HexagonTargetMachine &getHexagonTargetMachine() const { 3110b57cec5SDimitry Andric return getTM<HexagonTargetMachine>(); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric ScheduleDAGInstrs * 3150b57cec5SDimitry Andric createMachineScheduler(MachineSchedContext *C) const override { 3160b57cec5SDimitry Andric return createVLIWMachineSched(C); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric void addIRPasses() override; 3200b57cec5SDimitry Andric bool addInstSelector() override; 3210b57cec5SDimitry Andric void addPreRegAlloc() override; 3220b57cec5SDimitry Andric void addPostRegAlloc() override; 3230b57cec5SDimitry Andric void addPreSched2() override; 3240b57cec5SDimitry Andric void addPreEmitPass() override; 3250b57cec5SDimitry Andric }; 3260b57cec5SDimitry Andric } // namespace 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 3290b57cec5SDimitry Andric return new HexagonPassConfig(*this, PM); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric void HexagonPassConfig::addIRPasses() { 3330b57cec5SDimitry Andric TargetPassConfig::addIRPasses(); 3340b57cec5SDimitry Andric bool NoOpt = (getOptLevel() == CodeGenOpt::None); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric if (!NoOpt) { 337e8d8bef9SDimitry Andric if (EnableInstSimplify) 338e8d8bef9SDimitry Andric addPass(createInstSimplifyLegacyPass()); 3390b57cec5SDimitry Andric addPass(createDeadCodeEliminationPass()); 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric addPass(createAtomicExpandPass()); 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric if (!NoOpt) { 3450b57cec5SDimitry Andric if (EnableInitialCFGCleanup) 346e8d8bef9SDimitry Andric addPass(createCFGSimplificationPass(SimplifyCFGOptions() 347e8d8bef9SDimitry Andric .forwardSwitchCondToPhi(true) 348*fb03ea46SDimitry Andric .convertSwitchRangeToICmp(true) 349e8d8bef9SDimitry Andric .convertSwitchToLookupTable(true) 350e8d8bef9SDimitry Andric .needCanonicalLoops(false) 351e8d8bef9SDimitry Andric .hoistCommonInsts(true) 352e8d8bef9SDimitry Andric .sinkCommonInsts(true))); 3530b57cec5SDimitry Andric if (EnableLoopPrefetch) 3540b57cec5SDimitry Andric addPass(createLoopDataPrefetchPass()); 355e8d8bef9SDimitry Andric if (EnableVectorCombine) 356e8d8bef9SDimitry Andric addPass(createHexagonVectorCombineLegacyPass()); 3570b57cec5SDimitry Andric if (EnableCommGEP) 3580b57cec5SDimitry Andric addPass(createHexagonCommonGEP()); 3590b57cec5SDimitry Andric // Replace certain combinations of shifts and ands with extracts. 3600b57cec5SDimitry Andric if (EnableGenExtract) 3610b57cec5SDimitry Andric addPass(createHexagonGenExtract()); 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric bool HexagonPassConfig::addInstSelector() { 3660b57cec5SDimitry Andric HexagonTargetMachine &TM = getHexagonTargetMachine(); 3670b57cec5SDimitry Andric bool NoOpt = (getOptLevel() == CodeGenOpt::None); 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric if (!NoOpt) 3700b57cec5SDimitry Andric addPass(createHexagonOptimizeSZextends()); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric addPass(createHexagonISelDag(TM, getOptLevel())); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric if (!NoOpt) { 3750b57cec5SDimitry Andric if (EnableVExtractOpt) 3760b57cec5SDimitry Andric addPass(createHexagonVExtract()); 3770b57cec5SDimitry Andric // Create logical operations on predicate registers. 3780b57cec5SDimitry Andric if (EnableGenPred) 3790b57cec5SDimitry Andric addPass(createHexagonGenPredicate()); 3800b57cec5SDimitry Andric // Rotate loops to expose bit-simplification opportunities. 3810b57cec5SDimitry Andric if (EnableLoopResched) 3820b57cec5SDimitry Andric addPass(createHexagonLoopRescheduling()); 3830b57cec5SDimitry Andric // Split double registers. 3840b57cec5SDimitry Andric if (!DisableHSDR) 3850b57cec5SDimitry Andric addPass(createHexagonSplitDoubleRegs()); 3860b57cec5SDimitry Andric // Bit simplification. 3870b57cec5SDimitry Andric if (EnableBitSimplify) 3880b57cec5SDimitry Andric addPass(createHexagonBitSimplify()); 3890b57cec5SDimitry Andric addPass(createHexagonPeephole()); 3900b57cec5SDimitry Andric // Constant propagation. 3910b57cec5SDimitry Andric if (!DisableHCP) { 3920b57cec5SDimitry Andric addPass(createHexagonConstPropagationPass()); 3930b57cec5SDimitry Andric addPass(&UnreachableMachineBlockElimID); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric if (EnableGenInsert) 3960b57cec5SDimitry Andric addPass(createHexagonGenInsert()); 3970b57cec5SDimitry Andric if (EnableEarlyIf) 3980b57cec5SDimitry Andric addPass(createHexagonEarlyIfConversion()); 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric return false; 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric void HexagonPassConfig::addPreRegAlloc() { 4050b57cec5SDimitry Andric if (getOptLevel() != CodeGenOpt::None) { 4060b57cec5SDimitry Andric if (EnableCExtOpt) 4070b57cec5SDimitry Andric addPass(createHexagonConstExtenders()); 4080b57cec5SDimitry Andric if (EnableExpandCondsets) 4090b57cec5SDimitry Andric insertPass(&RegisterCoalescerID, &HexagonExpandCondsetsID); 4100b57cec5SDimitry Andric if (!DisableStoreWidening) 4110b57cec5SDimitry Andric addPass(createHexagonStoreWidening()); 4120b57cec5SDimitry Andric if (!DisableHardwareLoops) 4130b57cec5SDimitry Andric addPass(createHexagonHardwareLoops()); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric if (TM->getOptLevel() >= CodeGenOpt::Default) 4160b57cec5SDimitry Andric addPass(&MachinePipelinerID); 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric void HexagonPassConfig::addPostRegAlloc() { 4200b57cec5SDimitry Andric if (getOptLevel() != CodeGenOpt::None) { 4210b57cec5SDimitry Andric if (EnableRDFOpt) 4220b57cec5SDimitry Andric addPass(createHexagonRDFOpt()); 4230b57cec5SDimitry Andric if (!DisableHexagonCFGOpt) 4240b57cec5SDimitry Andric addPass(createHexagonCFGOptimizer()); 4250b57cec5SDimitry Andric if (!DisableAModeOpt) 4260b57cec5SDimitry Andric addPass(createHexagonOptAddrMode()); 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric void HexagonPassConfig::addPreSched2() { 4310b57cec5SDimitry Andric addPass(createHexagonCopyToCombine()); 4320b57cec5SDimitry Andric if (getOptLevel() != CodeGenOpt::None) 4330b57cec5SDimitry Andric addPass(&IfConverterID); 4340b57cec5SDimitry Andric addPass(createHexagonSplitConst32AndConst64()); 4350b57cec5SDimitry Andric } 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric void HexagonPassConfig::addPreEmitPass() { 4380b57cec5SDimitry Andric bool NoOpt = (getOptLevel() == CodeGenOpt::None); 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric if (!NoOpt) 4410b57cec5SDimitry Andric addPass(createHexagonNewValueJump()); 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric addPass(createHexagonBranchRelaxation()); 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric if (!NoOpt) { 4460b57cec5SDimitry Andric if (!DisableHardwareLoops) 4470b57cec5SDimitry Andric addPass(createHexagonFixupHwLoops()); 4480b57cec5SDimitry Andric // Generate MUX from pairs of conditional transfers. 4490b57cec5SDimitry Andric if (EnableGenMux) 4500b57cec5SDimitry Andric addPass(createHexagonGenMux()); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric // Packetization is mandatory: it handles gather/scatter at all opt levels. 454349cc55cSDimitry Andric addPass(createHexagonPacketizer(NoOpt)); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric if (EnableVectorPrint) 457349cc55cSDimitry Andric addPass(createHexagonVectorPrint()); 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric // Add CFI instructions if necessary. 460349cc55cSDimitry Andric addPass(createHexagonCallFrameInformation()); 4610b57cec5SDimitry Andric } 462