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" 24using namespace llvm; 25 26static cl::opt<bool> 27EnableGlobalMerge("global-merge", cl::Hidden, 28 cl::desc("Enable global merge pass"), 29 cl::init(true)); 30 31static cl::opt<bool> 32DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, 33 cl::desc("Inhibit optimization of S->D register accesses on A15"), 34 cl::init(false)); 35 36extern "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/// 45ARMBaseTargetMachine::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, Options), 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 59void 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 68void ARMTargetMachine::anchor() { } 69 70ARMTargetMachine::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 93void ThumbTargetMachine::anchor() { } 94 95ThumbTargetMachine::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 122namespace { 123/// ARM Code Generator Pass Configuration Options. 124class ARMPassConfig : public TargetPassConfig { 125public: 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 145TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) { 146 return new ARMPassConfig(this, PM); 147} 148 149bool ARMPassConfig::addPreISel() { 150 if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge) 151 addPass(createGlobalMergePass(TM->getTargetLowering())); 152 153 return false; 154} 155 156bool 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 166bool 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 181bool 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 (getARMSubtarget().hasNEON()) 189 addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass)); 190 } 191 192 // Expand some pseudo instructions into multiple instructions to allow 193 // proper scheduling. 194 addPass(createARMExpandPseudoPass()); 195 196 if (getOptLevel() != CodeGenOpt::None) { 197 if (!getARMSubtarget().isThumb1Only()) 198 addPass(&IfConverterID); 199 } 200 if (getARMSubtarget().isThumb2()) 201 addPass(createThumb2ITBlockPass()); 202 203 return true; 204} 205 206bool ARMPassConfig::addPreEmitPass() { 207 if (getARMSubtarget().isThumb2()) { 208 if (!getARMSubtarget().prefers32BitThumb()) 209 addPass(createThumb2SizeReductionPass()); 210 211 // Constant island pass work on unbundled instructions. 212 addPass(&UnpackMachineBundlesID); 213 } 214 215 addPass(createARMConstantIslandPass()); 216 217 return true; 218} 219 220bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 221 JITCodeEmitter &JCE) { 222 // Machine code emitter pass for ARM. 223 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 224 return false; 225} 226