ARMTargetMachine.cpp revision a67240399316f42d0da235053c77d71e6204f21f
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 "ARMMCAsmInfo.h" 15#include "ARMFrameInfo.h" 16#include "ARM.h" 17#include "llvm/PassManager.h" 18#include "llvm/CodeGen/Passes.h" 19#include "llvm/Support/CommandLine.h" 20#include "llvm/Support/FormattedStream.h" 21#include "llvm/Target/TargetOptions.h" 22#include "llvm/Target/TargetRegistry.h" 23using namespace llvm; 24 25static cl::opt<bool> DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden, 26 cl::desc("Disable load store optimization pass")); 27static cl::opt<bool> DisableIfConversion("disable-arm-if-conversion",cl::Hidden, 28 cl::desc("Disable if-conversion pass")); 29 30static const MCAsmInfo *createMCAsmInfo(const Target &T, 31 const StringRef &TT) { 32 Triple TheTriple(TT); 33 switch (TheTriple.getOS()) { 34 case Triple::Darwin: 35 return new ARMMCAsmInfoDarwin(); 36 default: 37 return new ARMELFMCAsmInfo(); 38 } 39} 40 41 42extern "C" void LLVMInitializeARMTarget() { 43 // Register the target. 44 RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget); 45 RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget); 46 47 // Register the target asm info. 48 RegisterAsmInfoFn A(TheARMTarget, createMCAsmInfo); 49 RegisterAsmInfoFn B(TheThumbTarget, createMCAsmInfo); 50} 51 52/// TargetMachine ctor - Create an ARM architecture model. 53/// 54ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, 55 const std::string &TT, 56 const std::string &FS, 57 bool isThumb) 58 : LLVMTargetMachine(T, TT), 59 Subtarget(TT, FS, isThumb), 60 FrameInfo(Subtarget), 61 JITInfo(), 62 InstrItins(Subtarget.getInstrItineraryData()) { 63 DefRelocModel = getRelocationModel(); 64} 65 66ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT, 67 const std::string &FS) 68 : ARMBaseTargetMachine(T, TT, FS, false), InstrInfo(Subtarget), 69 DataLayout(Subtarget.isAPCS_ABI() ? 70 std::string("e-p:32:32-f64:32:32-i64:32:32") : 71 std::string("e-p:32:32-f64:64:64-i64:64:64")), 72 TLInfo(*this) { 73} 74 75ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT, 76 const std::string &FS) 77 : ARMBaseTargetMachine(T, TT, FS, true), 78 InstrInfo(Subtarget.hasThumb2() 79 ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget)) 80 : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))), 81 DataLayout(Subtarget.isAPCS_ABI() ? 82 std::string("e-p:32:32-f64:32:32-i64:32:32-" 83 "i16:16:32-i8:8:32-i1:8:32-a:0:32") : 84 std::string("e-p:32:32-f64:64:64-i64:64:64-" 85 "i16:16:32-i8:8:32-i1:8:32-a:0:32")), 86 TLInfo(*this) { 87} 88 89 90 91// Pass Pipeline Configuration 92bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM, 93 CodeGenOpt::Level OptLevel) { 94 PM.add(createARMISelDag(*this)); 95 return false; 96} 97 98bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM, 99 CodeGenOpt::Level OptLevel) { 100 if (Subtarget.hasNEON()) 101 PM.add(createNEONPreAllocPass()); 102 103 // FIXME: temporarily disabling load / store optimization pass for Thumb mode. 104 if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb()) 105 PM.add(createARMLoadStoreOptimizationPass(true)); 106 return true; 107} 108 109bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM, 110 CodeGenOpt::Level OptLevel) { 111 // FIXME: temporarily disabling load / store optimization pass for Thumb1 mode. 112 if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && 113 !Subtarget.isThumb1Only()) 114 PM.add(createARMLoadStoreOptimizationPass()); 115 116 if (OptLevel != CodeGenOpt::None && 117 !DisableIfConversion && !Subtarget.isThumb1Only()) 118 PM.add(createIfConverterPass()); 119 120 if (Subtarget.isThumb2()) { 121 PM.add(createThumb2ITBlockPass()); 122 PM.add(createThumb2SizeReductionPass()); 123 } 124 125 PM.add(createARMConstantIslandPass()); 126 return true; 127} 128 129bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 130 CodeGenOpt::Level OptLevel, 131 MachineCodeEmitter &MCE) { 132 // FIXME: Move this to TargetJITInfo! 133 if (DefRelocModel == Reloc::Default) 134 setRelocationModel(Reloc::Static); 135 136 // Machine code emitter pass for ARM. 137 PM.add(createARMCodeEmitterPass(*this, MCE)); 138 return false; 139} 140 141bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 142 CodeGenOpt::Level OptLevel, 143 JITCodeEmitter &JCE) { 144 // FIXME: Move this to TargetJITInfo! 145 if (DefRelocModel == Reloc::Default) 146 setRelocationModel(Reloc::Static); 147 148 // Machine code emitter pass for ARM. 149 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 150 return false; 151} 152 153bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, 154 CodeGenOpt::Level OptLevel, 155 ObjectCodeEmitter &OCE) { 156 // FIXME: Move this to TargetJITInfo! 157 if (DefRelocModel == Reloc::Default) 158 setRelocationModel(Reloc::Static); 159 160 // Machine code emitter pass for ARM. 161 PM.add(createARMObjectCodeEmitterPass(*this, OCE)); 162 return false; 163} 164 165bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, 166 CodeGenOpt::Level OptLevel, 167 MachineCodeEmitter &MCE) { 168 // Machine code emitter pass for ARM. 169 PM.add(createARMCodeEmitterPass(*this, MCE)); 170 return false; 171} 172 173bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, 174 CodeGenOpt::Level OptLevel, 175 JITCodeEmitter &JCE) { 176 // Machine code emitter pass for ARM. 177 PM.add(createARMJITCodeEmitterPass(*this, JCE)); 178 return false; 179} 180 181bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, 182 CodeGenOpt::Level OptLevel, 183 ObjectCodeEmitter &OCE) { 184 // Machine code emitter pass for ARM. 185 PM.add(createARMObjectCodeEmitterPass(*this, OCE)); 186 return false; 187} 188 189