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 41 /// HexagonTargetMachineModule - Note that this is used on hosts that 42 /// cannot link in a library unless there are references into the 43 /// library. In particular, it seems that it is not possible to get 44 /// things to work on Win32 without this. Though it is unused, do not 45 /// remove it. 46 extern "C" int HexagonTargetMachineModule; 47 int HexagonTargetMachineModule = 0; 48 49 extern "C" void LLVMInitializeHexagonTarget() { 50 // Register the target. 51 RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget); 52 } 53 54 static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { 55 return new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>()); 56 } 57 58 static MachineSchedRegistry 59 SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", 60 createVLIWMachineSched); 61 62 namespace llvm { 63 FunctionPass *createHexagonExpandCondsets(); 64 } 65 66 /// HexagonTargetMachine ctor - Create an ILP32 architecture model. 67 /// 68 69 /// Hexagon_TODO: Do I need an aggregate alignment? 70 /// 71 HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT, 72 StringRef CPU, StringRef FS, 73 const TargetOptions &Options, 74 Reloc::Model RM, CodeModel::Model CM, 75 CodeGenOpt::Level OL) 76 : LLVMTargetMachine(T, "e-m:e-p:32:32-i1:32-i64:64-a:0-n32", TT, CPU, FS, 77 Options, RM, CM, OL), 78 TLOF(make_unique<HexagonTargetObjectFile>()), 79 Subtarget(TT, CPU, FS, *this) { 80 initAsmInfo(); 81 } 82 83 HexagonTargetMachine::~HexagonTargetMachine() {} 84 85 namespace { 86 /// Hexagon Code Generator Pass Configuration Options. 87 class HexagonPassConfig : public TargetPassConfig { 88 public: 89 HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM) 90 : TargetPassConfig(TM, PM) { 91 bool NoOpt = (TM->getOptLevel() == CodeGenOpt::None); 92 if (!NoOpt) { 93 if (EnableExpandCondsets) { 94 Pass *Exp = createHexagonExpandCondsets(); 95 insertPass(&RegisterCoalescerID, IdentifyingPassPtr(Exp)); 96 } 97 } 98 } 99 100 HexagonTargetMachine &getHexagonTargetMachine() const { 101 return getTM<HexagonTargetMachine>(); 102 } 103 104 ScheduleDAGInstrs * 105 createMachineScheduler(MachineSchedContext *C) const override { 106 return createVLIWMachineSched(C); 107 } 108 109 bool addInstSelector() override; 110 void addPreRegAlloc() override; 111 void addPostRegAlloc() override; 112 void addPreSched2() override; 113 void addPreEmitPass() override; 114 }; 115 } // namespace 116 117 TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) { 118 return new HexagonPassConfig(this, PM); 119 } 120 121 bool HexagonPassConfig::addInstSelector() { 122 HexagonTargetMachine &TM = getHexagonTargetMachine(); 123 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 124 125 if (!NoOpt) 126 addPass(createHexagonRemoveExtendArgs(TM)); 127 128 addPass(createHexagonISelDag(TM, getOptLevel())); 129 130 if (!NoOpt) { 131 addPass(createHexagonPeephole()); 132 printAndVerify("After hexagon peephole pass"); 133 } 134 135 return false; 136 } 137 138 void HexagonPassConfig::addPreRegAlloc() { 139 if (getOptLevel() != CodeGenOpt::None) 140 if (!DisableHardwareLoops) 141 addPass(createHexagonHardwareLoops(), false); 142 } 143 144 void HexagonPassConfig::addPostRegAlloc() { 145 if (getOptLevel() != CodeGenOpt::None) 146 if (!DisableHexagonCFGOpt) 147 addPass(createHexagonCFGOptimizer(), false); 148 } 149 150 void HexagonPassConfig::addPreSched2() { 151 addPass(createHexagonCopyToCombine(), false); 152 if (getOptLevel() != CodeGenOpt::None) 153 addPass(&IfConverterID, false); 154 addPass(createHexagonSplitConst32AndConst64()); 155 } 156 157 void HexagonPassConfig::addPreEmitPass() { 158 bool NoOpt = (getOptLevel() == CodeGenOpt::None); 159 160 if (!NoOpt) 161 addPass(createHexagonNewValueJump(), false); 162 163 // Expand Spill code for predicate registers. 164 addPass(createHexagonExpandPredSpillCode(), false); 165 166 // Create Packets. 167 if (!NoOpt) { 168 if (!DisableHardwareLoops) 169 addPass(createHexagonFixupHwLoops(), false); 170 addPass(createHexagonPacketizer(), false); 171 } 172 } 173