1 //===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implements the info about Hexagon target spec. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "HexagonTargetMachine.h" 15 #include "Hexagon.h" 16 #include "HexagonISelLowering.h" 17 #include "HexagonMachineScheduler.h" 18 #include "HexagonTargetObjectFile.h" 19 #include "llvm/CodeGen/Passes.h" 20 #include "llvm/IR/LegacyPassManager.h" 21 #include "llvm/IR/Module.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/TargetRegistry.h" 24 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 25 #include "llvm/Transforms/Scalar.h" 26 27 using namespace llvm; 28 29 static cl:: opt<bool> DisableHardwareLoops("disable-hexagon-hwloops", 30 cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target")); 31 32 static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt", 33 cl::Hidden, cl::ZeroOrMore, cl::init(false), 34 cl::desc("Disable Hexagon CFG Optimization")); 35 36 static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets", 37 cl::init(true), cl::Hidden, cl::ZeroOrMore, 38 cl::desc("Early expansion of MUX")); 39 40 static cl::opt<bool> EnableGenInsert("hexagon-insert", cl::init(true), 41 cl::Hidden, cl::desc("Generate \"insert\" instructions")); 42 43 static cl::opt<bool> EnableCommGEP("hexagon-commgep", cl::init(true), 44 cl::Hidden, cl::ZeroOrMore, cl::desc("Enable commoning of GEP instructions")); 45 46 47 /// HexagonTargetMachineModule - Note that this is used on hosts that 48 /// cannot link in a library unless there are references into the 49 /// library. In particular, it seems that it is not possible to get 50 /// things to work on Win32 without this. Though it is unused, do not 51 /// remove it. 52 extern "C" int HexagonTargetMachineModule; 53 int HexagonTargetMachineModule = 0; 54 55 extern "C" void LLVMInitializeHexagonTarget() { 56 // Register the target. 57 RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget); 58 } 59 60 static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 61 return new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>()); 62 } 63 64 static MachineSchedRegistry 65 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 66 createVLIWMachineSched); 67 68 namespace llvm { 69 FunctionPass *createHexagonCommonGEP(); 70 FunctionPass *createHexagonExpandCondsets(); 71 FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, 72 CodeGenOpt::Level OptLevel); 73 FunctionPass *createHexagonDelaySlotFillerPass(const TargetMachine &TM); 74 FunctionPass *createHexagonRemoveExtendArgs(const HexagonTargetMachine &TM); 75 FunctionPass *createHexagonCFGOptimizer(); 76 77 FunctionPass *createHexagonSplitConst32AndConst64(); 78 FunctionPass *createHexagonExpandPredSpillCode(); 79 FunctionPass *createHexagonGenInsert(); 80 FunctionPass *createHexagonHardwareLoops(); 81 FunctionPass *createHexagonPeephole(); 82 FunctionPass *createHexagonFixupHwLoops(); 83 FunctionPass *createHexagonNewValueJump(); 84 FunctionPass *createHexagonCopyToCombine(); 85 FunctionPass *createHexagonPacketizer(); 86 FunctionPass *createHexagonNewValueJump(); 87 } // end namespace llvm; 88 89 /// HexagonTargetMachine ctor - Create an ILP32 architecture model. 90 /// 91 92 /// Hexagon_TODO: Do I need an aggregate alignment? 93 /// 94 HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, 95 StringRef CPU, StringRef FS, 96 const TargetOptions &Options, 97 Reloc::Model RM, CodeModel::Model CM, 98 CodeGenOpt::Level OL) 99 : LLVMTargetMachine(T, "e-m:e-p:32:32-i1:32-i64:64-a:0-n32", TT, CPU, FS, 100 Options, RM, CM, OL), 101 TLOF(make_unique<HexagonTargetObjectFile>()), 102 Subtarget(TT, CPU, FS, *this) { 103 initAsmInfo(); 104 } 105 106 HexagonTargetMachine::~HexagonTargetMachine() {} 107 108 namespace { 109 /// Hexagon Code Generator Pass Configuration Options. 110 class HexagonPassConfig : public TargetPassConfig { 111 public: 112 HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM) 113 : TargetPassConfig(TM, PM) { 114 bool NoOpt = (TM->getOptLevel() == CodeGenOpt::None); 115 if (!NoOpt) { 116 if (EnableExpandCondsets) { 117 Pass *Exp = createHexagonExpandCondsets(); 118 insertPass(&RegisterCoalescerID, IdentifyingPassPtr(Exp)); 119 } 120 } 121 } 122 123 HexagonTargetMachine &getHexagonTargetMachine() const { 124 return getTM<HexagonTargetMachine>(); 125 } 126 127 ScheduleDAGInstrs * 128 createMachineScheduler(MachineSchedContext *C) const override { 129 return createVLIWMachineSched(C); 130 } 131 132 void addIRPasses() override; 133 bool addInstSelector() override; 134 void addPreRegAlloc() override; 135 void addPostRegAlloc() override; 136 void addPreSched2() override; 137 void addPreEmitPass() override; 138 }; 139 } // namespace 140 141 TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 142 return new HexagonPassConfig(this, PM); 143 } 144 145 void HexagonPassConfig::addIRPasses() { 146 TargetPassConfig::addIRPasses(); 147 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 148 149 addPass(createAtomicExpandPass(TM)); 150 if (!NoOpt && EnableCommGEP) 151 addPass(createHexagonCommonGEP()); 152 } 153 154 bool HexagonPassConfig::addInstSelector() { 155 HexagonTargetMachine &TM = getHexagonTargetMachine(); 156 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 157 158 if (!NoOpt) 159 addPass(createHexagonRemoveExtendArgs(TM)); 160 161 addPass(createHexagonISelDag(TM, getOptLevel())); 162 163 if (!NoOpt) { 164 addPass(createHexagonPeephole()); 165 printAndVerify("After hexagon peephole pass"); 166 if (EnableGenInsert) 167 addPass(createHexagonGenInsert(), false); 168 } 169 170 return false; 171 } 172 173 void HexagonPassConfig::addPreRegAlloc() { 174 if (getOptLevel() != CodeGenOpt::None) 175 if (!DisableHardwareLoops) 176 addPass(createHexagonHardwareLoops(), false); 177 } 178 179 void HexagonPassConfig::addPostRegAlloc() { 180 if (getOptLevel() != CodeGenOpt::None) 181 if (!DisableHexagonCFGOpt) 182 addPass(createHexagonCFGOptimizer(), false); 183 } 184 185 void HexagonPassConfig::addPreSched2() { 186 addPass(createHexagonCopyToCombine(), false); 187 if (getOptLevel() != CodeGenOpt::None) 188 addPass(&IfConverterID, false); 189 addPass(createHexagonSplitConst32AndConst64()); 190 } 191 192 void HexagonPassConfig::addPreEmitPass() { 193 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 194 195 if (!NoOpt) 196 addPass(createHexagonNewValueJump(), false); 197 198 // Expand Spill code for predicate registers. 199 addPass(createHexagonExpandPredSpillCode(), false); 200 201 // Create Packets. 202 if (!NoOpt) { 203 if (!DisableHardwareLoops) 204 addPass(createHexagonFixupHwLoops(), false); 205 addPass(createHexagonPacketizer(), false); 206 } 207 } 208