X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FHexagon%2FHexagonTargetMachine.cpp;h=ad5e8067db54e615b566879eb1aa3889c8b07eea;hb=7fcebdc82ba1ad2265ad8869242ef988ec1b0c9b;hp=133afa0973288c9770250ac7c624df17165f4e98;hpb=b33857040f63a9fdfb0c2a2ca2af67ec12cf9d02;p=oota-llvm.git diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp index 133afa09732..ad5e8067db5 100644 --- a/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -14,24 +14,59 @@ #include "HexagonTargetMachine.h" #include "Hexagon.h" #include "HexagonISelLowering.h" -#include "llvm/Module.h" +#include "HexagonMachineScheduler.h" +#include "HexagonTargetObjectFile.h" +#include "HexagonTargetTransformInfo.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/PassManager.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" -#include "llvm/Transforms/Scalar.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Transforms/Scalar.h" using namespace llvm; -static cl:: -opt DisableHardwareLoops( - "disable-hexagon-hwloops", cl::Hidden, - cl::desc("Disable Hardware Loops for Hexagon target")); -static cl:: -opt DisableCExtOpt( - "disable-hexagon-cextopt", cl::Hidden, - cl::desc("Disable Optimization of Constant Extenders")); +static cl:: opt DisableHardwareLoops("disable-hexagon-hwloops", + cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target")); + +static cl::opt DisableHexagonCFGOpt("disable-hexagon-cfgopt", + cl::Hidden, cl::ZeroOrMore, cl::init(false), + cl::desc("Disable Hexagon CFG Optimization")); + +static cl::opt DisableStoreWidening("disable-store-widen", + cl::Hidden, cl::init(false), cl::desc("Disable store widening")); + +static cl::opt EnableExpandCondsets("hexagon-expand-condsets", + cl::init(true), cl::Hidden, cl::ZeroOrMore, + cl::desc("Early expansion of MUX")); + +static cl::opt EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden, + cl::ZeroOrMore, cl::desc("Enable early if-conversion")); + +static cl::opt EnableGenInsert("hexagon-insert", cl::init(true), + cl::Hidden, cl::desc("Generate \"insert\" instructions")); + +static cl::opt EnableCommGEP("hexagon-commgep", cl::init(true), + cl::Hidden, cl::ZeroOrMore, cl::desc("Enable commoning of GEP instructions")); + +static cl::opt EnableGenExtract("hexagon-extract", cl::init(true), + cl::Hidden, cl::desc("Generate \"extract\" instructions")); + +static cl::opt EnableGenMux("hexagon-mux", cl::init(true), cl::Hidden, + cl::desc("Enable converting conditional transfers into MUX instructions")); + +static cl::opt EnableGenPred("hexagon-gen-pred", cl::init(true), + cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " + "predicate instructions")); + +static cl::opt DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden, + cl::desc("Disable splitting double registers")); + +static cl::opt EnableBitSimplify("hexagon-bit", cl::init(true), + cl::Hidden, cl::desc("Bit simplification")); + +static cl::opt EnableLoopResched("hexagon-loop-resched", cl::init(true), + cl::Hidden, cl::desc("Loop rescheduling")); /// HexagonTargetMachineModule - Note that this is used on hosts that /// cannot link in a library unless there are references into the @@ -46,58 +81,122 @@ extern "C" void LLVMInitializeHexagonTarget() { RegisterTargetMachine X(TheHexagonTarget); } +static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { + return new VLIWMachineScheduler(C, make_unique()); +} + +static MachineSchedRegistry +SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", + createVLIWMachineSched); + +namespace llvm { + FunctionPass *createHexagonBitSimplify(); + FunctionPass *createHexagonCallFrameInformation(); + FunctionPass *createHexagonCFGOptimizer(); + FunctionPass *createHexagonCommonGEP(); + FunctionPass *createHexagonCopyToCombine(); + FunctionPass *createHexagonEarlyIfConversion(); + FunctionPass *createHexagonExpandCondsets(); + FunctionPass *createHexagonExpandPredSpillCode(); + FunctionPass *createHexagonFixupHwLoops(); + FunctionPass *createHexagonGenExtract(); + FunctionPass *createHexagonGenInsert(); + FunctionPass *createHexagonGenMux(); + FunctionPass *createHexagonGenPredicate(); + FunctionPass *createHexagonHardwareLoops(); + FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, + CodeGenOpt::Level OptLevel); + FunctionPass *createHexagonLoopRescheduling(); + FunctionPass *createHexagonNewValueJump(); + FunctionPass *createHexagonOptimizeSZextends(); + FunctionPass *createHexagonPacketizer(); + FunctionPass *createHexagonPeephole(); + FunctionPass *createHexagonSplitConst32AndConst64(); + FunctionPass *createHexagonSplitDoubleRegs(); + FunctionPass *createHexagonStoreWidening(); +} // end namespace llvm; /// HexagonTargetMachine ctor - Create an ILP32 architecture model. /// /// Hexagon_TODO: Do I need an aggregate alignment? /// -HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT, +HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, - Reloc::Model RM, - CodeModel::Model CM, + Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), - DataLayout("e-p:32:32:32-" - "i64:64:64-i32:32:32-i16:16:16-i1:32:32-" - "f64:64:64-f32:32:32-a0:0-n32") , - Subtarget(TT, CPU, FS), InstrInfo(Subtarget), TLInfo(*this), - TSInfo(*this), - FrameLowering(Subtarget), - InstrItins(&Subtarget.getInstrItineraryData()) { - setMCUseCFI(false); + : LLVMTargetMachine(T, "e-m:e-p:32:32-i1:32-i64:64-a:0-n32", TT, CPU, FS, + Options, RM, CM, OL), + TLOF(make_unique()) { + initAsmInfo(); +} + +const HexagonSubtarget * +HexagonTargetMachine::getSubtargetImpl(const Function &F) const { + AttributeSet FnAttrs = F.getAttributes(); + Attribute CPUAttr = + FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu"); + Attribute FSAttr = + FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features"); + + std::string CPU = !CPUAttr.hasAttribute(Attribute::None) + ? CPUAttr.getValueAsString().str() + : TargetCPU; + std::string FS = !FSAttr.hasAttribute(Attribute::None) + ? FSAttr.getValueAsString().str() + : TargetFS; + + auto &I = SubtargetMap[CPU + FS]; + if (!I) { + // This needs to be done before we create a new subtarget since any + // creation will depend on the TM and the code generation flags on the + // function that reside in TargetOptions. + resetTargetOptions(F); + I = llvm::make_unique(TargetTriple, CPU, FS, *this); + } + return I.get(); } -// addPassesForOptimizations - Allow the backend (target) to add Target -// Independent Optimization passes to the Pass Manager. -bool HexagonTargetMachine::addPassesForOptimizations(PassManagerBase &PM) { - - PM.add(createConstantPropagationPass()); - PM.add(createLoopSimplifyPass()); - PM.add(createDeadCodeEliminationPass()); - PM.add(createConstantPropagationPass()); - PM.add(createLoopUnrollPass()); - PM.add(createLoopStrengthReducePass(getTargetLowering())); - return true; +TargetIRAnalysis HexagonTargetMachine::getTargetIRAnalysis() { + return TargetIRAnalysis([this](const Function &F) { + return TargetTransformInfo(HexagonTTIImpl(this, F)); + }); } + +HexagonTargetMachine::~HexagonTargetMachine() {} + namespace { /// Hexagon Code Generator Pass Configuration Options. class HexagonPassConfig : public TargetPassConfig { public: HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM) - : TargetPassConfig(TM, PM) {} + : TargetPassConfig(TM, PM) { + bool NoOpt = (TM->getOptLevel() == CodeGenOpt::None); + if (!NoOpt) { + if (EnableExpandCondsets) { + Pass *Exp = createHexagonExpandCondsets(); + insertPass(&RegisterCoalescerID, IdentifyingPassPtr(Exp)); + } + } + } HexagonTargetMachine &getHexagonTargetMachine() const { return getTM(); } - virtual bool addInstSelector(); - virtual bool addPreRegAlloc(); - virtual bool addPostRegAlloc(); - virtual bool addPreSched2(); - virtual bool addPreEmitPass(); + ScheduleDAGInstrs * + createMachineScheduler(MachineSchedContext *C) const override { + return createVLIWMachineSched(C); + } + + void addIRPasses() override; + bool addInstSelector() override; + void addPreRegAlloc() override; + void addPostRegAlloc() override; + void addPreSched2() override; + void addPreEmitPass() override; }; } // namespace @@ -105,51 +204,95 @@ TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { return new HexagonPassConfig(this, PM); } -bool HexagonPassConfig::addInstSelector() { - PM->add(createHexagonRemoveExtendOps(getHexagonTargetMachine())); - PM->add(createHexagonISelDag(getHexagonTargetMachine())); - PM->add(createHexagonPeephole()); - return false; +void HexagonPassConfig::addIRPasses() { + TargetPassConfig::addIRPasses(); + bool NoOpt = (getOptLevel() == CodeGenOpt::None); + + addPass(createAtomicExpandPass(TM)); + if (!NoOpt) { + if (EnableCommGEP) + addPass(createHexagonCommonGEP()); + // Replace certain combinations of shifts and ands with extracts. + if (EnableGenExtract) + addPass(createHexagonGenExtract()); + } } +bool HexagonPassConfig::addInstSelector() { + HexagonTargetMachine &TM = getHexagonTargetMachine(); + bool NoOpt = (getOptLevel() == CodeGenOpt::None); -bool HexagonPassConfig::addPreRegAlloc() { - if (!DisableCExtOpt) { - PM->add(createHexagonOptimizeConstExt(getHexagonTargetMachine())); - } - if (!DisableHardwareLoops) { - PM->add(createHexagonHardwareLoops()); + if (!NoOpt) + addPass(createHexagonOptimizeSZextends()); + + addPass(createHexagonISelDag(TM, getOptLevel())); + + if (!NoOpt) { + // Create logical operations on predicate registers. + if (EnableGenPred) + addPass(createHexagonGenPredicate(), false); + // Rotate loops to expose bit-simplification opportunities. + if (EnableLoopResched) + addPass(createHexagonLoopRescheduling(), false); + // Split double registers. + if (!DisableHSDR) + addPass(createHexagonSplitDoubleRegs()); + // Bit simplification. + if (EnableBitSimplify) + addPass(createHexagonBitSimplify(), false); + addPass(createHexagonPeephole()); + printAndVerify("After hexagon peephole pass"); + if (EnableGenInsert) + addPass(createHexagonGenInsert(), false); + if (EnableEarlyIf) + addPass(createHexagonEarlyIfConversion(), false); } + return false; } -bool HexagonPassConfig::addPostRegAlloc() { - PM->add(createHexagonCFGOptimizer(getHexagonTargetMachine())); - return true; +void HexagonPassConfig::addPreRegAlloc() { + if (getOptLevel() != CodeGenOpt::None) { + if (!DisableStoreWidening) + addPass(createHexagonStoreWidening(), false); + if (!DisableHardwareLoops) + addPass(createHexagonHardwareLoops(), false); + } } +void HexagonPassConfig::addPostRegAlloc() { + if (getOptLevel() != CodeGenOpt::None) + if (!DisableHexagonCFGOpt) + addPass(createHexagonCFGOptimizer(), false); +} -bool HexagonPassConfig::addPreSched2() { - addPass(IfConverterID); - return true; +void HexagonPassConfig::addPreSched2() { + addPass(createHexagonCopyToCombine(), false); + if (getOptLevel() != CodeGenOpt::None) + addPass(&IfConverterID, false); + addPass(createHexagonSplitConst32AndConst64()); } -bool HexagonPassConfig::addPreEmitPass() { +void HexagonPassConfig::addPreEmitPass() { + bool NoOpt = (getOptLevel() == CodeGenOpt::None); - if (!DisableHardwareLoops) { - PM->add(createHexagonFixupHwLoops()); - } - - PM->add(createHexagonNewValueJump()); + if (!NoOpt) + addPass(createHexagonNewValueJump(), false); // Expand Spill code for predicate registers. - PM->add(createHexagonExpandPredSpillCode(getHexagonTargetMachine())); - - // Split up TFRcondsets into conditional transfers. - PM->add(createHexagonSplitTFRCondSets(getHexagonTargetMachine())); + addPass(createHexagonExpandPredSpillCode(), false); // Create Packets. - PM->add(createHexagonPacketizer()); + if (!NoOpt) { + if (!DisableHardwareLoops) + addPass(createHexagonFixupHwLoops(), false); + // Generate MUX from pairs of conditional transfers. + if (EnableGenMux) + addPass(createHexagonGenMux(), false); - return false; + addPass(createHexagonPacketizer(), false); + } + + // Add CFI instructions if necessary. + addPass(createHexagonCallFrameInformation(), false); }