One last cleanup of LLVM's DataLayout strings.
[oota-llvm.git] / lib / Target / ARM / ARMTargetMachine.cpp
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 "ARM.h"
15 #include "ARMFrameLowering.h"
16 #include "llvm/CodeGen/Passes.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/PassManager.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"
24 using namespace llvm;
25
26 static cl::opt<bool>
27 EnableGlobalMerge("global-merge", cl::Hidden,
28                   cl::desc("Enable global merge pass"),
29                   cl::init(true));
30
31 static cl::opt<bool>
32 DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
33                    cl::desc("Inhibit optimization of S->D register accesses on A15"),
34                    cl::init(false));
35
36 extern "C" void LLVMInitializeARMTarget() {
37   // Register the target.
38   RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
39   RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
40 }
41
42
43 /// TargetMachine ctor - Create an ARM architecture model.
44 ///
45 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
46                                            StringRef CPU, StringRef FS,
47                                            const TargetOptions &Options,
48                                            Reloc::Model RM, CodeModel::Model CM,
49                                            CodeGenOpt::Level OL)
50   : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
51     Subtarget(TT, CPU, FS, Options),
52     JITInfo(),
53     InstrItins(Subtarget.getInstrItineraryData()) {
54   // Default to soft float ABI
55   if (Options.FloatABIType == FloatABI::Default)
56     this->Options.FloatABIType = FloatABI::Soft;
57 }
58
59 void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
60   // Add first the target-independent BasicTTI pass, then our ARM pass. This
61   // allows the ARM pass to delegate to the target independent layer when
62   // appropriate.
63   PM.add(createBasicTargetTransformInfoPass(this));
64   PM.add(createARMTargetTransformInfoPass(this));
65 }
66
67
68 void ARMTargetMachine::anchor() { }
69
70 static std::string computeDataLayout(ARMSubtarget &ST) {
71   // Little endian. Pointers are 32 bits and aligned to 32 bits.
72   std::string Ret = "e-p:32:32";
73
74   // On thumb, i16,i18 and i1 have natural aligment requirements, but we try to
75   // align to 32.
76   if (ST.isThumb())
77     Ret += "-i1:8:32-i8:8:32-i16:16:32";
78
79   // We have 64 bits floats and integers. The APCS ABI requires them to be
80   // aligned s them to 32 bits, others to 64 bits. We always try to align to
81   // 64 bits.
82   if (ST.isAPCS_ABI())
83     Ret += "-f64:32:64";
84   else
85     Ret += "-i64:64";
86
87   // We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others
88   // to 64. We always ty to give them natural alignment.
89   if (ST.isAPCS_ABI())
90     Ret += "-v64:32:64-v128:32:128";
91   else
92     Ret += "-v128:64:128";
93
94   // An aggregate of size 0 is ABI aligned to 0.
95   // FIXME: explain better what this means.
96   if (ST.isThumb())
97     Ret += "-a:0:32";
98
99   // Integer registers are 32 bits.
100   Ret += "-n32";
101
102   // The stack is 64 bit aligned on AAPCS and 32 bit aligned everywhere else.
103   if (ST.isAAPCS_ABI())
104     Ret += "-S64";
105   else
106     Ret += "-S32";
107
108   return Ret;
109 }
110
111 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
112                                    StringRef CPU, StringRef FS,
113                                    const TargetOptions &Options,
114                                    Reloc::Model RM, CodeModel::Model CM,
115                                    CodeGenOpt::Level OL)
116   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
117     InstrInfo(Subtarget),
118     DL(computeDataLayout(Subtarget)),
119     TLInfo(*this),
120     TSInfo(*this),
121     FrameLowering(Subtarget) {
122   initAsmInfo();
123   if (!Subtarget.hasARMOps())
124     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
125                        "support ARM mode execution!");
126 }
127
128 void ThumbTargetMachine::anchor() { }
129
130 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
131                                        StringRef CPU, StringRef FS,
132                                        const TargetOptions &Options,
133                                        Reloc::Model RM, CodeModel::Model CM,
134                                        CodeGenOpt::Level OL)
135   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
136     InstrInfo(Subtarget.hasThumb2()
137               ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
138               : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
139     DL(computeDataLayout(Subtarget)),
140     TLInfo(*this),
141     TSInfo(*this),
142     FrameLowering(Subtarget.hasThumb2()
143               ? new ARMFrameLowering(Subtarget)
144               : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
145   initAsmInfo();
146 }
147
148 namespace {
149 /// ARM Code Generator Pass Configuration Options.
150 class ARMPassConfig : public TargetPassConfig {
151 public:
152   ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
153     : TargetPassConfig(TM, PM) {}
154
155   ARMBaseTargetMachine &getARMTargetMachine() const {
156     return getTM<ARMBaseTargetMachine>();
157   }
158
159   const ARMSubtarget &getARMSubtarget() const {
160     return *getARMTargetMachine().getSubtargetImpl();
161   }
162
163   virtual bool addPreISel();
164   virtual bool addInstSelector();
165   virtual bool addPreRegAlloc();
166   virtual bool addPreSched2();
167   virtual bool addPreEmitPass();
168 };
169 } // namespace
170
171 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
172   return new ARMPassConfig(this, PM);
173 }
174
175 bool ARMPassConfig::addPreISel() {
176   if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
177     addPass(createGlobalMergePass(TM));
178
179   return false;
180 }
181
182 bool ARMPassConfig::addInstSelector() {
183   addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
184
185   const ARMSubtarget *Subtarget = &getARMSubtarget();
186   if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
187       TM->Options.EnableFastISel)
188     addPass(createARMGlobalBaseRegPass());
189   return false;
190 }
191
192 bool ARMPassConfig::addPreRegAlloc() {
193   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
194   if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
195     addPass(createARMLoadStoreOptimizationPass(true));
196   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
197     addPass(createMLxExpansionPass());
198   // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
199   // enabled when NEON is available.
200   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() &&
201     getARMSubtarget().hasNEON() && !DisableA15SDOptimization) {
202     addPass(createA15SDOptimizerPass());
203   }
204   return true;
205 }
206
207 bool ARMPassConfig::addPreSched2() {
208   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
209   if (getOptLevel() != CodeGenOpt::None) {
210     if (!getARMSubtarget().isThumb1Only()) {
211       addPass(createARMLoadStoreOptimizationPass());
212       printAndVerify("After ARM load / store optimizer");
213     }
214     if (getARMSubtarget().hasNEON())
215       addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
216   }
217
218   // Expand some pseudo instructions into multiple instructions to allow
219   // proper scheduling.
220   addPass(createARMExpandPseudoPass());
221
222   if (getOptLevel() != CodeGenOpt::None) {
223     if (!getARMSubtarget().isThumb1Only()) {
224       // in v8, IfConversion depends on Thumb instruction widths
225       if (getARMSubtarget().restrictIT() &&
226           !getARMSubtarget().prefers32BitThumb())
227         addPass(createThumb2SizeReductionPass());
228       addPass(&IfConverterID);
229     }
230   }
231   if (getARMSubtarget().isThumb2())
232     addPass(createThumb2ITBlockPass());
233
234   return true;
235 }
236
237 bool ARMPassConfig::addPreEmitPass() {
238   if (getARMSubtarget().isThumb2()) {
239     if (!getARMSubtarget().prefers32BitThumb())
240       addPass(createThumb2SizeReductionPass());
241
242     // Constant island pass work on unbundled instructions.
243     addPass(&UnpackMachineBundlesID);
244   }
245
246   addPass(createARMConstantIslandPass());
247
248   return true;
249 }
250
251 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
252                                           JITCodeEmitter &JCE) {
253   // Machine code emitter pass for ARM.
254   PM.add(createARMJITCodeEmitterPass(*this, JCE));
255   return false;
256 }