LLVM API Documentation
00001 //===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Implements the info about Hexagon target spec. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "HexagonTargetMachine.h" 00015 #include "Hexagon.h" 00016 #include "HexagonISelLowering.h" 00017 #include "HexagonMachineScheduler.h" 00018 #include "HexagonTargetObjectFile.h" 00019 #include "llvm/CodeGen/Passes.h" 00020 #include "llvm/IR/Module.h" 00021 #include "llvm/PassManager.h" 00022 #include "llvm/Support/CommandLine.h" 00023 #include "llvm/Support/TargetRegistry.h" 00024 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 00025 #include "llvm/Transforms/Scalar.h" 00026 00027 using namespace llvm; 00028 00029 static cl:: opt<bool> DisableHardwareLoops("disable-hexagon-hwloops", 00030 cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target")); 00031 00032 static cl::opt<bool> DisableHexagonMISched("disable-hexagon-misched", 00033 cl::Hidden, cl::ZeroOrMore, cl::init(false), 00034 cl::desc("Disable Hexagon MI Scheduling")); 00035 00036 static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt", 00037 cl::Hidden, cl::ZeroOrMore, cl::init(false), 00038 cl::desc("Disable Hexagon CFG Optimization")); 00039 00040 00041 /// HexagonTargetMachineModule - Note that this is used on hosts that 00042 /// cannot link in a library unless there are references into the 00043 /// library. In particular, it seems that it is not possible to get 00044 /// things to work on Win32 without this. Though it is unused, do not 00045 /// remove it. 00046 extern "C" int HexagonTargetMachineModule; 00047 int HexagonTargetMachineModule = 0; 00048 00049 extern "C" void LLVMInitializeHexagonTarget() { 00050 // Register the target. 00051 RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget); 00052 } 00053 00054 static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 00055 return new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>()); 00056 } 00057 00058 static MachineSchedRegistry 00059 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 00060 createVLIWMachineSched); 00061 00062 /// HexagonTargetMachine ctor - Create an ILP32 architecture model. 00063 /// 00064 00065 /// Hexagon_TODO: Do I need an aggregate alignment? 00066 /// 00067 HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT, 00068 StringRef CPU, StringRef FS, 00069 const TargetOptions &Options, 00070 Reloc::Model RM, CodeModel::Model CM, 00071 CodeGenOpt::Level OL) 00072 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 00073 Subtarget(TT, CPU, FS, *this) { 00074 initAsmInfo(); 00075 } 00076 00077 namespace { 00078 /// Hexagon Code Generator Pass Configuration Options. 00079 class HexagonPassConfig : public TargetPassConfig { 00080 public: 00081 HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM) 00082 : TargetPassConfig(TM, PM) { 00083 // FIXME: Rather than calling enablePass(&MachineSchedulerID) below, define 00084 // HexagonSubtarget::enableMachineScheduler() { return true; }. 00085 // That will bypass the SelectionDAG VLIW scheduler, which is probably just 00086 // hurting compile time and will be removed eventually anyway. 00087 if (DisableHexagonMISched) 00088 disablePass(&MachineSchedulerID); 00089 else 00090 enablePass(&MachineSchedulerID); 00091 } 00092 00093 HexagonTargetMachine &getHexagonTargetMachine() const { 00094 return getTM<HexagonTargetMachine>(); 00095 } 00096 00097 ScheduleDAGInstrs * 00098 createMachineScheduler(MachineSchedContext *C) const override { 00099 return createVLIWMachineSched(C); 00100 } 00101 00102 bool addInstSelector() override; 00103 bool addPreRegAlloc() override; 00104 bool addPostRegAlloc() override; 00105 bool addPreSched2() override; 00106 bool addPreEmitPass() override; 00107 }; 00108 } // namespace 00109 00110 TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 00111 return new HexagonPassConfig(this, PM); 00112 } 00113 00114 bool HexagonPassConfig::addInstSelector() { 00115 HexagonTargetMachine &TM = getHexagonTargetMachine(); 00116 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 00117 00118 if (!NoOpt) 00119 addPass(createHexagonRemoveExtendArgs(TM)); 00120 00121 addPass(createHexagonISelDag(TM, getOptLevel())); 00122 00123 if (!NoOpt) { 00124 addPass(createHexagonPeephole()); 00125 printAndVerify("After hexagon peephole pass"); 00126 } 00127 00128 return false; 00129 } 00130 00131 bool HexagonPassConfig::addPreRegAlloc() { 00132 if (getOptLevel() != CodeGenOpt::None) 00133 if (!DisableHardwareLoops) 00134 addPass(createHexagonHardwareLoops()); 00135 return false; 00136 } 00137 00138 bool HexagonPassConfig::addPostRegAlloc() { 00139 const HexagonTargetMachine &TM = getHexagonTargetMachine(); 00140 if (getOptLevel() != CodeGenOpt::None) 00141 if (!DisableHexagonCFGOpt) 00142 addPass(createHexagonCFGOptimizer(TM)); 00143 return false; 00144 } 00145 00146 bool HexagonPassConfig::addPreSched2() { 00147 const HexagonTargetMachine &TM = getHexagonTargetMachine(); 00148 00149 addPass(createHexagonCopyToCombine()); 00150 if (getOptLevel() != CodeGenOpt::None) 00151 addPass(&IfConverterID); 00152 addPass(createHexagonSplitConst32AndConst64(TM)); 00153 printAndVerify("After hexagon split const32/64 pass"); 00154 return true; 00155 } 00156 00157 bool HexagonPassConfig::addPreEmitPass() { 00158 const HexagonTargetMachine &TM = getHexagonTargetMachine(); 00159 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 00160 00161 if (!NoOpt) 00162 addPass(createHexagonNewValueJump()); 00163 00164 // Expand Spill code for predicate registers. 00165 addPass(createHexagonExpandPredSpillCode(TM)); 00166 00167 // Split up TFRcondsets into conditional transfers. 00168 addPass(createHexagonSplitTFRCondSets(TM)); 00169 00170 // Create Packets. 00171 if (!NoOpt) { 00172 if (!DisableHardwareLoops) 00173 addPass(createHexagonFixupHwLoops()); 00174 addPass(createHexagonPacketizer()); 00175 } 00176 00177 return false; 00178 }