Use the new script to sort the includes of every file under lib.
[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 extern "C" void LLVMInitializeARMTarget() {
32   // Register the target.
33   RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
34   RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
35 }
36
37
38 /// TargetMachine ctor - Create an ARM architecture model.
39 ///
40 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
41                                            StringRef CPU, StringRef FS,
42                                            const TargetOptions &Options,
43                                            Reloc::Model RM, CodeModel::Model CM,
44                                            CodeGenOpt::Level OL)
45   : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
46     Subtarget(TT, CPU, FS),
47     JITInfo(),
48     InstrItins(Subtarget.getInstrItineraryData()) {
49   // Default to soft float ABI
50   if (Options.FloatABIType == FloatABI::Default)
51     this->Options.FloatABIType = FloatABI::Soft;
52 }
53
54 void ARMTargetMachine::anchor() { }
55
56 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
57                                    StringRef CPU, StringRef FS,
58                                    const TargetOptions &Options,
59                                    Reloc::Model RM, CodeModel::Model CM,
60                                    CodeGenOpt::Level OL)
61   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
62     InstrInfo(Subtarget),
63     DL(Subtarget.isAPCS_ABI() ?
64                std::string("e-p:32:32-f64:32:64-i64:32:64-"
65                            "v128:32:128-v64:32:64-n32-S32") :
66                Subtarget.isAAPCS_ABI() ?
67                std::string("e-p:32:32-f64:64:64-i64:64:64-"
68                            "v128:64:128-v64:64:64-n32-S64") :
69                std::string("e-p:32:32-f64:64:64-i64:64:64-"
70                            "v128:64:128-v64:64:64-n32-S32")),
71     TLInfo(*this),
72     TSInfo(*this),
73     FrameLowering(Subtarget),
74     STTI(&TLInfo), VTTI(&TLInfo) {
75   if (!Subtarget.hasARMOps())
76     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
77                        "support ARM mode execution!");
78 }
79
80 void ThumbTargetMachine::anchor() { }
81
82 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
83                                        StringRef CPU, StringRef FS,
84                                        const TargetOptions &Options,
85                                        Reloc::Model RM, CodeModel::Model CM,
86                                        CodeGenOpt::Level OL)
87   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
88     InstrInfo(Subtarget.hasThumb2()
89               ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
90               : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
91     DL(Subtarget.isAPCS_ABI() ?
92                std::string("e-p:32:32-f64:32:64-i64:32:64-"
93                            "i16:16:32-i8:8:32-i1:8:32-"
94                            "v128:32:128-v64:32:64-a:0:32-n32-S32") :
95                Subtarget.isAAPCS_ABI() ?
96                std::string("e-p:32:32-f64:64:64-i64:64:64-"
97                            "i16:16:32-i8:8:32-i1:8:32-"
98                            "v128:64:128-v64:64:64-a:0:32-n32-S64") :
99                std::string("e-p:32:32-f64:64:64-i64:64:64-"
100                            "i16:16:32-i8:8:32-i1:8:32-"
101                            "v128:64:128-v64:64:64-a:0:32-n32-S32")),
102     TLInfo(*this),
103     TSInfo(*this),
104     FrameLowering(Subtarget.hasThumb2()
105               ? new ARMFrameLowering(Subtarget)
106               : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)),
107     STTI(&TLInfo), VTTI(&TLInfo) {
108 }
109
110 namespace {
111 /// ARM Code Generator Pass Configuration Options.
112 class ARMPassConfig : public TargetPassConfig {
113 public:
114   ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
115     : TargetPassConfig(TM, PM) {}
116
117   ARMBaseTargetMachine &getARMTargetMachine() const {
118     return getTM<ARMBaseTargetMachine>();
119   }
120
121   const ARMSubtarget &getARMSubtarget() const {
122     return *getARMTargetMachine().getSubtargetImpl();
123   }
124
125   virtual bool addPreISel();
126   virtual bool addInstSelector();
127   virtual bool addPreRegAlloc();
128   virtual bool addPreSched2();
129   virtual bool addPreEmitPass();
130 };
131 } // namespace
132
133 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
134   return new ARMPassConfig(this, PM);
135 }
136
137 bool ARMPassConfig::addPreISel() {
138   if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
139     addPass(createGlobalMergePass(TM->getTargetLowering()));
140
141   return false;
142 }
143
144 bool ARMPassConfig::addInstSelector() {
145   addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
146
147   const ARMSubtarget *Subtarget = &getARMSubtarget();
148   if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
149       TM->Options.EnableFastISel)
150     addPass(createARMGlobalBaseRegPass());
151   return false;
152 }
153
154 bool ARMPassConfig::addPreRegAlloc() {
155   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
156   if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
157     addPass(createARMLoadStoreOptimizationPass(true));
158   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isLikeA9())
159     addPass(createMLxExpansionPass());
160   return true;
161 }
162
163 bool ARMPassConfig::addPreSched2() {
164   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
165   if (getOptLevel() != CodeGenOpt::None) {
166     if (!getARMSubtarget().isThumb1Only()) {
167       addPass(createARMLoadStoreOptimizationPass());
168       printAndVerify("After ARM load / store optimizer");
169     }
170     if (getARMSubtarget().hasNEON())
171       addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
172   }
173
174   // Expand some pseudo instructions into multiple instructions to allow
175   // proper scheduling.
176   addPass(createARMExpandPseudoPass());
177
178   if (getOptLevel() != CodeGenOpt::None) {
179     if (!getARMSubtarget().isThumb1Only())
180       addPass(&IfConverterID);
181   }
182   if (getARMSubtarget().isThumb2())
183     addPass(createThumb2ITBlockPass());
184
185   return true;
186 }
187
188 bool ARMPassConfig::addPreEmitPass() {
189   if (getARMSubtarget().isThumb2()) {
190     if (!getARMSubtarget().prefers32BitThumb())
191       addPass(createThumb2SizeReductionPass());
192
193     // Constant island pass work on unbundled instructions.
194     addPass(&UnpackMachineBundlesID);
195   }
196
197   addPass(createARMConstantIslandPass());
198
199   return true;
200 }
201
202 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
203                                           JITCodeEmitter &JCE) {
204   // Machine code emitter pass for ARM.
205   PM.add(createARMJITCodeEmitterPass(*this, JCE));
206   return false;
207 }