LLVM API Documentation
00001 //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // 00011 //===----------------------------------------------------------------------===// 00012 00013 #include "ARM.h" 00014 #include "ARMTargetMachine.h" 00015 #include "ARMFrameLowering.h" 00016 #include "llvm/CodeGen/Passes.h" 00017 #include "llvm/MC/MCAsmInfo.h" 00018 #include "llvm/PassManager.h" 00019 #include "llvm/Support/CommandLine.h" 00020 #include "llvm/Support/FormattedStream.h" 00021 #include "llvm/Support/TargetRegistry.h" 00022 #include "llvm/Target/TargetOptions.h" 00023 #include "llvm/Transforms/Scalar.h" 00024 using namespace llvm; 00025 00026 static cl::opt<bool> 00027 DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, 00028 cl::desc("Inhibit optimization of S->D register accesses on A15"), 00029 cl::init(false)); 00030 00031 static cl::opt<bool> 00032 EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden, 00033 cl::desc("Run SimplifyCFG after expanding atomic operations" 00034 " to make use of cmpxchg flow-based information"), 00035 cl::init(true)); 00036 00037 extern "C" void LLVMInitializeARMTarget() { 00038 // Register the target. 00039 RegisterTargetMachine<ARMLETargetMachine> X(TheARMLETarget); 00040 RegisterTargetMachine<ARMBETargetMachine> Y(TheARMBETarget); 00041 RegisterTargetMachine<ThumbLETargetMachine> A(TheThumbLETarget); 00042 RegisterTargetMachine<ThumbBETargetMachine> B(TheThumbBETarget); 00043 } 00044 00045 00046 /// TargetMachine ctor - Create an ARM architecture model. 00047 /// 00048 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT, 00049 StringRef CPU, StringRef FS, 00050 const TargetOptions &Options, 00051 Reloc::Model RM, CodeModel::Model CM, 00052 CodeGenOpt::Level OL, bool isLittle) 00053 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 00054 Subtarget(TT, CPU, FS, *this, isLittle, Options) { 00055 00056 // Default to triple-appropriate float ABI 00057 if (Options.FloatABIType == FloatABI::Default) 00058 this->Options.FloatABIType = 00059 Subtarget.isTargetHardFloat() ? FloatABI::Hard : FloatABI::Soft; 00060 } 00061 00062 void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 00063 // Add first the target-independent BasicTTI pass, then our ARM pass. This 00064 // allows the ARM pass to delegate to the target independent layer when 00065 // appropriate. 00066 PM.add(createBasicTargetTransformInfoPass(this)); 00067 PM.add(createARMTargetTransformInfoPass(this)); 00068 } 00069 00070 00071 void ARMTargetMachine::anchor() { } 00072 00073 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, StringRef CPU, 00074 StringRef FS, const TargetOptions &Options, 00075 Reloc::Model RM, CodeModel::Model CM, 00076 CodeGenOpt::Level OL, bool isLittle) 00077 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle) { 00078 initAsmInfo(); 00079 if (!Subtarget.hasARMOps()) 00080 report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not " 00081 "support ARM mode execution!"); 00082 } 00083 00084 void ARMLETargetMachine::anchor() { } 00085 00086 ARMLETargetMachine::ARMLETargetMachine(const Target &T, StringRef TT, 00087 StringRef CPU, StringRef FS, 00088 const TargetOptions &Options, 00089 Reloc::Model RM, CodeModel::Model CM, 00090 CodeGenOpt::Level OL) 00091 : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 00092 00093 void ARMBETargetMachine::anchor() { } 00094 00095 ARMBETargetMachine::ARMBETargetMachine(const Target &T, StringRef TT, 00096 StringRef CPU, StringRef FS, 00097 const TargetOptions &Options, 00098 Reloc::Model RM, CodeModel::Model CM, 00099 CodeGenOpt::Level OL) 00100 : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 00101 00102 void ThumbTargetMachine::anchor() { } 00103 00104 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT, 00105 StringRef CPU, StringRef FS, 00106 const TargetOptions &Options, 00107 Reloc::Model RM, CodeModel::Model CM, 00108 CodeGenOpt::Level OL, bool isLittle) 00109 : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, 00110 isLittle) { 00111 initAsmInfo(); 00112 } 00113 00114 void ThumbLETargetMachine::anchor() { } 00115 00116 ThumbLETargetMachine::ThumbLETargetMachine(const Target &T, StringRef TT, 00117 StringRef CPU, StringRef FS, 00118 const TargetOptions &Options, 00119 Reloc::Model RM, CodeModel::Model CM, 00120 CodeGenOpt::Level OL) 00121 : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 00122 00123 void ThumbBETargetMachine::anchor() { } 00124 00125 ThumbBETargetMachine::ThumbBETargetMachine(const Target &T, StringRef TT, 00126 StringRef CPU, StringRef FS, 00127 const TargetOptions &Options, 00128 Reloc::Model RM, CodeModel::Model CM, 00129 CodeGenOpt::Level OL) 00130 : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 00131 00132 namespace { 00133 /// ARM Code Generator Pass Configuration Options. 00134 class ARMPassConfig : public TargetPassConfig { 00135 public: 00136 ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM) 00137 : TargetPassConfig(TM, PM) {} 00138 00139 ARMBaseTargetMachine &getARMTargetMachine() const { 00140 return getTM<ARMBaseTargetMachine>(); 00141 } 00142 00143 const ARMSubtarget &getARMSubtarget() const { 00144 return *getARMTargetMachine().getSubtargetImpl(); 00145 } 00146 00147 void addIRPasses() override; 00148 bool addPreISel() override; 00149 bool addInstSelector() override; 00150 bool addPreRegAlloc() override; 00151 bool addPreSched2() override; 00152 bool addPreEmitPass() override; 00153 }; 00154 } // namespace 00155 00156 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) { 00157 return new ARMPassConfig(this, PM); 00158 } 00159 00160 void ARMPassConfig::addIRPasses() { 00161 if (TM->Options.ThreadModel == ThreadModel::Single) 00162 addPass(createLowerAtomicPass()); 00163 else 00164 addPass(createAtomicExpandPass(TM)); 00165 00166 // Cmpxchg instructions are often used with a subsequent comparison to 00167 // determine whether it succeeded. We can exploit existing control-flow in 00168 // ldrex/strex loops to simplify this, but it needs tidying up. 00169 const ARMSubtarget *Subtarget = &getARMSubtarget(); 00170 if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only()) 00171 if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) 00172 addPass(createCFGSimplificationPass()); 00173 00174 TargetPassConfig::addIRPasses(); 00175 } 00176 00177 bool ARMPassConfig::addPreISel() { 00178 if (TM->getOptLevel() != CodeGenOpt::None) 00179 addPass(createGlobalMergePass(TM)); 00180 00181 return false; 00182 } 00183 00184 bool ARMPassConfig::addInstSelector() { 00185 addPass(createARMISelDag(getARMTargetMachine(), getOptLevel())); 00186 00187 const ARMSubtarget *Subtarget = &getARMSubtarget(); 00188 if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() && 00189 TM->Options.EnableFastISel) 00190 addPass(createARMGlobalBaseRegPass()); 00191 return false; 00192 } 00193 00194 bool ARMPassConfig::addPreRegAlloc() { 00195 if (getOptLevel() != CodeGenOpt::None) 00196 addPass(createARMLoadStoreOptimizationPass(true)); 00197 if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9()) 00198 addPass(createMLxExpansionPass()); 00199 // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be 00200 // enabled when NEON is available. 00201 if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() && 00202 getARMSubtarget().hasNEON() && !DisableA15SDOptimization) { 00203 addPass(createA15SDOptimizerPass()); 00204 } 00205 return true; 00206 } 00207 00208 bool ARMPassConfig::addPreSched2() { 00209 if (getOptLevel() != CodeGenOpt::None) { 00210 addPass(createARMLoadStoreOptimizationPass()); 00211 printAndVerify("After ARM load / store optimizer"); 00212 00213 if (getARMSubtarget().hasNEON()) 00214 addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass)); 00215 } 00216 00217 // Expand some pseudo instructions into multiple instructions to allow 00218 // proper scheduling. 00219 addPass(createARMExpandPseudoPass()); 00220 00221 if (getOptLevel() != CodeGenOpt::None) { 00222 if (!getARMSubtarget().isThumb1Only()) { 00223 // in v8, IfConversion depends on Thumb instruction widths 00224 if (getARMSubtarget().restrictIT() && 00225 !getARMSubtarget().prefers32BitThumb()) 00226 addPass(createThumb2SizeReductionPass()); 00227 addPass(&IfConverterID); 00228 } 00229 } 00230 if (getARMSubtarget().isThumb2()) 00231 addPass(createThumb2ITBlockPass()); 00232 00233 return true; 00234 } 00235 00236 bool ARMPassConfig::addPreEmitPass() { 00237 if (getARMSubtarget().isThumb2()) { 00238 if (!getARMSubtarget().prefers32BitThumb()) 00239 addPass(createThumb2SizeReductionPass()); 00240 00241 // Constant island pass work on unbundled instructions. 00242 addPass(&UnpackMachineBundlesID); 00243 } 00244 00245 addPass(createARMOptimizeBarriersPass()); 00246 addPass(createARMConstantIslandPass()); 00247 00248 return true; 00249 }