LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ARMTargetMachine.cpp
Go to the documentation of this file.
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"
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.
40 }
41 
42 
43 /// TargetMachine ctor - Create an ARM architecture model.
44 ///
46  StringRef CPU, StringRef FS,
47  const TargetOptions &Options,
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.
65 }
66 
67 
68 void ARMTargetMachine::anchor() { }
69 
71  StringRef CPU, StringRef FS,
72  const TargetOptions &Options,
75  : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
76  InstrInfo(Subtarget),
77  DL(Subtarget.isAPCS_ABI() ?
78  std::string("e-p:32:32-f64:32:64-i64:32:64-"
79  "v128:32:128-v64:32:64-n32-S32") :
80  Subtarget.isAAPCS_ABI() ?
81  std::string("e-p:32:32-f64:64:64-i64:64:64-"
82  "v128:64:128-v64:64:64-n32-S64") :
83  std::string("e-p:32:32-f64:64:64-i64:64:64-"
84  "v128:64:128-v64:64:64-n32-S32")),
85  TLInfo(*this),
86  TSInfo(*this),
87  FrameLowering(Subtarget) {
88  initAsmInfo();
89  if (!Subtarget.hasARMOps())
90  report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
91  "support ARM mode execution!");
92 }
93 
94 void ThumbTargetMachine::anchor() { }
95 
97  StringRef CPU, StringRef FS,
98  const TargetOptions &Options,
101  : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
102  InstrInfo(Subtarget.hasThumb2()
103  ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
104  : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
105  DL(Subtarget.isAPCS_ABI() ?
106  std::string("e-p:32:32-f64:32:64-i64:32:64-"
107  "i16:16:32-i8:8:32-i1:8:32-"
108  "v128:32:128-v64:32:64-a:0:32-n32-S32") :
109  Subtarget.isAAPCS_ABI() ?
110  std::string("e-p:32:32-f64:64:64-i64:64:64-"
111  "i16:16:32-i8:8:32-i1:8:32-"
112  "v128:64:128-v64:64:64-a:0:32-n32-S64") :
113  std::string("e-p:32:32-f64:64:64-i64:64:64-"
114  "i16:16:32-i8:8:32-i1:8:32-"
115  "v128:64:128-v64:64:64-a:0:32-n32-S32")),
116  TLInfo(*this),
117  TSInfo(*this),
118  FrameLowering(Subtarget.hasThumb2()
119  ? new ARMFrameLowering(Subtarget)
120  : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
121  initAsmInfo();
122 }
123 
124 namespace {
125 /// ARM Code Generator Pass Configuration Options.
126 class ARMPassConfig : public TargetPassConfig {
127 public:
128  ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
129  : TargetPassConfig(TM, PM) {}
130 
131  ARMBaseTargetMachine &getARMTargetMachine() const {
132  return getTM<ARMBaseTargetMachine>();
133  }
134 
135  const ARMSubtarget &getARMSubtarget() const {
136  return *getARMTargetMachine().getSubtargetImpl();
137  }
138 
139  virtual bool addPreISel();
140  virtual bool addInstSelector();
141  virtual bool addPreRegAlloc();
142  virtual bool addPreSched2();
143  virtual bool addPreEmitPass();
144 };
145 } // namespace
146 
148  return new ARMPassConfig(this, PM);
149 }
150 
151 bool ARMPassConfig::addPreISel() {
152  if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
153  addPass(createGlobalMergePass(TM));
154 
155  return false;
156 }
157 
158 bool ARMPassConfig::addInstSelector() {
159  addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
160 
161  const ARMSubtarget *Subtarget = &getARMSubtarget();
162  if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
163  TM->Options.EnableFastISel)
164  addPass(createARMGlobalBaseRegPass());
165  return false;
166 }
167 
168 bool ARMPassConfig::addPreRegAlloc() {
169  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
170  if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
171  addPass(createARMLoadStoreOptimizationPass(true));
172  if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
173  addPass(createMLxExpansionPass());
174  // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
175  // enabled when NEON is available.
176  if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() &&
177  getARMSubtarget().hasNEON() && !DisableA15SDOptimization) {
178  addPass(createA15SDOptimizerPass());
179  }
180  return true;
181 }
182 
183 bool ARMPassConfig::addPreSched2() {
184  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
185  if (getOptLevel() != CodeGenOpt::None) {
186  if (!getARMSubtarget().isThumb1Only()) {
188  printAndVerify("After ARM load / store optimizer");
189  }
190  if (getARMSubtarget().hasNEON())
191  addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
192  }
193 
194  // Expand some pseudo instructions into multiple instructions to allow
195  // proper scheduling.
196  addPass(createARMExpandPseudoPass());
197 
198  if (getOptLevel() != CodeGenOpt::None) {
199  if (!getARMSubtarget().isThumb1Only()) {
200  // in v8, IfConversion depends on Thumb instruction widths
201  if (getARMSubtarget().restrictIT() &&
202  !getARMSubtarget().prefers32BitThumb())
204  addPass(&IfConverterID);
205  }
206  }
207  if (getARMSubtarget().isThumb2())
208  addPass(createThumb2ITBlockPass());
209 
210  return true;
211 }
212 
213 bool ARMPassConfig::addPreEmitPass() {
214  if (getARMSubtarget().isThumb2()) {
215  if (!getARMSubtarget().prefers32BitThumb())
217 
218  // Constant island pass work on unbundled instructions.
219  addPass(&UnpackMachineBundlesID);
220  }
221 
222  addPass(createARMConstantIslandPass());
223 
224  return true;
225 }
226 
227 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
228  JITCodeEmitter &JCE) {
229  // Machine code emitter pass for ARM.
230  PM.add(createARMJITCodeEmitterPass(*this, JCE));
231  return false;
232 }
FunctionPass * createThumb2SizeReductionPass()
ImmutablePass * createARMTargetTransformInfoPass(const ARMBaseTargetMachine *TM)
Creates an ARM-specific Target Transformation Info pass.
FunctionPass * createA15SDOptimizerPass()
FunctionPass * createMLxExpansionPass()
ARMBaseTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
const std::string & getCPUString() const
Definition: ARMSubtarget.h:336
FunctionPass * createARMGlobalBaseRegPass()
ImmutablePass * createBasicTargetTransformInfoPass(const TargetMachine *TM)
Create a basic TargetTransformInfo analysis pass.
FunctionPass * createARMExpandPseudoPass()
bool isThumb1Only() const
Definition: ARMSubtarget.h:320
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
ThumbTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &MCE)
virtual void addAnalysisPasses(PassManagerBase &PM)
Register ARM analysis passes with a pass manager.
bool isTargetELF() const
Definition: ARMSubtarget.h:306
FunctionPass * createARMConstantIslandPass()
virtual TargetPassConfig * createPassConfig(PassManagerBase &PM)
void LLVMInitializeARMTarget()
FunctionPass * createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM, JITCodeEmitter &JCE)
Pass * createGlobalMergePass(const TargetMachine *TM=0)
bool hasARMOps() const
Definition: ARMSubtarget.h:262
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:314
static cl::opt< bool > DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden, cl::desc("Inhibit optimization of S->D register accesses on A15"), cl::init(false))
Target TheThumbTarget
char & UnpackMachineBundlesID
UnpackMachineBundles - This pass unpack machine instruction bundles.
FunctionPass * createARMLoadStoreOptimizationPass(bool PreAlloc=false)
FunctionPass * createExecutionDependencyFixPass(const TargetRegisterClass *RC)
Target TheARMTarget
char & IfConverterID
IfConverter - This pass performs machine code if conversion.
FunctionPass * createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOpt::Level OptLevel)
static cl::opt< bool > EnableGlobalMerge("global-merge", cl::Hidden, cl::desc("Enable global merge pass"), cl::init(true))
FunctionPass * createThumb2ITBlockPass()
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
ARMTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
FloatABI::ABIType FloatABIType