Move ARMSelectionDAGInfo from the TargetMachine to the subtarget.
[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 "ARM.h"
14 #include "ARMTargetMachine.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 DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
28                    cl::desc("Inhibit optimization of S->D register accesses on A15"),
29                    cl::init(false));
30
31 static cl::opt<bool>
32 EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden,
33                  cl::desc("Run SimplifyCFG after expanding atomic operations"
34                           " to make use of cmpxchg flow-based information"),
35                  cl::init(true));
36
37 extern "C" void LLVMInitializeARMTarget() {
38   // Register the target.
39   RegisterTargetMachine<ARMLETargetMachine> X(TheARMLETarget);
40   RegisterTargetMachine<ARMBETargetMachine> Y(TheARMBETarget);
41   RegisterTargetMachine<ThumbLETargetMachine> A(TheThumbLETarget);
42   RegisterTargetMachine<ThumbBETargetMachine> B(TheThumbBETarget);
43 }
44
45
46 /// TargetMachine ctor - Create an ARM architecture model.
47 ///
48 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
49                                            StringRef CPU, StringRef FS,
50                                            const TargetOptions &Options,
51                                            Reloc::Model RM, CodeModel::Model CM,
52                                            CodeGenOpt::Level OL,
53                                            bool isLittle)
54   : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
55     Subtarget(TT, CPU, FS, isLittle, Options),
56     JITInfo(),
57     InstrItins(Subtarget.getInstrItineraryData()) {
58
59   // Default to triple-appropriate float ABI
60   if (Options.FloatABIType == FloatABI::Default)
61     this->Options.FloatABIType =
62         Subtarget.isTargetHardFloat() ? FloatABI::Hard : FloatABI::Soft;
63 }
64
65 void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
66   // Add first the target-independent BasicTTI pass, then our ARM pass. This
67   // allows the ARM pass to delegate to the target independent layer when
68   // appropriate.
69   PM.add(createBasicTargetTransformInfoPass(this));
70   PM.add(createARMTargetTransformInfoPass(this));
71 }
72
73
74 void ARMTargetMachine::anchor() { }
75
76 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
77                                    StringRef CPU, StringRef FS,
78                                    const TargetOptions &Options,
79                                    Reloc::Model RM, CodeModel::Model CM,
80                                    CodeGenOpt::Level OL,
81                                    bool isLittle)
82   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle),
83     InstrInfo(Subtarget),
84     TLInfo(*this),
85     FrameLowering(Subtarget) {
86   initAsmInfo();
87   if (!Subtarget.hasARMOps())
88     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
89                        "support ARM mode execution!");
90 }
91
92 void ARMLETargetMachine::anchor() { }
93
94 ARMLETargetMachine::
95 ARMLETargetMachine(const Target &T, StringRef TT,
96                        StringRef CPU, StringRef FS, const TargetOptions &Options,
97                        Reloc::Model RM, CodeModel::Model CM,
98                        CodeGenOpt::Level OL)
99   : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
100
101 void ARMBETargetMachine::anchor() { }
102
103 ARMBETargetMachine::
104 ARMBETargetMachine(const Target &T, StringRef TT,
105                        StringRef CPU, StringRef FS, const TargetOptions &Options,
106                        Reloc::Model RM, CodeModel::Model CM,
107                        CodeGenOpt::Level OL)
108   : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
109
110 void ThumbTargetMachine::anchor() { }
111
112 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
113                                        StringRef CPU, StringRef FS,
114                                        const TargetOptions &Options,
115                                        Reloc::Model RM, CodeModel::Model CM,
116                                        CodeGenOpt::Level OL,
117                                        bool isLittle)
118   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle),
119     InstrInfo(Subtarget.hasThumb2()
120               ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
121               : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
122     TLInfo(*this),
123     FrameLowering(Subtarget.hasThumb2()
124               ? new ARMFrameLowering(Subtarget)
125               : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
126   initAsmInfo();
127 }
128
129 void ThumbLETargetMachine::anchor() { }
130
131 ThumbLETargetMachine::
132 ThumbLETargetMachine(const Target &T, StringRef TT,
133                        StringRef CPU, StringRef FS, const TargetOptions &Options,
134                        Reloc::Model RM, CodeModel::Model CM,
135                        CodeGenOpt::Level OL)
136   : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
137
138 void ThumbBETargetMachine::anchor() { }
139
140 ThumbBETargetMachine::
141 ThumbBETargetMachine(const Target &T, StringRef TT,
142                        StringRef CPU, StringRef FS, const TargetOptions &Options,
143                        Reloc::Model RM, CodeModel::Model CM,
144                        CodeGenOpt::Level OL)
145   : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
146
147 namespace {
148 /// ARM Code Generator Pass Configuration Options.
149 class ARMPassConfig : public TargetPassConfig {
150 public:
151   ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
152     : TargetPassConfig(TM, PM) {}
153
154   ARMBaseTargetMachine &getARMTargetMachine() const {
155     return getTM<ARMBaseTargetMachine>();
156   }
157
158   const ARMSubtarget &getARMSubtarget() const {
159     return *getARMTargetMachine().getSubtargetImpl();
160   }
161
162   void addIRPasses() override;
163   bool addPreISel() override;
164   bool addInstSelector() override;
165   bool addPreRegAlloc() override;
166   bool addPreSched2() override;
167   bool addPreEmitPass() override;
168 };
169 } // namespace
170
171 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
172   return new ARMPassConfig(this, PM);
173 }
174
175 void ARMPassConfig::addIRPasses() {
176   const ARMSubtarget *Subtarget = &getARMSubtarget();
177   if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only()) {
178     addPass(createAtomicExpandLoadLinkedPass(TM));
179
180     // Cmpxchg instructions are often used with a subsequent comparison to
181     // determine whether it succeeded. We can exploit existing control-flow in
182     // ldrex/strex loops to simplify this, but it needs tidying up.
183     if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
184       addPass(createCFGSimplificationPass());
185   }
186
187   TargetPassConfig::addIRPasses();
188 }
189
190 bool ARMPassConfig::addPreISel() {
191   if (TM->getOptLevel() != CodeGenOpt::None)
192     addPass(createGlobalMergePass(TM));
193
194   return false;
195 }
196
197 bool ARMPassConfig::addInstSelector() {
198   addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
199
200   const ARMSubtarget *Subtarget = &getARMSubtarget();
201   if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
202       TM->Options.EnableFastISel)
203     addPass(createARMGlobalBaseRegPass());
204   return false;
205 }
206
207 bool ARMPassConfig::addPreRegAlloc() {
208   // FIXME: Temporarily disabling Thumb-1 pre-RA Load/Store optimization pass
209   if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
210     addPass(createARMLoadStoreOptimizationPass(true));
211   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
212     addPass(createMLxExpansionPass());
213   // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
214   // enabled when NEON is available.
215   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() &&
216     getARMSubtarget().hasNEON() && !DisableA15SDOptimization) {
217     addPass(createA15SDOptimizerPass());
218   }
219   return true;
220 }
221
222 bool ARMPassConfig::addPreSched2() {
223   if (getOptLevel() != CodeGenOpt::None) {
224     // FIXME: Temporarily disabling Thumb-1 post-RA Load/Store optimization pass
225     if (!getARMSubtarget().isThumb1Only()) {
226       addPass(createARMLoadStoreOptimizationPass());
227       printAndVerify("After ARM load / store optimizer");
228     }
229
230     if (getARMSubtarget().hasNEON())
231       addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
232   }
233
234   // Expand some pseudo instructions into multiple instructions to allow
235   // proper scheduling.
236   addPass(createARMExpandPseudoPass());
237
238   if (getOptLevel() != CodeGenOpt::None) {
239     if (!getARMSubtarget().isThumb1Only()) {
240       // in v8, IfConversion depends on Thumb instruction widths
241       if (getARMSubtarget().restrictIT() &&
242           !getARMSubtarget().prefers32BitThumb())
243         addPass(createThumb2SizeReductionPass());
244       addPass(&IfConverterID);
245     }
246   }
247   if (getARMSubtarget().isThumb2())
248     addPass(createThumb2ITBlockPass());
249
250   return true;
251 }
252
253 bool ARMPassConfig::addPreEmitPass() {
254   if (getARMSubtarget().isThumb2()) {
255     if (!getARMSubtarget().prefers32BitThumb())
256       addPass(createThumb2SizeReductionPass());
257
258     // Constant island pass work on unbundled instructions.
259     addPass(&UnpackMachineBundlesID);
260   }
261
262   addPass(createARMOptimizeBarriersPass());
263   addPass(createARMConstantIslandPass());
264
265   return true;
266 }
267
268 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
269                                           JITCodeEmitter &JCE) {
270   // Machine code emitter pass for ARM.
271   PM.add(createARMJITCodeEmitterPass(*this, JCE));
272   return false;
273 }