ARMTargetMachine.cpp revision 0f660260e69e9c6cb6662c14abfc67b8d7b39a40
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 "ARMFrameLowering.h"
15#include "ARM.h"
16#include "llvm/PassManager.h"
17#include "llvm/CodeGen/Passes.h"
18#include "llvm/Support/CommandLine.h"
19#include "llvm/Support/FormattedStream.h"
20#include "llvm/Support/TargetRegistry.h"
21#include "llvm/Target/TargetOptions.h"
22using namespace llvm;
23
24extern "C" void LLVMInitializeARMTarget() {
25  // Register the target.
26  RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
27  RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
28}
29
30/// TargetMachine ctor - Create an ARM architecture model.
31///
32ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
33                                           StringRef CPU, StringRef FS,
34                                           Reloc::Model RM, CodeModel::Model CM)
35  : LLVMTargetMachine(T, TT, CPU, FS, RM, CM),
36    Subtarget(TT, CPU, FS),
37    JITInfo(),
38    InstrItins(Subtarget.getInstrItineraryData()) {
39  // Default to soft float ABI
40  if (FloatABIType == FloatABI::Default)
41    FloatABIType = FloatABI::Soft;
42}
43
44ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
45                                   StringRef CPU, StringRef FS,
46                                   Reloc::Model RM, CodeModel::Model CM)
47  : ARMBaseTargetMachine(T, TT, CPU, FS, RM, CM), InstrInfo(Subtarget),
48    DataLayout(Subtarget.isAPCS_ABI() ?
49               std::string("e-p:32:32-f64:32:64-i64:32:64-"
50                           "v128:32:128-v64:32:64-n32") :
51               std::string("e-p:32:32-f64:64:64-i64:64:64-"
52                           "v128:64:128-v64:64:64-n32")),
53    ELFWriterInfo(*this),
54    TLInfo(*this),
55    TSInfo(*this),
56    FrameLowering(Subtarget) {
57  if (!Subtarget.hasARMOps())
58    report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
59                       "support ARM mode execution!");
60}
61
62ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
63                                       StringRef CPU, StringRef FS,
64                                       Reloc::Model RM, CodeModel::Model CM)
65  : ARMBaseTargetMachine(T, TT, CPU, FS, RM, CM),
66    InstrInfo(Subtarget.hasThumb2()
67              ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
68              : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
69    DataLayout(Subtarget.isAPCS_ABI() ?
70               std::string("e-p:32:32-f64:32:64-i64:32:64-"
71                           "i16:16:32-i8:8:32-i1:8:32-"
72                           "v128:32:128-v64:32:64-a:0:32-n32") :
73               std::string("e-p:32:32-f64:64:64-i64:64:64-"
74                           "i16:16:32-i8:8:32-i1:8:32-"
75                           "v128:64:128-v64:64:64-a:0:32-n32")),
76    ELFWriterInfo(*this),
77    TLInfo(*this),
78    TSInfo(*this),
79    FrameLowering(Subtarget.hasThumb2()
80              ? new ARMFrameLowering(Subtarget)
81              : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
82}
83
84bool ARMBaseTargetMachine::addPreISel(PassManagerBase &PM,
85                                      CodeGenOpt::Level OptLevel) {
86  if (OptLevel != CodeGenOpt::None)
87    PM.add(createARMGlobalMergePass(getTargetLowering()));
88
89  return false;
90}
91
92bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
93                                           CodeGenOpt::Level OptLevel) {
94  PM.add(createARMISelDag(*this, OptLevel));
95  return false;
96}
97
98bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
99                                          CodeGenOpt::Level OptLevel) {
100  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
101  if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
102    PM.add(createARMLoadStoreOptimizationPass(true));
103  if (OptLevel != CodeGenOpt::None && Subtarget.isCortexA9())
104    PM.add(createMLxExpansionPass());
105
106  return true;
107}
108
109bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM,
110                                        CodeGenOpt::Level OptLevel) {
111  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
112  if (OptLevel != CodeGenOpt::None) {
113    if (!Subtarget.isThumb1Only())
114      PM.add(createARMLoadStoreOptimizationPass());
115    if (Subtarget.hasNEON())
116      PM.add(createNEONMoveFixPass());
117  }
118
119  // Expand some pseudo instructions into multiple instructions to allow
120  // proper scheduling.
121  PM.add(createARMExpandPseudoPass());
122
123  if (OptLevel != CodeGenOpt::None) {
124    if (!Subtarget.isThumb1Only())
125      PM.add(createIfConverterPass());
126  }
127  if (Subtarget.isThumb2())
128    PM.add(createThumb2ITBlockPass());
129
130  return true;
131}
132
133bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
134                                          CodeGenOpt::Level OptLevel) {
135  if (Subtarget.isThumb2() && !Subtarget.prefers32BitThumb())
136    PM.add(createThumb2SizeReductionPass());
137
138  PM.add(createARMConstantIslandPass());
139  return true;
140}
141
142bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
143                                          CodeGenOpt::Level OptLevel,
144                                          JITCodeEmitter &JCE) {
145  // Machine code emitter pass for ARM.
146  PM.add(createARMJITCodeEmitterPass(*this, JCE));
147  return false;
148}
149