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/IR/LegacyPassManager.h" 22 #include "llvm/IR/Module.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/TargetRegistry.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> EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden, 41 cl::ZeroOrMore, cl::desc("Enable early if-conversion")); 42 43 static cl::opt<bool> EnableGenInsert("hexagon-insert", cl::init(true), 44 cl::Hidden, cl::desc("Generate \"insert\" instructions")); 45 46 static cl::opt<bool> EnableCommGEP("hexagon-commgep", cl::init(true), 47 cl::Hidden, cl::ZeroOrMore, cl::desc("Enable commoning of GEP instructions")); 48 49 static cl::opt<bool> EnableGenExtract("hexagon-extract", cl::init(true), 50 cl::Hidden, cl::desc("Generate \"extract\" instructions")); 51 52 static cl::opt<bool> EnableGenMux("hexagon-mux", cl::init(true), cl::Hidden, 53 cl::desc("Enable converting conditional transfers into MUX instructions")); 54 55 static cl::opt<bool> EnableGenPred("hexagon-gen-pred", cl::init(true), 56 cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " 57 "predicate instructions")); 58 59 /// HexagonTargetMachineModule - Note that this is used on hosts that 60 /// cannot link in a library unless there are references into the 61 /// library. In particular, it seems that it is not possible to get 62 /// things to work on Win32 without this. Though it is unused, do not 63 /// remove it. 64 extern "C" int HexagonTargetMachineModule; 65 int HexagonTargetMachineModule = 0; 66 67 extern "C" void LLVMInitializeHexagonTarget() { 68 // Register the target. 69 RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget); 70 } 71 72 static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 73 return new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>()); 74 } 75 76 static MachineSchedRegistry 77 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 78 createVLIWMachineSched); 79 80 namespace llvm { 81 FunctionPass *createHexagonCFGOptimizer(); 82 FunctionPass *createHexagonCommonGEP(); 83 FunctionPass *createHexagonCopyToCombine(); 84 FunctionPass *createHexagonEarlyIfConversion(); 85 FunctionPass *createHexagonExpandCondsets(); 86 FunctionPass *createHexagonExpandPredSpillCode(); 87 FunctionPass *createHexagonFixupHwLoops(); 88 FunctionPass *createHexagonGenExtract(); 89 FunctionPass *createHexagonGenInsert(); 90 FunctionPass *createHexagonGenMux(); 91 FunctionPass *createHexagonGenPredicate(); 92 FunctionPass *createHexagonHardwareLoops(); 93 FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, 94 CodeGenOpt::Level OptLevel); 95 FunctionPass *createHexagonNewValueJump(); 96 FunctionPass *createHexagonPacketizer(); 97 FunctionPass *createHexagonPeephole(); 98 FunctionPass *createHexagonRemoveExtendArgs(const HexagonTargetMachine &TM); 99 FunctionPass *createHexagonSplitConst32AndConst64(); 100 } // end namespace llvm; 101 102 /// HexagonTargetMachine ctor - Create an ILP32 architecture model. 103 /// 104 105 /// Hexagon_TODO: Do I need an aggregate alignment? 106 /// 107 HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, 108 StringRef CPU, StringRef FS, 109 const TargetOptions &Options, 110 Reloc::Model RM, CodeModel::Model CM, 111 CodeGenOpt::Level OL) 112 : LLVMTargetMachine(T, "e-m:e-p:32:32-i1:32-i64:64-a:0-n32", TT, CPU, FS, 113 Options, RM, CM, OL), 114 TLOF(make_unique<HexagonTargetObjectFile>()) { 115 initAsmInfo(); 116 } 117 118 const HexagonSubtarget * 119 HexagonTargetMachine::getSubtargetImpl(const Function &F) const { 120 AttributeSet FnAttrs = F.getAttributes(); 121 Attribute CPUAttr = 122 FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu"); 123 Attribute FSAttr = 124 FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features"); 125 126 std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 127 ? CPUAttr.getValueAsString().str() 128 : TargetCPU; 129 std::string FS = !FSAttr.hasAttribute(Attribute::None) 130 ? FSAttr.getValueAsString().str() 131 : TargetFS; 132 133 auto &I = SubtargetMap[CPU + FS]; 134 if (!I) { 135 // This needs to be done before we create a new subtarget since any 136 // creation will depend on the TM and the code generation flags on the 137 // function that reside in TargetOptions. 138 resetTargetOptions(F); 139 I = llvm::make_unique<HexagonSubtarget>(TargetTriple, CPU, FS, *this); 140 } 141 return I.get(); 142 } 143 144 TargetIRAnalysis HexagonTargetMachine::getTargetIRAnalysis() { 145 return TargetIRAnalysis([this](const Function &F) { 146 return TargetTransformInfo(HexagonTTIImpl(this, F)); 147 }); 148 } 149 150 151 HexagonTargetMachine::~HexagonTargetMachine() {} 152 153 namespace { 154 /// Hexagon Code Generator Pass Configuration Options. 155 class HexagonPassConfig : public TargetPassConfig { 156 public: 157 HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM) 158 : TargetPassConfig(TM, PM) { 159 bool NoOpt = (TM->getOptLevel() == CodeGenOpt::None); 160 if (!NoOpt) { 161 if (EnableExpandCondsets) { 162 Pass *Exp = createHexagonExpandCondsets(); 163 insertPass(&RegisterCoalescerID, IdentifyingPassPtr(Exp)); 164 } 165 } 166 } 167 168 HexagonTargetMachine &getHexagonTargetMachine() const { 169 return getTM<HexagonTargetMachine>(); 170 } 171 172 ScheduleDAGInstrs * 173 createMachineScheduler(MachineSchedContext *C) const override { 174 return createVLIWMachineSched(C); 175 } 176 177 void addIRPasses() override; 178 bool addInstSelector() override; 179 void addPreRegAlloc() override; 180 void addPostRegAlloc() override; 181 void addPreSched2() override; 182 void addPreEmitPass() override; 183 }; 184 } // namespace 185 186 TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 187 return new HexagonPassConfig(this, PM); 188 } 189 190 void HexagonPassConfig::addIRPasses() { 191 TargetPassConfig::addIRPasses(); 192 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 193 194 addPass(createAtomicExpandPass(TM)); 195 if (!NoOpt) { 196 if (EnableCommGEP) 197 addPass(createHexagonCommonGEP()); 198 // Replace certain combinations of shifts and ands with extracts. 199 if (EnableGenExtract) 200 addPass(createHexagonGenExtract()); 201 } 202 } 203 204 bool HexagonPassConfig::addInstSelector() { 205 HexagonTargetMachine &TM = getHexagonTargetMachine(); 206 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 207 208 if (!NoOpt) 209 addPass(createHexagonRemoveExtendArgs(TM)); 210 211 addPass(createHexagonISelDag(TM, getOptLevel())); 212 213 if (!NoOpt) { 214 // Create logical operations on predicate registers. 215 if (EnableGenPred) 216 addPass(createHexagonGenPredicate(), false); 217 addPass(createHexagonPeephole()); 218 printAndVerify("After hexagon peephole pass"); 219 if (EnableGenInsert) 220 addPass(createHexagonGenInsert(), false); 221 if (EnableEarlyIf) 222 addPass(createHexagonEarlyIfConversion(), false); 223 } 224 225 return false; 226 } 227 228 void HexagonPassConfig::addPreRegAlloc() { 229 if (getOptLevel() != CodeGenOpt::None) 230 if (!DisableHardwareLoops) 231 addPass(createHexagonHardwareLoops(), false); 232 } 233 234 void HexagonPassConfig::addPostRegAlloc() { 235 if (getOptLevel() != CodeGenOpt::None) 236 if (!DisableHexagonCFGOpt) 237 addPass(createHexagonCFGOptimizer(), false); 238 } 239 240 void HexagonPassConfig::addPreSched2() { 241 addPass(createHexagonCopyToCombine(), false); 242 if (getOptLevel() != CodeGenOpt::None) 243 addPass(&IfConverterID, false); 244 addPass(createHexagonSplitConst32AndConst64()); 245 } 246 247 void HexagonPassConfig::addPreEmitPass() { 248 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 249 250 if (!NoOpt) 251 addPass(createHexagonNewValueJump(), false); 252 253 // Expand Spill code for predicate registers. 254 addPass(createHexagonExpandPredSpillCode(), false); 255 256 // Create Packets. 257 if (!NoOpt) { 258 if (!DisableHardwareLoops) 259 addPass(createHexagonFixupHwLoops(), false); 260 // Generate MUX from pairs of conditional transfers. 261 if (EnableGenMux) 262 addPass(createHexagonGenMux(), false); 263 264 addPass(createHexagonPacketizer(), false); 265 } 266 } 267