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 static cl::opt<bool> EnableGenExtract("hexagon-extract", cl::init(true), 47 cl::Hidden, cl::desc("Generate \"extract\" instructions")); 48 49 static cl::opt<bool> EnableGenPred("hexagon-gen-pred", cl::init(true), 50 cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " 51 "predicate instructions")); 52 53 /// HexagonTargetMachineModule - Note that this is used on hosts that 54 /// cannot link in a library unless there are references into the 55 /// library. In particular, it seems that it is not possible to get 56 /// things to work on Win32 without this. Though it is unused, do not 57 /// remove it. 58 extern "C" int HexagonTargetMachineModule; 59 int HexagonTargetMachineModule = 0; 60 61 extern "C" void LLVMInitializeHexagonTarget() { 62 // Register the target. 63 RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget); 64 } 65 66 static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 67 return new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>()); 68 } 69 70 static MachineSchedRegistry 71 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 72 createVLIWMachineSched); 73 74 namespace llvm { 75 FunctionPass *createHexagonCFGOptimizer(); 76 FunctionPass *createHexagonCommonGEP(); 77 FunctionPass *createHexagonCopyToCombine(); 78 FunctionPass *createHexagonExpandCondsets(); 79 FunctionPass *createHexagonExpandPredSpillCode(); 80 FunctionPass *createHexagonFixupHwLoops(); 81 FunctionPass *createHexagonGenExtract(); 82 FunctionPass *createHexagonGenInsert(); 83 FunctionPass *createHexagonGenPredicate(); 84 FunctionPass *createHexagonHardwareLoops(); 85 FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, 86 CodeGenOpt::Level OptLevel); 87 FunctionPass *createHexagonNewValueJump(); 88 FunctionPass *createHexagonPacketizer(); 89 FunctionPass *createHexagonPeephole(); 90 FunctionPass *createHexagonRemoveExtendArgs(const HexagonTargetMachine &TM); 91 FunctionPass *createHexagonSplitConst32AndConst64(); 92 } // end namespace llvm; 93 94 /// HexagonTargetMachine ctor - Create an ILP32 architecture model. 95 /// 96 97 /// Hexagon_TODO: Do I need an aggregate alignment? 98 /// 99 HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, 100 StringRef CPU, StringRef FS, 101 const TargetOptions &Options, 102 Reloc::Model RM, CodeModel::Model CM, 103 CodeGenOpt::Level OL) 104 : LLVMTargetMachine(T, "e-m:e-p:32:32-i1:32-i64:64-a:0-n32", TT, CPU, FS, 105 Options, RM, CM, OL), 106 TLOF(make_unique<HexagonTargetObjectFile>()), 107 Subtarget(TT, CPU, FS, *this) { 108 initAsmInfo(); 109 } 110 111 HexagonTargetMachine::~HexagonTargetMachine() {} 112 113 namespace { 114 /// Hexagon Code Generator Pass Configuration Options. 115 class HexagonPassConfig : public TargetPassConfig { 116 public: 117 HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM) 118 : TargetPassConfig(TM, PM) { 119 bool NoOpt = (TM->getOptLevel() == CodeGenOpt::None); 120 if (!NoOpt) { 121 if (EnableExpandCondsets) { 122 Pass *Exp = createHexagonExpandCondsets(); 123 insertPass(&RegisterCoalescerID, IdentifyingPassPtr(Exp)); 124 } 125 } 126 } 127 128 HexagonTargetMachine &getHexagonTargetMachine() const { 129 return getTM<HexagonTargetMachine>(); 130 } 131 132 ScheduleDAGInstrs * 133 createMachineScheduler(MachineSchedContext *C) const override { 134 return createVLIWMachineSched(C); 135 } 136 137 void addIRPasses() override; 138 bool addInstSelector() override; 139 void addPreRegAlloc() override; 140 void addPostRegAlloc() override; 141 void addPreSched2() override; 142 void addPreEmitPass() override; 143 }; 144 } // namespace 145 146 TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 147 return new HexagonPassConfig(this, PM); 148 } 149 150 void HexagonPassConfig::addIRPasses() { 151 TargetPassConfig::addIRPasses(); 152 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 153 154 addPass(createAtomicExpandPass(TM)); 155 if (!NoOpt) { 156 if (EnableCommGEP) 157 addPass(createHexagonCommonGEP()); 158 // Replace certain combinations of shifts and ands with extracts. 159 if (EnableGenExtract) 160 addPass(createHexagonGenExtract()); 161 } 162 } 163 164 bool HexagonPassConfig::addInstSelector() { 165 HexagonTargetMachine &TM = getHexagonTargetMachine(); 166 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 167 168 if (!NoOpt) 169 addPass(createHexagonRemoveExtendArgs(TM)); 170 171 addPass(createHexagonISelDag(TM, getOptLevel())); 172 173 if (!NoOpt) { 174 // Create logical operations on predicate registers. 175 if (EnableGenPred) 176 addPass(createHexagonGenPredicate(), false); 177 addPass(createHexagonPeephole()); 178 printAndVerify("After hexagon peephole pass"); 179 if (EnableGenInsert) 180 addPass(createHexagonGenInsert(), false); 181 } 182 183 return false; 184 } 185 186 void HexagonPassConfig::addPreRegAlloc() { 187 if (getOptLevel() != CodeGenOpt::None) 188 if (!DisableHardwareLoops) 189 addPass(createHexagonHardwareLoops(), false); 190 } 191 192 void HexagonPassConfig::addPostRegAlloc() { 193 if (getOptLevel() != CodeGenOpt::None) 194 if (!DisableHexagonCFGOpt) 195 addPass(createHexagonCFGOptimizer(), false); 196 } 197 198 void HexagonPassConfig::addPreSched2() { 199 addPass(createHexagonCopyToCombine(), false); 200 if (getOptLevel() != CodeGenOpt::None) 201 addPass(&IfConverterID, false); 202 addPass(createHexagonSplitConst32AndConst64()); 203 } 204 205 void HexagonPassConfig::addPreEmitPass() { 206 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 207 208 if (!NoOpt) 209 addPass(createHexagonNewValueJump(), false); 210 211 // Expand Spill code for predicate registers. 212 addPass(createHexagonExpandPredSpillCode(), false); 213 214 // Create Packets. 215 if (!NoOpt) { 216 if (!DisableHardwareLoops) 217 addPass(createHexagonFixupHwLoops(), false); 218 addPass(createHexagonPacketizer(), false); 219 } 220 } 221