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