ARMTargetMachine.cpp revision cd81d94322a39503e4a3e87b6ee03d4fcb3465fb
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 "ARM.h" 14#include "ARMTargetMachine.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" 24using namespace llvm; 25 26static cl::opt<bool> 27DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, 28 cl::desc("Inhibit optimization of S->D register accesses on A15"), 29 cl::init(false)); 30 31static cl::opt<bool> 32EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden, 33 cl::desc("Run SimplifyCFG after expanding atomic operations" 34 " to make use of cmpxchg flow-based information"), 35 cl::init(true)); 36 37extern "C" void LLVMInitializeARMTarget() { 38 // Register the target. 39 RegisterTargetMachine<ARMLETargetMachine> X(TheARMLETarget); 40 RegisterTargetMachine<ARMBETargetMachine> Y(TheARMBETarget); 41 RegisterTargetMachine<ThumbLETargetMachine> A(TheThumbLETarget); 42 RegisterTargetMachine<ThumbBETargetMachine> B(TheThumbBETarget); 43} 44 45 46/// TargetMachine ctor - Create an ARM architecture model. 47/// 48ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT, 49 StringRef CPU, StringRef FS, 50 const TargetOptions &Options, 51 Reloc::Model RM, CodeModel::Model CM, 52 CodeGenOpt::Level OL, bool isLittle) 53 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 54 Subtarget(TT, CPU, FS, *this, isLittle, Options) { 55 56 // Default to triple-appropriate float ABI 57 if (Options.FloatABIType == FloatABI::Default) 58 this->Options.FloatABIType = 59 Subtarget.isTargetHardFloat() ? FloatABI::Hard : FloatABI::Soft; 60} 61 62void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 63 // Add first the target-independent BasicTTI pass, then our ARM pass. This 64 // allows the ARM pass to delegate to the target independent layer when 65 // appropriate. 66 PM.add(createBasicTargetTransformInfoPass(this)); 67 PM.add(createARMTargetTransformInfoPass(this)); 68} 69 70 71void ARMTargetMachine::anchor() { } 72 73ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, StringRef CPU, 74 StringRef FS, const TargetOptions &Options, 75 Reloc::Model RM, CodeModel::Model CM, 76 CodeGenOpt::Level OL, bool isLittle) 77 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle) { 78 initAsmInfo(); 79 if (!Subtarget.hasARMOps()) 80 report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not " 81 "support ARM mode execution!"); 82} 83 84void ARMLETargetMachine::anchor() { } 85 86ARMLETargetMachine::ARMLETargetMachine(const Target &T, StringRef TT, 87 StringRef CPU, StringRef FS, 88 const TargetOptions &Options, 89 Reloc::Model RM, CodeModel::Model CM, 90 CodeGenOpt::Level OL) 91 : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 92 93void ARMBETargetMachine::anchor() { } 94 95ARMBETargetMachine::ARMBETargetMachine(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 : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 101 102void ThumbTargetMachine::anchor() { } 103 104ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT, 105 StringRef CPU, StringRef FS, 106 const TargetOptions &Options, 107 Reloc::Model RM, CodeModel::Model CM, 108 CodeGenOpt::Level OL, bool isLittle) 109 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, 110 isLittle) { 111 initAsmInfo(); 112} 113 114void ThumbLETargetMachine::anchor() { } 115 116ThumbLETargetMachine::ThumbLETargetMachine(const Target &T, StringRef TT, 117 StringRef CPU, StringRef FS, 118 const TargetOptions &Options, 119 Reloc::Model RM, CodeModel::Model CM, 120 CodeGenOpt::Level OL) 121 : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 122 123void ThumbBETargetMachine::anchor() { } 124 125ThumbBETargetMachine::ThumbBETargetMachine(const Target &T, StringRef TT, 126 StringRef CPU, StringRef FS, 127 const TargetOptions &Options, 128 Reloc::Model RM, CodeModel::Model CM, 129 CodeGenOpt::Level OL) 130 : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 131 132namespace { 133/// ARM Code Generator Pass Configuration Options. 134class ARMPassConfig : public TargetPassConfig { 135public: 136 ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM) 137 : TargetPassConfig(TM, PM) {} 138 139 ARMBaseTargetMachine &getARMTargetMachine() const { 140 return getTM<ARMBaseTargetMachine>(); 141 } 142 143 const ARMSubtarget &getARMSubtarget() const { 144 return *getARMTargetMachine().getSubtargetImpl(); 145 } 146 147 void addIRPasses() override; 148 bool addPreISel() override; 149 bool addInstSelector() override; 150 bool addPreRegAlloc() override; 151 bool addPreSched2() override; 152 bool addPreEmitPass() override; 153}; 154} // namespace 155 156TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) { 157 return new ARMPassConfig(this, PM); 158} 159 160void ARMPassConfig::addIRPasses() { 161 addPass(createAtomicExpandLoadLinkedPass(TM)); 162 163 // Cmpxchg instructions are often used with a subsequent comparison to 164 // determine whether it succeeded. We can exploit existing control-flow in 165 // ldrex/strex loops to simplify this, but it needs tidying up. 166 const ARMSubtarget *Subtarget = &getARMSubtarget(); 167 if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only()) 168 if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) 169 addPass(createCFGSimplificationPass()); 170 171 TargetPassConfig::addIRPasses(); 172} 173 174bool ARMPassConfig::addPreISel() { 175 if (TM->getOptLevel() != CodeGenOpt::None) 176 addPass(createGlobalMergePass(TM)); 177 178 return false; 179} 180 181bool ARMPassConfig::addInstSelector() { 182 addPass(createARMISelDag(getARMTargetMachine(), getOptLevel())); 183 184 const ARMSubtarget *Subtarget = &getARMSubtarget(); 185 if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() && 186 TM->Options.EnableFastISel) 187 addPass(createARMGlobalBaseRegPass()); 188 return false; 189} 190 191bool ARMPassConfig::addPreRegAlloc() { 192 if (getOptLevel() != CodeGenOpt::None) 193 addPass(createARMLoadStoreOptimizationPass(true)); 194 if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9()) 195 addPass(createMLxExpansionPass()); 196 // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be 197 // enabled when NEON is available. 198 if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() && 199 getARMSubtarget().hasNEON() && !DisableA15SDOptimization) { 200 addPass(createA15SDOptimizerPass()); 201 } 202 return true; 203} 204 205bool ARMPassConfig::addPreSched2() { 206 if (getOptLevel() != CodeGenOpt::None) { 207 addPass(createARMLoadStoreOptimizationPass()); 208 printAndVerify("After ARM load / store optimizer"); 209 210 if (getARMSubtarget().hasNEON()) 211 addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass)); 212 } 213 214 // Expand some pseudo instructions into multiple instructions to allow 215 // proper scheduling. 216 addPass(createARMExpandPseudoPass()); 217 218 if (getOptLevel() != CodeGenOpt::None) { 219 if (!getARMSubtarget().isThumb1Only()) { 220 // in v8, IfConversion depends on Thumb instruction widths 221 if (getARMSubtarget().restrictIT() && 222 !getARMSubtarget().prefers32BitThumb()) 223 addPass(createThumb2SizeReductionPass()); 224 addPass(&IfConverterID); 225 } 226 } 227 if (getARMSubtarget().isThumb2()) 228 addPass(createThumb2ITBlockPass()); 229 230 return true; 231} 232 233bool ARMPassConfig::addPreEmitPass() { 234 if (getARMSubtarget().isThumb2()) { 235 if (!getARMSubtarget().prefers32BitThumb()) 236 addPass(createThumb2SizeReductionPass()); 237 238 // Constant island pass work on unbundled instructions. 239 addPass(&UnpackMachineBundlesID); 240 } 241 242 addPass(createARMOptimizeBarriersPass()); 243 addPass(createARMConstantIslandPass()); 244 245 return true; 246} 247 248bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 249 JITCodeEmitter &JCE) { 250 // Machine code emitter pass for ARM. 251 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 252 return false; 253} 254