This patch changes the ownership of TLOF from TargetLoweringBase to TargetMachine...
[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 "ARMTargetObjectFile.h"
17 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/PassManager.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/FormattedStream.h"
23 #include "llvm/Support/TargetRegistry.h"
24 #include "llvm/Target/TargetOptions.h"
25 #include "llvm/Transforms/Scalar.h"
26 using namespace llvm;
27
28 static cl::opt<bool>
29 DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
30                    cl::desc("Inhibit optimization of S->D register accesses on A15"),
31                    cl::init(false));
32
33 static cl::opt<bool>
34 EnableAtomicTidy("arm-atomic-cfg-tidy", cl::Hidden,
35                  cl::desc("Run SimplifyCFG after expanding atomic operations"
36                           " to make use of cmpxchg flow-based information"),
37                  cl::init(true));
38
39 extern "C" void LLVMInitializeARMTarget() {
40   // Register the target.
41   RegisterTargetMachine<ARMLETargetMachine> X(TheARMLETarget);
42   RegisterTargetMachine<ARMBETargetMachine> Y(TheARMBETarget);
43   RegisterTargetMachine<ThumbLETargetMachine> A(TheThumbLETarget);
44   RegisterTargetMachine<ThumbBETargetMachine> B(TheThumbBETarget);
45 }
46
47 static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
48   if (TT.isOSBinFormatMachO())
49     return make_unique<TargetLoweringObjectFileMachO>();
50   if (TT.isOSWindows())
51     return make_unique<TargetLoweringObjectFileCOFF>();
52   return make_unique<ARMElfTargetObjectFile>();
53 }
54
55 /// TargetMachine ctor - Create an ARM architecture model.
56 ///
57 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
58                                            StringRef CPU, StringRef FS,
59                                            const TargetOptions &Options,
60                                            Reloc::Model RM, CodeModel::Model CM,
61                                            CodeGenOpt::Level OL, bool isLittle)
62     : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
63       TLOF(createTLOF(Triple(getTargetTriple()))),
64       Subtarget(TT, CPU, FS, *this, isLittle), isLittle(isLittle) {
65
66   // Default to triple-appropriate float ABI
67   if (Options.FloatABIType == FloatABI::Default)
68     this->Options.FloatABIType =
69         Subtarget.isTargetHardFloat() ? FloatABI::Hard : FloatABI::Soft;
70 }
71
72 const ARMSubtarget *
73 ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
74   AttributeSet FnAttrs = F.getAttributes();
75   Attribute CPUAttr =
76       FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu");
77   Attribute FSAttr =
78       FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features");
79
80   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
81                         ? CPUAttr.getValueAsString().str()
82                         : TargetCPU;
83   std::string FS = !FSAttr.hasAttribute(Attribute::None)
84                        ? FSAttr.getValueAsString().str()
85                        : TargetFS;
86
87   // FIXME: This is related to the code below to reset the target options,
88   // we need to know whether or not the soft float flag is set on the
89   // function before we can generate a subtarget. We also need to use
90   // it as a key for the subtarget since that can be the only difference
91   // between two functions.
92   Attribute SFAttr =
93       FnAttrs.getAttribute(AttributeSet::FunctionIndex, "use-soft-float");
94   bool SoftFloat = !SFAttr.hasAttribute(Attribute::None)
95                        ? SFAttr.getValueAsString() == "true"
96                        : Options.UseSoftFloat;
97
98   auto &I = SubtargetMap[CPU + FS + (SoftFloat ? "use-soft-float=true"
99                                                : "use-soft-float=false")];
100   if (!I) {
101     // This needs to be done before we create a new subtarget since any
102     // creation will depend on the TM and the code generation flags on the
103     // function that reside in TargetOptions.
104     resetTargetOptions(F);
105     I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle);
106   }
107   return I.get();
108 }
109
110 void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
111   // Add first the target-independent BasicTTI pass, then our ARM pass. This
112   // allows the ARM pass to delegate to the target independent layer when
113   // appropriate.
114   PM.add(createBasicTargetTransformInfoPass(this));
115   PM.add(createARMTargetTransformInfoPass(this));
116 }
117
118
119 void ARMTargetMachine::anchor() { }
120
121 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT, StringRef CPU,
122                                    StringRef FS, const TargetOptions &Options,
123                                    Reloc::Model RM, CodeModel::Model CM,
124                                    CodeGenOpt::Level OL, bool isLittle)
125     : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, isLittle) {
126   initAsmInfo();
127   if (!Subtarget.hasARMOps())
128     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
129                        "support ARM mode execution!");
130 }
131
132 void ARMLETargetMachine::anchor() { }
133
134 ARMLETargetMachine::ARMLETargetMachine(const Target &T, StringRef TT,
135                                        StringRef CPU, StringRef FS,
136                                        const TargetOptions &Options,
137                                        Reloc::Model RM, CodeModel::Model CM,
138                                        CodeGenOpt::Level OL)
139     : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
140
141 void ARMBETargetMachine::anchor() { }
142
143 ARMBETargetMachine::ARMBETargetMachine(const Target &T, StringRef TT,
144                                        StringRef CPU, StringRef FS,
145                                        const TargetOptions &Options,
146                                        Reloc::Model RM, CodeModel::Model CM,
147                                        CodeGenOpt::Level OL)
148     : ARMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
149
150 void ThumbTargetMachine::anchor() { }
151
152 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
153                                        StringRef CPU, StringRef FS,
154                                        const TargetOptions &Options,
155                                        Reloc::Model RM, CodeModel::Model CM,
156                                        CodeGenOpt::Level OL, bool isLittle)
157     : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL,
158                            isLittle) {
159   initAsmInfo();
160 }
161
162 void ThumbLETargetMachine::anchor() { }
163
164 ThumbLETargetMachine::ThumbLETargetMachine(const Target &T, StringRef TT,
165                                            StringRef CPU, StringRef FS,
166                                            const TargetOptions &Options,
167                                            Reloc::Model RM, CodeModel::Model CM,
168                                            CodeGenOpt::Level OL)
169     : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
170
171 void ThumbBETargetMachine::anchor() { }
172
173 ThumbBETargetMachine::ThumbBETargetMachine(const Target &T, StringRef TT,
174                                            StringRef CPU, StringRef FS,
175                                            const TargetOptions &Options,
176                                            Reloc::Model RM, CodeModel::Model CM,
177                                            CodeGenOpt::Level OL)
178     : ThumbTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
179
180 namespace {
181 /// ARM Code Generator Pass Configuration Options.
182 class ARMPassConfig : public TargetPassConfig {
183 public:
184   ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
185     : TargetPassConfig(TM, PM) {}
186
187   ARMBaseTargetMachine &getARMTargetMachine() const {
188     return getTM<ARMBaseTargetMachine>();
189   }
190
191   const ARMSubtarget &getARMSubtarget() const {
192     return *getARMTargetMachine().getSubtargetImpl();
193   }
194
195   void addIRPasses() override;
196   bool addPreISel() override;
197   bool addInstSelector() override;
198   bool addPreRegAlloc() override;
199   bool addPreSched2() override;
200   bool addPreEmitPass() override;
201 };
202 } // namespace
203
204 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
205   return new ARMPassConfig(this, PM);
206 }
207
208 void ARMPassConfig::addIRPasses() {
209   if (TM->Options.ThreadModel == ThreadModel::Single)
210     addPass(createLowerAtomicPass());
211   else
212     addPass(createAtomicExpandPass(TM));
213
214   // Cmpxchg instructions are often used with a subsequent comparison to
215   // determine whether it succeeded. We can exploit existing control-flow in
216   // ldrex/strex loops to simplify this, but it needs tidying up.
217   const ARMSubtarget *Subtarget = &getARMSubtarget();
218   if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only())
219     if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
220       addPass(createCFGSimplificationPass());
221
222   TargetPassConfig::addIRPasses();
223 }
224
225 bool ARMPassConfig::addPreISel() {
226   if (TM->getOptLevel() != CodeGenOpt::None)
227     addPass(createGlobalMergePass(TM));
228
229   return false;
230 }
231
232 bool ARMPassConfig::addInstSelector() {
233   addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
234
235   const ARMSubtarget *Subtarget = &getARMSubtarget();
236   if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
237       TM->Options.EnableFastISel)
238     addPass(createARMGlobalBaseRegPass());
239   return false;
240 }
241
242 bool ARMPassConfig::addPreRegAlloc() {
243   if (getOptLevel() != CodeGenOpt::None)
244     addPass(createARMLoadStoreOptimizationPass(true));
245   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
246     addPass(createMLxExpansionPass());
247   // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
248   // enabled when NEON is available.
249   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() &&
250     getARMSubtarget().hasNEON() && !DisableA15SDOptimization) {
251     addPass(createA15SDOptimizerPass());
252   }
253   return true;
254 }
255
256 bool ARMPassConfig::addPreSched2() {
257   if (getOptLevel() != CodeGenOpt::None) {
258     addPass(createARMLoadStoreOptimizationPass());
259     printAndVerify("After ARM load / store optimizer");
260
261     if (getARMSubtarget().hasNEON())
262       addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
263   }
264
265   // Expand some pseudo instructions into multiple instructions to allow
266   // proper scheduling.
267   addPass(createARMExpandPseudoPass());
268
269   if (getOptLevel() != CodeGenOpt::None) {
270     if (!getARMSubtarget().isThumb1Only()) {
271       // in v8, IfConversion depends on Thumb instruction widths
272       if (getARMSubtarget().restrictIT() &&
273           !getARMSubtarget().prefers32BitThumb())
274         addPass(createThumb2SizeReductionPass());
275       addPass(&IfConverterID);
276     }
277   }
278   if (getARMSubtarget().isThumb2())
279     addPass(createThumb2ITBlockPass());
280
281   return true;
282 }
283
284 bool ARMPassConfig::addPreEmitPass() {
285   if (getARMSubtarget().isThumb2()) {
286     if (!getARMSubtarget().prefers32BitThumb())
287       addPass(createThumb2SizeReductionPass());
288
289     // Constant island pass work on unbundled instructions.
290     addPass(&UnpackMachineBundlesID);
291   }
292
293   addPass(createARMOptimizeBarriersPass());
294   addPass(createARMConstantIslandPass());
295
296   return true;
297 }