1 //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===// 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 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARMTargetMachine.h" 14 #include "ARM.h" 15 #include "ARMFrameLowering.h" 16 #include "llvm/CodeGen/Passes.h" 17 #include "llvm/MC/MCAsmInfo.h" 18 #include "llvm/PassManager.h" 19 #include "llvm/Support/CommandLine.h" 20 #include "llvm/Support/FormattedStream.h" 21 #include "llvm/Support/TargetRegistry.h" 22 #include "llvm/Target/TargetOptions.h" 23 #include "llvm/Transforms/Scalar.h" 24 using namespace llvm; 25 26 static cl::opt<bool> 27 EnableGlobalMerge("global-merge", cl::Hidden, 28 cl::desc("Enable global merge pass"), 29 cl::init(true)); 30 31 static cl::opt<bool> 32 DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, 33 cl::desc("Inhibit optimization of S->D register accesses on A15"), 34 cl::init(false)); 35 36 extern "C" void LLVMInitializeARMTarget() { 37 // Register the target. 38 RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget); 39 RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget); 40 } 41 42 43 /// TargetMachine ctor - Create an ARM architecture model. 44 /// 45 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT, 46 StringRef CPU, StringRef FS, 47 const TargetOptions &Options, 48 Reloc::Model RM, CodeModel::Model CM, 49 CodeGenOpt::Level OL) 50 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 51 Subtarget(TT, CPU, FS), 52 JITInfo(), 53 InstrItins(Subtarget.getInstrItineraryData()) { 54 // Default to soft float ABI 55 if (Options.FloatABIType == FloatABI::Default) 56 this->Options.FloatABIType = FloatABI::Soft; 57 } 58 59 void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 60 // Add first the target-independent BasicTTI pass, then our ARM pass. This 61 // allows the ARM pass to delegate to the target independent layer when 62 // appropriate. 63 PM.add(createBasicTargetTransformInfoPass(getTargetLowering())); 64 PM.add(createARMTargetTransformInfoPass(this)); 65 } 66 67 68 void ARMTargetMachine::anchor() { } 69 70 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, 71 StringRef CPU, StringRef FS, 72 const TargetOptions &Options, 73 Reloc::Model RM, CodeModel::Model CM, 74 CodeGenOpt::Level OL) 75 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 76 InstrInfo(Subtarget), 77 DL(Subtarget.isAPCS_ABI() ? 78 std::string("e-p:32:32-f64:32:64-i64:32:64-" 79 "v128:32:128-v64:32:64-n32-S32") : 80 Subtarget.isAAPCS_ABI() ? 81 std::string("e-p:32:32-f64:64:64-i64:64:64-" 82 "v128:64:128-v64:64:64-n32-S64") : 83 std::string("e-p:32:32-f64:64:64-i64:64:64-" 84 "v128:64:128-v64:64:64-n32-S32")), 85 TLInfo(*this), 86 TSInfo(*this), 87 FrameLowering(Subtarget) { 88 if (!Subtarget.hasARMOps()) 89 report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not " 90 "support ARM mode execution!"); 91 } 92 93 void ThumbTargetMachine::anchor() { } 94 95 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT, 96 StringRef CPU, StringRef FS, 97 const TargetOptions &Options, 98 Reloc::Model RM, CodeModel::Model CM, 99 CodeGenOpt::Level OL) 100 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 101 InstrInfo(Subtarget.hasThumb2() 102 ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget)) 103 : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))), 104 DL(Subtarget.isAPCS_ABI() ? 105 std::string("e-p:32:32-f64:32:64-i64:32:64-" 106 "i16:16:32-i8:8:32-i1:8:32-" 107 "v128:32:128-v64:32:64-a:0:32-n32-S32") : 108 Subtarget.isAAPCS_ABI() ? 109 std::string("e-p:32:32-f64:64:64-i64:64:64-" 110 "i16:16:32-i8:8:32-i1:8:32-" 111 "v128:64:128-v64:64:64-a:0:32-n32-S64") : 112 std::string("e-p:32:32-f64:64:64-i64:64:64-" 113 "i16:16:32-i8:8:32-i1:8:32-" 114 "v128:64:128-v64:64:64-a:0:32-n32-S32")), 115 TLInfo(*this), 116 TSInfo(*this), 117 FrameLowering(Subtarget.hasThumb2() 118 ? new ARMFrameLowering(Subtarget) 119 : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) { 120 } 121 122 namespace { 123 /// ARM Code Generator Pass Configuration Options. 124 class ARMPassConfig : public TargetPassConfig { 125 public: 126 ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM) 127 : TargetPassConfig(TM, PM) {} 128 129 ARMBaseTargetMachine &getARMTargetMachine() const { 130 return getTM<ARMBaseTargetMachine>(); 131 } 132 133 const ARMSubtarget &getARMSubtarget() const { 134 return *getARMTargetMachine().getSubtargetImpl(); 135 } 136 137 virtual bool addPreISel(); 138 virtual bool addInstSelector(); 139 virtual bool addPreRegAlloc(); 140 virtual bool addPreSched2(); 141 virtual bool addPreEmitPass(); 142 }; 143 } // namespace 144 145 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) { 146 return new ARMPassConfig(this, PM); 147 } 148 149 bool ARMPassConfig::addPreISel() { 150 if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge) 151 addPass(createGlobalMergePass(TM->getTargetLowering())); 152 153 return false; 154 } 155 156 bool ARMPassConfig::addInstSelector() { 157 addPass(createARMISelDag(getARMTargetMachine(), getOptLevel())); 158 159 const ARMSubtarget *Subtarget = &getARMSubtarget(); 160 if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() && 161 TM->Options.EnableFastISel) 162 addPass(createARMGlobalBaseRegPass()); 163 return false; 164 } 165 166 bool ARMPassConfig::addPreRegAlloc() { 167 // FIXME: temporarily disabling load / store optimization pass for Thumb1. 168 if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only()) 169 addPass(createARMLoadStoreOptimizationPass(true)); 170 if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isLikeA9()) 171 addPass(createMLxExpansionPass()); 172 // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be 173 // enabled when NEON is available. 174 if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() && 175 getARMSubtarget().hasNEON() && !DisableA15SDOptimization) { 176 addPass(createA15SDOptimizerPass()); 177 } 178 return true; 179 } 180 181 bool ARMPassConfig::addPreSched2() { 182 // FIXME: temporarily disabling load / store optimization pass for Thumb1. 183 if (getOptLevel() != CodeGenOpt::None) { 184 if (!getARMSubtarget().isThumb1Only()) { 185 addPass(createARMLoadStoreOptimizationPass()); 186 printAndVerify("After ARM load / store optimizer"); 187 } 188 if ((DisableA15SDOptimization || !getARMSubtarget().isCortexA15()) && 189 getARMSubtarget().hasNEON()) 190 addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass)); 191 } 192 193 // Expand some pseudo instructions into multiple instructions to allow 194 // proper scheduling. 195 addPass(createARMExpandPseudoPass()); 196 197 if (getOptLevel() != CodeGenOpt::None) { 198 if (!getARMSubtarget().isThumb1Only()) 199 addPass(&IfConverterID); 200 } 201 if (getARMSubtarget().isThumb2()) 202 addPass(createThumb2ITBlockPass()); 203 204 return true; 205 } 206 207 bool ARMPassConfig::addPreEmitPass() { 208 if (getARMSubtarget().isThumb2()) { 209 if (!getARMSubtarget().prefers32BitThumb()) 210 addPass(createThumb2SizeReductionPass()); 211 212 // Constant island pass work on unbundled instructions. 213 addPass(&UnpackMachineBundlesID); 214 } 215 216 addPass(createARMConstantIslandPass()); 217 218 return true; 219 } 220 221 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 222 JITCodeEmitter &JCE) { 223 // Machine code emitter pass for ARM. 224 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 225 return false; 226 } 227