//
//===----------------------------------------------------------------------===//
//
+// Implements the info about Hexagon target spec.
//
//===----------------------------------------------------------------------===//
-#include "HexagonMCAsmInfo.h"
#include "HexagonTargetMachine.h"
#include "Hexagon.h"
#include "HexagonISelLowering.h"
-#include "llvm/Module.h"
+#include "HexagonMachineScheduler.h"
+#include "HexagonTargetObjectFile.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/TargetRegistry.h"
-#include <iostream>
-#define GET_REGINFO_MC_DESC
-#define GET_REGINFO_TARGET_DESC
-#include "HexagonGenRegisterInfo.inc"
+using namespace llvm;
-extern "C" void LLVMInitializeHexagonTargetMC() {}
+static cl:: opt<bool> DisableHardwareLoops("disable-hexagon-hwloops",
+ cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target"));
-using namespace llvm;
+static cl::opt<bool> DisableHexagonMISched("disable-hexagon-misched",
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Disable Hexagon MI Scheduling"));
+
+static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt",
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Disable Hexagon CFG Optimization"));
-static cl::
-opt<bool> DisableHardwareLoops(
- "disable-hexagon-hwloops", cl::Hidden,
- cl::desc("Disable Hardware Loops for Hexagon target"));
/// HexagonTargetMachineModule - Note that this is used on hosts that
/// cannot link in a library unless there are references into the
extern "C" void LLVMInitializeHexagonTarget() {
// Register the target.
RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget);
+}
- // Register the target asm info.
- RegisterMCAsmInfo<HexagonMCAsmInfo> A(TheHexagonTarget);
+static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) {
+ return new VLIWMachineScheduler(C, new ConvergingVLIWScheduler());
}
+static MachineSchedRegistry
+SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler",
+ createVLIWMachineSched);
/// HexagonTargetMachine ctor - Create an ILP32 architecture model.
///
///
HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS,
- TargetOptions Options,
+ const TargetOptions &Options,
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-a0:0") ,
- Subtarget(TT, CPU, FS), TLInfo(*this), InstrInfo(Subtarget),
+ DL("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);
+ setMCUseCFI(false);
+ initAsmInfo();
}
// 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()));
+ if (getOptLevel() != CodeGenOpt::None) {
+ PM.add(createConstantPropagationPass());
+ PM.add(createLoopSimplifyPass());
+ PM.add(createDeadCodeEliminationPass());
+ PM.add(createConstantPropagationPass());
+ PM.add(createLoopUnrollPass());
+ PM.add(createLoopStrengthReducePass());
+ }
return true;
}
-bool HexagonTargetMachine::addInstSelector(PassManagerBase &PM) {
- PM.add(createHexagonRemoveExtendOps(*this));
- PM.add(createHexagonISelDag(*this));
- return false;
+namespace {
+/// Hexagon Code Generator Pass Configuration Options.
+class HexagonPassConfig : public TargetPassConfig {
+public:
+ HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM)
+ : TargetPassConfig(TM, PM) {
+ // FIXME: Rather than calling enablePass(&MachineSchedulerID) below, define
+ // HexagonSubtarget::enableMachineScheduler() { return true; }.
+ // That will bypass the SelectionDAG VLIW scheduler, which is probably just
+ // hurting compile time and will be removed eventually anyway.
+ if (DisableHexagonMISched)
+ disablePass(&MachineSchedulerID);
+ else
+ enablePass(&MachineSchedulerID);
+ }
+
+ HexagonTargetMachine &getHexagonTargetMachine() const {
+ return getTM<HexagonTargetMachine>();
+ }
+
+ virtual ScheduleDAGInstrs *
+ createMachineScheduler(MachineSchedContext *C) const {
+ return createVLIWMachineSched(C);
+ }
+
+ virtual bool addInstSelector();
+ virtual bool addPreRegAlloc();
+ virtual bool addPostRegAlloc();
+ virtual bool addPreSched2();
+ virtual bool addPreEmitPass();
+};
+} // namespace
+
+TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
+ return new HexagonPassConfig(this, PM);
}
+bool HexagonPassConfig::addInstSelector() {
+ HexagonTargetMachine &TM = getHexagonTargetMachine();
+ bool NoOpt = (getOptLevel() == CodeGenOpt::None);
+
+ if (!NoOpt)
+ addPass(createHexagonRemoveExtendArgs(TM));
-bool HexagonTargetMachine::addPreRegAlloc(PassManagerBase &PM) {
- if (!DisableHardwareLoops) {
- PM.add(createHexagonHardwareLoops());
+ addPass(createHexagonISelDag(TM, getOptLevel()));
+
+ if (!NoOpt) {
+ addPass(createHexagonPeephole());
+ printAndVerify("After hexagon peephole pass");
}
return false;
}
-bool HexagonTargetMachine::addPostRegAlloc(PassManagerBase &PM) {
- PM.add(createHexagonCFGOptimizer(*this));
- return true;
+bool HexagonPassConfig::addPreRegAlloc() {
+ if (getOptLevel() != CodeGenOpt::None)
+ if (!DisableHardwareLoops)
+ addPass(createHexagonHardwareLoops());
+ return false;
}
+bool HexagonPassConfig::addPostRegAlloc() {
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ if (getOptLevel() != CodeGenOpt::None)
+ if (!DisableHexagonCFGOpt)
+ addPass(createHexagonCFGOptimizer(TM));
+ return false;
+}
-bool HexagonTargetMachine::addPreSched2(PassManagerBase &PM) {
- PM.add(createIfConverterPass());
+bool HexagonPassConfig::addPreSched2() {
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ const HexagonTargetObjectFile &TLOF =
+ (const HexagonTargetObjectFile &)getTargetLowering()->getObjFileLowering();
+
+ addPass(createHexagonCopyToCombine());
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(&IfConverterID);
+ if (!TLOF.IsSmallDataEnabled()) {
+ addPass(createHexagonSplitConst32AndConst64(TM));
+ printAndVerify("After hexagon split const32/64 pass");
+ }
return true;
}
-bool HexagonTargetMachine::addPreEmitPass(PassManagerBase &PM) {
+bool HexagonPassConfig::addPreEmitPass() {
+ const HexagonTargetMachine &TM = getHexagonTargetMachine();
+ bool NoOpt = (getOptLevel() == CodeGenOpt::None);
- if (!DisableHardwareLoops) {
- PM.add(createHexagonFixupHwLoops());
- }
+ if (!NoOpt)
+ addPass(createHexagonNewValueJump());
// Expand Spill code for predicate registers.
- PM.add(createHexagonExpandPredSpillCode(*this));
+ addPass(createHexagonExpandPredSpillCode(TM));
// Split up TFRcondsets into conditional transfers.
- PM.add(createHexagonSplitTFRCondSets(*this));
+ addPass(createHexagonSplitTFRCondSets(TM));
+
+ // Create Packets.
+ if (!NoOpt) {
+ if (!DisableHardwareLoops)
+ addPass(createHexagonFixupHwLoops());
+ addPass(createHexagonPacketizer());
+ }
return false;
}