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