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 "HexagonTargetTransformInfo.h" 20 #include "llvm/CodeGen/Passes.h" 21 #include "llvm/CodeGen/TargetPassConfig.h" 22 #include "llvm/IR/LegacyPassManager.h" 23 #include "llvm/IR/Module.h" 24 #include "llvm/Support/CommandLine.h" 25 #include "llvm/Support/TargetRegistry.h" 26 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 27 #include "llvm/Transforms/Scalar.h" 28 29 using namespace llvm; 30 31 static cl::opt<bool> EnableCExtOpt("hexagon-cext", cl::Hidden, cl::ZeroOrMore, 32 cl::init(true), cl::desc("Enable Hexagon constant-extender optimization")); 33 34 static cl::opt<bool> EnableRDFOpt("rdf-opt", cl::Hidden, cl::ZeroOrMore, 35 cl::init(true), cl::desc("Enable RDF-based optimizations")); 36 37 static cl::opt<bool> DisableHardwareLoops("disable-hexagon-hwloops", 38 cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target")); 39 40 static cl::opt<bool> DisableAModeOpt("disable-hexagon-amodeopt", 41 cl::Hidden, cl::ZeroOrMore, cl::init(false), 42 cl::desc("Disable Hexagon Addressing Mode Optimization")); 43 44 static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt", 45 cl::Hidden, cl::ZeroOrMore, cl::init(false), 46 cl::desc("Disable Hexagon CFG Optimization")); 47 48 static cl::opt<bool> DisableHCP("disable-hcp", cl::init(false), cl::Hidden, 49 cl::ZeroOrMore, cl::desc("Disable Hexagon constant propagation")); 50 51 static cl::opt<bool> DisableStoreWidening("disable-store-widen", 52 cl::Hidden, cl::init(false), cl::desc("Disable store widening")); 53 54 static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets", 55 cl::init(true), cl::Hidden, cl::ZeroOrMore, 56 cl::desc("Early expansion of MUX")); 57 58 static cl::opt<bool> EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden, 59 cl::ZeroOrMore, cl::desc("Enable early if-conversion")); 60 61 static cl::opt<bool> EnableGenInsert("hexagon-insert", cl::init(true), 62 cl::Hidden, cl::desc("Generate \"insert\" instructions")); 63 64 static cl::opt<bool> EnableCommGEP("hexagon-commgep", cl::init(true), 65 cl::Hidden, cl::ZeroOrMore, cl::desc("Enable commoning of GEP instructions")); 66 67 static cl::opt<bool> EnableGenExtract("hexagon-extract", cl::init(true), 68 cl::Hidden, cl::desc("Generate \"extract\" instructions")); 69 70 static cl::opt<bool> EnableGenMux("hexagon-mux", cl::init(true), cl::Hidden, 71 cl::desc("Enable converting conditional transfers into MUX instructions")); 72 73 static cl::opt<bool> EnableGenPred("hexagon-gen-pred", cl::init(true), 74 cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " 75 "predicate instructions")); 76 77 static cl::opt<bool> EnableLoopPrefetch("hexagon-loop-prefetch", 78 cl::init(false), cl::Hidden, cl::ZeroOrMore, 79 cl::desc("Enable loop data prefetch on Hexagon")); 80 81 static cl::opt<bool> DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden, 82 cl::desc("Disable splitting double registers")); 83 84 static cl::opt<bool> EnableBitSimplify("hexagon-bit", cl::init(true), 85 cl::Hidden, cl::desc("Bit simplification")); 86 87 static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(true), 88 cl::Hidden, cl::desc("Loop rescheduling")); 89 90 static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(false), 91 cl::Hidden, cl::desc("Disable backend optimizations")); 92 93 static cl::opt<bool> EnableVectorPrint("enable-hexagon-vector-print", 94 cl::Hidden, cl::ZeroOrMore, cl::init(false), 95 cl::desc("Enable Hexagon Vector print instr pass")); 96 97 static cl::opt<bool> EnableTrapUnreachable("hexagon-trap-unreachable", 98 cl::Hidden, cl::ZeroOrMore, cl::init(false), 99 cl::desc("Enable generating trap for unreachable")); 100 101 /// HexagonTargetMachineModule - Note that this is used on hosts that 102 /// cannot link in a library unless there are references into the 103 /// library. In particular, it seems that it is not possible to get 104 /// things to work on Win32 without this. Though it is unused, do not 105 /// remove it. 106 extern "C" int HexagonTargetMachineModule; 107 int HexagonTargetMachineModule = 0; 108 109 static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 110 ScheduleDAGMILive *DAG = 111 new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>()); 112 DAG->addMutation(make_unique<HexagonSubtarget::UsrOverflowMutation>()); 113 DAG->addMutation(make_unique<HexagonSubtarget::HVXMemLatencyMutation>()); 114 DAG->addMutation(make_unique<HexagonSubtarget::CallMutation>()); 115 DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI)); 116 return DAG; 117 } 118 119 static MachineSchedRegistry 120 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 121 createVLIWMachineSched); 122 123 namespace llvm { 124 extern char &HexagonExpandCondsetsID; 125 void initializeHexagonConstExtendersPass(PassRegistry&); 126 void initializeHexagonEarlyIfConversionPass(PassRegistry&); 127 void initializeHexagonExpandCondsetsPass(PassRegistry&); 128 void initializeHexagonGenMuxPass(PassRegistry&); 129 void initializeHexagonHardwareLoopsPass(PassRegistry&); 130 void initializeHexagonLoopIdiomRecognizePass(PassRegistry&); 131 void initializeHexagonVectorLoopCarriedReusePass(PassRegistry&); 132 void initializeHexagonNewValueJumpPass(PassRegistry&); 133 void initializeHexagonOptAddrModePass(PassRegistry&); 134 void initializeHexagonPacketizerPass(PassRegistry&); 135 Pass *createHexagonLoopIdiomPass(); 136 Pass *createHexagonVectorLoopCarriedReusePass(); 137 138 FunctionPass *createHexagonBitSimplify(); 139 FunctionPass *createHexagonBranchRelaxation(); 140 FunctionPass *createHexagonCallFrameInformation(); 141 FunctionPass *createHexagonCFGOptimizer(); 142 FunctionPass *createHexagonCommonGEP(); 143 FunctionPass *createHexagonConstExtenders(); 144 FunctionPass *createHexagonConstPropagationPass(); 145 FunctionPass *createHexagonCopyToCombine(); 146 FunctionPass *createHexagonEarlyIfConversion(); 147 FunctionPass *createHexagonFixupHwLoops(); 148 FunctionPass *createHexagonGenExtract(); 149 FunctionPass *createHexagonGenInsert(); 150 FunctionPass *createHexagonGenMux(); 151 FunctionPass *createHexagonGenPredicate(); 152 FunctionPass *createHexagonHardwareLoops(); 153 FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, 154 CodeGenOpt::Level OptLevel); 155 FunctionPass *createHexagonLoopRescheduling(); 156 FunctionPass *createHexagonNewValueJump(); 157 FunctionPass *createHexagonOptimizeSZextends(); 158 FunctionPass *createHexagonOptAddrMode(); 159 FunctionPass *createHexagonPacketizer(); 160 FunctionPass *createHexagonPeephole(); 161 FunctionPass *createHexagonRDFOpt(); 162 FunctionPass *createHexagonSplitConst32AndConst64(); 163 FunctionPass *createHexagonSplitDoubleRegs(); 164 FunctionPass *createHexagonStoreWidening(); 165 FunctionPass *createHexagonVectorPrint(); 166 } // end namespace llvm; 167 168 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { 169 if (!RM.hasValue()) 170 return Reloc::Static; 171 return *RM; 172 } 173 174 static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) { 175 if (CM) 176 return *CM; 177 return CodeModel::Small; 178 } 179 180 extern "C" void LLVMInitializeHexagonTarget() { 181 // Register the target. 182 RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget()); 183 184 PassRegistry &PR = *PassRegistry::getPassRegistry(); 185 initializeHexagonConstExtendersPass(PR); 186 initializeHexagonEarlyIfConversionPass(PR); 187 initializeHexagonGenMuxPass(PR); 188 initializeHexagonHardwareLoopsPass(PR); 189 initializeHexagonLoopIdiomRecognizePass(PR); 190 initializeHexagonVectorLoopCarriedReusePass(PR); 191 initializeHexagonNewValueJumpPass(PR); 192 initializeHexagonOptAddrModePass(PR); 193 initializeHexagonPacketizerPass(PR); 194 } 195 196 HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, 197 StringRef CPU, StringRef FS, 198 const TargetOptions &Options, 199 Optional<Reloc::Model> RM, 200 Optional<CodeModel::Model> CM, 201 CodeGenOpt::Level OL, bool JIT) 202 // Specify the vector alignment explicitly. For v512x1, the calculated 203 // alignment would be 512*alignment(i1), which is 512 bytes, instead of 204 // the required minimum of 64 bytes. 205 : LLVMTargetMachine( 206 T, 207 "e-m:e-p:32:32:32-a:0-n16:32-" 208 "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" 209 "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048", 210 TT, CPU, FS, Options, getEffectiveRelocModel(RM), 211 getEffectiveCodeModel(CM), (HexagonNoOpt ? CodeGenOpt::None : OL)), 212 TLOF(make_unique<HexagonTargetObjectFile>()) { 213 if (EnableTrapUnreachable) 214 this->Options.TrapUnreachable = true; 215 initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry()); 216 initAsmInfo(); 217 } 218 219 const HexagonSubtarget * 220 HexagonTargetMachine::getSubtargetImpl(const Function &F) const { 221 AttributeList FnAttrs = F.getAttributes(); 222 Attribute CPUAttr = 223 FnAttrs.getAttribute(AttributeList::FunctionIndex, "target-cpu"); 224 Attribute FSAttr = 225 FnAttrs.getAttribute(AttributeList::FunctionIndex, "target-features"); 226 227 std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 228 ? CPUAttr.getValueAsString().str() 229 : TargetCPU; 230 std::string FS = !FSAttr.hasAttribute(Attribute::None) 231 ? FSAttr.getValueAsString().str() 232 : TargetFS; 233 234 auto &I = SubtargetMap[CPU + FS]; 235 if (!I) { 236 // This needs to be done before we create a new subtarget since any 237 // creation will depend on the TM and the code generation flags on the 238 // function that reside in TargetOptions. 239 resetTargetOptions(F); 240 I = llvm::make_unique<HexagonSubtarget>(TargetTriple, CPU, FS, *this); 241 } 242 return I.get(); 243 } 244 245 void HexagonTargetMachine::adjustPassManager(PassManagerBuilder &PMB) { 246 PMB.addExtension( 247 PassManagerBuilder::EP_LateLoopOptimizations, 248 [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 249 PM.add(createHexagonLoopIdiomPass()); 250 }); 251 PMB.addExtension( 252 PassManagerBuilder::EP_LoopOptimizerEnd, 253 [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { 254 PM.add(createHexagonVectorLoopCarriedReusePass()); 255 }); 256 } 257 258 TargetIRAnalysis HexagonTargetMachine::getTargetIRAnalysis() { 259 return TargetIRAnalysis([this](const Function &F) { 260 return TargetTransformInfo(HexagonTTIImpl(this, F)); 261 }); 262 } 263 264 265 HexagonTargetMachine::~HexagonTargetMachine() {} 266 267 namespace { 268 /// Hexagon Code Generator Pass Configuration Options. 269 class HexagonPassConfig : public TargetPassConfig { 270 public: 271 HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM) 272 : TargetPassConfig(TM, PM) {} 273 274 HexagonTargetMachine &getHexagonTargetMachine() const { 275 return getTM<HexagonTargetMachine>(); 276 } 277 278 ScheduleDAGInstrs * 279 createMachineScheduler(MachineSchedContext *C) const override { 280 return createVLIWMachineSched(C); 281 } 282 283 void addIRPasses() override; 284 bool addInstSelector() override; 285 void addPreRegAlloc() override; 286 void addPostRegAlloc() override; 287 void addPreSched2() override; 288 void addPreEmitPass() override; 289 }; 290 } // namespace 291 292 TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 293 return new HexagonPassConfig(*this, PM); 294 } 295 296 void HexagonPassConfig::addIRPasses() { 297 TargetPassConfig::addIRPasses(); 298 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 299 300 addPass(createAtomicExpandPass()); 301 if (!NoOpt) { 302 if (EnableLoopPrefetch) 303 addPass(createLoopDataPrefetchPass()); 304 if (EnableCommGEP) 305 addPass(createHexagonCommonGEP()); 306 // Replace certain combinations of shifts and ands with extracts. 307 if (EnableGenExtract) 308 addPass(createHexagonGenExtract()); 309 } 310 } 311 312 bool HexagonPassConfig::addInstSelector() { 313 HexagonTargetMachine &TM = getHexagonTargetMachine(); 314 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 315 316 if (!NoOpt) 317 addPass(createHexagonOptimizeSZextends()); 318 319 addPass(createHexagonISelDag(TM, getOptLevel())); 320 321 if (!NoOpt) { 322 // Create logical operations on predicate registers. 323 if (EnableGenPred) 324 addPass(createHexagonGenPredicate()); 325 // Rotate loops to expose bit-simplification opportunities. 326 if (EnableLoopResched) 327 addPass(createHexagonLoopRescheduling()); 328 // Split double registers. 329 if (!DisableHSDR) 330 addPass(createHexagonSplitDoubleRegs()); 331 // Bit simplification. 332 if (EnableBitSimplify) 333 addPass(createHexagonBitSimplify()); 334 addPass(createHexagonPeephole()); 335 // Constant propagation. 336 if (!DisableHCP) { 337 addPass(createHexagonConstPropagationPass()); 338 addPass(&UnreachableMachineBlockElimID); 339 } 340 if (EnableGenInsert) 341 addPass(createHexagonGenInsert()); 342 if (EnableEarlyIf) 343 addPass(createHexagonEarlyIfConversion()); 344 } 345 346 return false; 347 } 348 349 void HexagonPassConfig::addPreRegAlloc() { 350 if (getOptLevel() != CodeGenOpt::None) { 351 if (EnableCExtOpt) 352 addPass(createHexagonConstExtenders()); 353 if (EnableExpandCondsets) 354 insertPass(&RegisterCoalescerID, &HexagonExpandCondsetsID); 355 if (!DisableStoreWidening) 356 addPass(createHexagonStoreWidening()); 357 if (!DisableHardwareLoops) 358 addPass(createHexagonHardwareLoops()); 359 } 360 if (TM->getOptLevel() >= CodeGenOpt::Default) 361 addPass(&MachinePipelinerID); 362 } 363 364 void HexagonPassConfig::addPostRegAlloc() { 365 if (getOptLevel() != CodeGenOpt::None) { 366 if (EnableRDFOpt) 367 addPass(createHexagonRDFOpt()); 368 if (!DisableHexagonCFGOpt) 369 addPass(createHexagonCFGOptimizer()); 370 if (!DisableAModeOpt) 371 addPass(createHexagonOptAddrMode()); 372 } 373 } 374 375 void HexagonPassConfig::addPreSched2() { 376 addPass(createHexagonCopyToCombine()); 377 if (getOptLevel() != CodeGenOpt::None) 378 addPass(&IfConverterID); 379 addPass(createHexagonSplitConst32AndConst64()); 380 } 381 382 void HexagonPassConfig::addPreEmitPass() { 383 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 384 385 if (!NoOpt) 386 addPass(createHexagonNewValueJump()); 387 388 addPass(createHexagonBranchRelaxation()); 389 390 // Create Packets. 391 if (!NoOpt) { 392 if (!DisableHardwareLoops) 393 addPass(createHexagonFixupHwLoops()); 394 // Generate MUX from pairs of conditional transfers. 395 if (EnableGenMux) 396 addPass(createHexagonGenMux()); 397 398 addPass(createHexagonPacketizer(), false); 399 } 400 if (EnableVectorPrint) 401 addPass(createHexagonVectorPrint(), false); 402 403 // Add CFI instructions if necessary. 404 addPass(createHexagonCallFrameInformation(), false); 405 } 406