ARMTargetMachine.cpp revision 6c05796294a7a0693d96c0c87194b9d5ddf55a94
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 "ARMTargetAsmInfo.h" 15#include "ARMFrameInfo.h" 16#include "ARM.h" 17#include "llvm/Module.h" 18#include "llvm/PassManager.h" 19#include "llvm/CodeGen/Passes.h" 20#include "llvm/Support/CommandLine.h" 21#include "llvm/Support/FormattedStream.h" 22#include "llvm/Target/TargetMachineRegistry.h" 23#include "llvm/Target/TargetOptions.h" 24using namespace llvm; 25 26static cl::opt<bool> DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden, 27 cl::desc("Disable load store optimization pass")); 28static cl::opt<bool> DisableIfConversion("disable-arm-if-conversion",cl::Hidden, 29 cl::desc("Disable if-conversion pass")); 30 31/// ARMTargetMachineModule - Note that this is used on hosts that cannot link 32/// in a library unless there are references into the library. In particular, 33/// it seems that it is not possible to get things to work on Win32 without 34/// this. Though it is unused, do not remove it. 35extern "C" int ARMTargetMachineModule; 36int ARMTargetMachineModule = 0; 37 38// Register the target. 39extern Target TheARMTarget; 40static RegisterTarget<ARMTargetMachine> X(TheARMTarget, "arm", "ARM"); 41 42extern Target TheThumbTarget; 43static RegisterTarget<ThumbTargetMachine> Y(TheThumbTarget, "thumb", "Thumb"); 44 45// Force static initialization. 46extern "C" void LLVMInitializeARMTarget() { } 47 48// No assembler printer by default 49ARMBaseTargetMachine::AsmPrinterCtorFn ARMBaseTargetMachine::AsmPrinterCtor = 0; 50 51/// TargetMachine ctor - Create an ARM architecture model. 52/// 53ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, 54 const Module &M, 55 const std::string &FS, 56 bool isThumb) 57 : LLVMTargetMachine(T), 58 Subtarget(M, FS, isThumb), 59 FrameInfo(Subtarget), 60 JITInfo(), 61 InstrItins(Subtarget.getInstrItineraryData()) { 62 DefRelocModel = getRelocationModel(); 63} 64 65ARMTargetMachine::ARMTargetMachine(const Target &T, const Module &M, 66 const std::string &FS) 67 : ARMBaseTargetMachine(T, M, FS, false), InstrInfo(Subtarget), 68 DataLayout(Subtarget.isAPCS_ABI() ? 69 std::string("e-p:32:32-f64:32:32-i64:32:32") : 70 std::string("e-p:32:32-f64:64:64-i64:64:64")), 71 TLInfo(*this) { 72} 73 74ThumbTargetMachine::ThumbTargetMachine(const Target &T, const Module &M, 75 const std::string &FS) 76 : ARMBaseTargetMachine(T, M, FS, true), 77 DataLayout(Subtarget.isAPCS_ABI() ? 78 std::string("e-p:32:32-f64:32:32-i64:32:32-" 79 "i16:16:32-i8:8:32-i1:8:32-a:0:32") : 80 std::string("e-p:32:32-f64:64:64-i64:64:64-" 81 "i16:16:32-i8:8:32-i1:8:32-a:0:32")), 82 TLInfo(*this) { 83 // Create the approriate type of Thumb InstrInfo 84 if (Subtarget.hasThumb2()) 85 InstrInfo = new Thumb2InstrInfo(Subtarget); 86 else 87 InstrInfo = new Thumb1InstrInfo(Subtarget); 88} 89 90 91const TargetAsmInfo *ARMBaseTargetMachine::createTargetAsmInfo() const { 92 switch (Subtarget.TargetType) { 93 case ARMSubtarget::isDarwin: 94 return new ARMDarwinTargetAsmInfo(*this); 95 case ARMSubtarget::isELF: 96 return new ARMELFTargetAsmInfo(*this); 97 default: 98 return new ARMGenericTargetAsmInfo(*this); 99 } 100} 101 102 103// Pass Pipeline Configuration 104bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM, 105 CodeGenOpt::Level OptLevel) { 106 PM.add(createARMISelDag(*this)); 107 return false; 108} 109 110bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM, 111 CodeGenOpt::Level OptLevel) { 112 // FIXME: temporarily disabling load / store optimization pass for Thumb mode. 113 if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb()) 114 PM.add(createARMLoadStoreOptimizationPass(true)); 115 return true; 116} 117 118bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM, 119 CodeGenOpt::Level OptLevel) { 120 // FIXME: temporarily disabling load / store optimization pass for Thumb mode. 121 if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb()) 122 PM.add(createARMLoadStoreOptimizationPass()); 123 124 if (OptLevel != CodeGenOpt::None && 125 !DisableIfConversion && !Subtarget.isThumb()) 126 PM.add(createIfConverterPass()); 127 128 if (Subtarget.isThumb2()) 129 PM.add(createThumb2ITBlockPass()); 130 131 PM.add(createARMConstantIslandPass()); 132 return true; 133} 134 135bool ARMBaseTargetMachine::addAssemblyEmitter(PassManagerBase &PM, 136 CodeGenOpt::Level OptLevel, 137 bool Verbose, 138 formatted_raw_ostream &Out) { 139 // Output assembly language. 140 assert(AsmPrinterCtor && "AsmPrinter was not linked in"); 141 if (AsmPrinterCtor) 142 PM.add(AsmPrinterCtor(Out, *this, Verbose)); 143 144 return false; 145} 146 147 148bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 149 CodeGenOpt::Level OptLevel, 150 bool DumpAsm, 151 MachineCodeEmitter &MCE) { 152 // FIXME: Move this to TargetJITInfo! 153 if (DefRelocModel == Reloc::Default) 154 setRelocationModel(Reloc::Static); 155 156 // Machine code emitter pass for ARM. 157 PM.add(createARMCodeEmitterPass(*this, MCE)); 158 if (DumpAsm) { 159 assert(AsmPrinterCtor && "AsmPrinter was not linked in"); 160 if (AsmPrinterCtor) 161 PM.add(AsmPrinterCtor(ferrs(), *this, true)); 162 } 163 164 return false; 165} 166 167bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 168 CodeGenOpt::Level OptLevel, 169 bool DumpAsm, 170 JITCodeEmitter &JCE) { 171 // FIXME: Move this to TargetJITInfo! 172 if (DefRelocModel == Reloc::Default) 173 setRelocationModel(Reloc::Static); 174 175 // Machine code emitter pass for ARM. 176 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 177 if (DumpAsm) { 178 assert(AsmPrinterCtor && "AsmPrinter was not linked in"); 179 if (AsmPrinterCtor) 180 PM.add(AsmPrinterCtor(ferrs(), *this, true)); 181 } 182 183 return false; 184} 185 186bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 187 CodeGenOpt::Level OptLevel, 188 bool DumpAsm, 189 ObjectCodeEmitter &OCE) { 190 // FIXME: Move this to TargetJITInfo! 191 if (DefRelocModel == Reloc::Default) 192 setRelocationModel(Reloc::Static); 193 194 // Machine code emitter pass for ARM. 195 PM.add(createARMObjectCodeEmitterPass(*this, OCE)); 196 if (DumpAsm) { 197 assert(AsmPrinterCtor && "AsmPrinter was not linked in"); 198 if (AsmPrinterCtor) 199 PM.add(AsmPrinterCtor(ferrs(), *this, true)); 200 } 201 202 return false; 203} 204 205bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, 206 CodeGenOpt::Level OptLevel, 207 bool DumpAsm, 208 MachineCodeEmitter &MCE) { 209 // Machine code emitter pass for ARM. 210 PM.add(createARMCodeEmitterPass(*this, MCE)); 211 if (DumpAsm) { 212 assert(AsmPrinterCtor && "AsmPrinter was not linked in"); 213 if (AsmPrinterCtor) 214 PM.add(AsmPrinterCtor(ferrs(), *this, true)); 215 } 216 217 return false; 218} 219 220bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, 221 CodeGenOpt::Level OptLevel, 222 bool DumpAsm, 223 JITCodeEmitter &JCE) { 224 // Machine code emitter pass for ARM. 225 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 226 if (DumpAsm) { 227 assert(AsmPrinterCtor && "AsmPrinter was not linked in"); 228 if (AsmPrinterCtor) 229 PM.add(AsmPrinterCtor(ferrs(), *this, true)); 230 } 231 232 return false; 233} 234 235bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, 236 CodeGenOpt::Level OptLevel, 237 bool DumpAsm, 238 ObjectCodeEmitter &OCE) { 239 // Machine code emitter pass for ARM. 240 PM.add(createARMObjectCodeEmitterPass(*this, OCE)); 241 if (DumpAsm) { 242 assert(AsmPrinterCtor && "AsmPrinter was not linked in"); 243 if (AsmPrinterCtor) 244 PM.add(AsmPrinterCtor(ferrs(), *this, true)); 245 } 246 247 return false; 248} 249 250