ARMTargetMachine.cpp revision ddfd1377d2e4154d44dc3ad217735adc15af2e3f
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 "ARMFrameLowering.h"
15#include "ARM.h"
16#include "llvm/PassManager.h"
17#include "llvm/CodeGen/Passes.h"
18#include "llvm/MC/MCAsmInfo.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
31extern "C" void LLVMInitializeARMTarget() {
32  // Register the target.
33  RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
34  RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
35}
36
37/// TargetMachine ctor - Create an ARM architecture model.
38///
39ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
40                                           StringRef CPU, StringRef FS,
41                                           const TargetOptions &Options,
42                                           Reloc::Model RM, CodeModel::Model CM,
43                                           CodeGenOpt::Level OL)
44  : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
45    Subtarget(TT, CPU, FS),
46    JITInfo(),
47    InstrItins(Subtarget.getInstrItineraryData()) {
48  // Default to soft float ABI
49  if (Options.FloatABIType == FloatABI::Default)
50    this->Options.FloatABIType = FloatABI::Soft;
51}
52
53ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
54                                   StringRef CPU, StringRef FS,
55                                   const TargetOptions &Options,
56                                   Reloc::Model RM, CodeModel::Model CM,
57                                   CodeGenOpt::Level OL)
58  : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
59    InstrInfo(Subtarget),
60    DataLayout(Subtarget.isAPCS_ABI() ?
61               std::string("e-p:32:32-f64:32:64-i64:32:64-"
62                           "v128:32:128-v64:32:64-n32-S32") :
63               Subtarget.isAAPCS_ABI() ?
64               std::string("e-p:32:32-f64:64:64-i64:64:64-"
65                           "v128:64:128-v64:64:64-n32-S64") :
66               std::string("e-p:32:32-f64:64:64-i64:64:64-"
67                           "v128:64:128-v64:64:64-n32-S32")),
68    ELFWriterInfo(*this),
69    TLInfo(*this),
70    TSInfo(*this),
71    FrameLowering(Subtarget) {
72  if (!Subtarget.hasARMOps())
73    report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
74                       "support ARM mode execution!");
75}
76
77ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
78                                       StringRef CPU, StringRef FS,
79                                       const TargetOptions &Options,
80                                       Reloc::Model RM, CodeModel::Model CM,
81                                       CodeGenOpt::Level OL)
82  : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
83    InstrInfo(Subtarget.hasThumb2()
84              ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
85              : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
86    DataLayout(Subtarget.isAPCS_ABI() ?
87               std::string("e-p:32:32-f64:32:64-i64:32:64-"
88                           "i16:16:32-i8:8:32-i1:8:32-"
89                           "v128:32:128-v64:32:64-a:0:32-n32-S32") :
90               Subtarget.isAAPCS_ABI() ?
91               std::string("e-p:32:32-f64:64:64-i64:64:64-"
92                           "i16:16:32-i8:8:32-i1:8:32-"
93                           "v128:64:128-v64:64:64-a:0:32-n32-S64") :
94               std::string("e-p:32:32-f64:64:64-i64:64:64-"
95                           "i16:16:32-i8:8:32-i1:8:32-"
96                           "v128:64:128-v64:64:64-a:0:32-n32-S32")),
97    ELFWriterInfo(*this),
98    TLInfo(*this),
99    TSInfo(*this),
100    FrameLowering(Subtarget.hasThumb2()
101              ? new ARMFrameLowering(Subtarget)
102              : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
103}
104
105bool ARMBaseTargetMachine::addPreISel(PassManagerBase &PM) {
106  if (getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
107    PM.add(createGlobalMergePass(getTargetLowering()));
108
109  return false;
110}
111
112bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM) {
113  PM.add(createARMISelDag(*this, getOptLevel()));
114  return false;
115}
116
117bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM) {
118  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
119  if (getOptLevel() != CodeGenOpt::None && !Subtarget.isThumb1Only())
120    PM.add(createARMLoadStoreOptimizationPass(true));
121  if (getOptLevel() != CodeGenOpt::None && Subtarget.isCortexA9())
122    PM.add(createMLxExpansionPass());
123  return true;
124}
125
126bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM) {
127  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
128  if (getOptLevel() != CodeGenOpt::None) {
129    if (!Subtarget.isThumb1Only())
130      PM.add(createARMLoadStoreOptimizationPass());
131    if (Subtarget.hasNEON())
132      PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass));
133  }
134
135  // Expand some pseudo instructions into multiple instructions to allow
136  // proper scheduling.
137  PM.add(createARMExpandPseudoPass());
138
139  if (getOptLevel() != CodeGenOpt::None) {
140    if (!Subtarget.isThumb1Only())
141      PM.add(createIfConverterPass());
142  }
143  if (Subtarget.isThumb2())
144    PM.add(createThumb2ITBlockPass());
145
146  return true;
147}
148
149bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM) {
150  if (Subtarget.isThumb2()) {
151    if (!Subtarget.prefers32BitThumb())
152      PM.add(createThumb2SizeReductionPass());
153
154    // Constant island pass work on unbundled instructions.
155    PM.add(createUnpackMachineBundlesPass());
156  }
157
158  PM.add(createARMConstantIslandPass());
159
160  return true;
161}
162
163bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
164                                          JITCodeEmitter &JCE) {
165  // Machine code emitter pass for ARM.
166  PM.add(createARMJITCodeEmitterPass(*this, JCE));
167  return false;
168}
169