ARMTargetMachine.cpp revision 86050dc8cc0aaea8c9dfeb89de02cafbd7f48d92
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 "ARMMCAsmInfo.h"
15#include "ARMFrameInfo.h"
16#include "ARM.h"
17#include "llvm/PassManager.h"
18#include "llvm/CodeGen/Passes.h"
19#include "llvm/Support/CommandLine.h"
20#include "llvm/Support/FormattedStream.h"
21#include "llvm/Target/TargetOptions.h"
22#include "llvm/Target/TargetRegistry.h"
23using namespace llvm;
24
25static cl::opt<bool>
26EarlyITBlockFormation("thumb2-early-it-blocks", cl::Hidden,
27  cl::desc("Form IT blocks early before register allocation"),
28  cl::init(false));
29
30static cl::opt<bool>
31EarlyIfConvert("arm-early-if-convert", cl::Hidden,
32  cl::desc("Run if-conversion before post-ra scheduling"),
33  cl::init(false));
34
35static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
36  Triple TheTriple(TT);
37  switch (TheTriple.getOS()) {
38  case Triple::Darwin:
39    return new ARMMCAsmInfoDarwin();
40  default:
41    return new ARMELFMCAsmInfo();
42  }
43}
44
45
46extern "C" void LLVMInitializeARMTarget() {
47  // Register the target.
48  RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
49  RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
50
51  // Register the target asm info.
52  RegisterAsmInfoFn A(TheARMTarget, createMCAsmInfo);
53  RegisterAsmInfoFn B(TheThumbTarget, createMCAsmInfo);
54}
55
56/// TargetMachine ctor - Create an ARM architecture model.
57///
58ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T,
59                                           const std::string &TT,
60                                           const std::string &FS,
61                                           bool isThumb)
62  : LLVMTargetMachine(T, TT),
63    Subtarget(TT, FS, isThumb),
64    FrameInfo(Subtarget),
65    JITInfo(),
66    InstrItins(Subtarget.getInstrItineraryData()) {
67  DefRelocModel = getRelocationModel();
68}
69
70ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
71                                   const std::string &FS)
72  : ARMBaseTargetMachine(T, TT, FS, false), InstrInfo(Subtarget),
73    DataLayout(Subtarget.isAPCS_ABI() ?
74               std::string("e-p:32:32-f64:32:32-i64:32:32-n32") :
75               std::string("e-p:32:32-f64:64:64-i64:64:64-n32")),
76    TLInfo(*this),
77    TSInfo(*this) {
78}
79
80ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
81                                       const std::string &FS)
82  : ARMBaseTargetMachine(T, TT, FS, true),
83    InstrInfo(Subtarget.hasThumb2()
84              ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
85              : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
86    DataLayout(Subtarget.isAPCS_ABI() ?
87               std::string("e-p:32:32-f64:32:32-i64:32:32-"
88                           "i16:16:32-i8:8:32-i1:8:32-a:0:32-n32") :
89               std::string("e-p:32:32-f64:64:64-i64:64:64-"
90                           "i16:16:32-i8:8:32-i1:8:32-a:0:32-n32")),
91    TLInfo(*this),
92    TSInfo(*this) {
93}
94
95
96
97// Pass Pipeline Configuration
98bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
99                                           CodeGenOpt::Level OptLevel) {
100  PM.add(createARMISelDag(*this, OptLevel));
101  return false;
102}
103
104bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
105                                          CodeGenOpt::Level OptLevel) {
106  if (Subtarget.hasNEON())
107    PM.add(createNEONPreAllocPass());
108
109  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
110  if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
111    PM.add(createARMLoadStoreOptimizationPass(true));
112
113  if (OptLevel != CodeGenOpt::None && Subtarget.isThumb2() &&
114      EarlyITBlockFormation)
115    PM.add(createThumb2ITBlockPass(true));
116  return true;
117}
118
119bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM,
120                                        CodeGenOpt::Level OptLevel) {
121  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
122  if (OptLevel != CodeGenOpt::None) {
123    if (!Subtarget.isThumb1Only())
124      PM.add(createARMLoadStoreOptimizationPass());
125    if (Subtarget.hasNEON())
126      PM.add(createNEONMoveFixPass());
127  }
128
129  // Expand some pseudo instructions into multiple instructions to allow
130  // proper scheduling.
131  PM.add(createARMExpandPseudoPass());
132
133  if (EarlyIfConvert && OptLevel != CodeGenOpt::None) {
134    if (!Subtarget.isThumb1Only())
135      PM.add(createIfConverterPass());
136    if (Subtarget.isThumb2())
137      PM.add(createThumb2ITBlockPass());
138  }
139
140  return true;
141}
142
143bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
144                                          CodeGenOpt::Level OptLevel) {
145  if (!EarlyIfConvert && OptLevel != CodeGenOpt::None) {
146    if (!Subtarget.isThumb1Only())
147      PM.add(createIfConverterPass());
148  }
149
150  if (Subtarget.isThumb2()) {
151    if (!EarlyIfConvert)
152      PM.add(createThumb2ITBlockPass());
153    PM.add(createThumb2SizeReductionPass());
154  }
155
156  PM.add(createARMConstantIslandPass());
157  return true;
158}
159
160bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
161                                          CodeGenOpt::Level OptLevel,
162                                          JITCodeEmitter &JCE) {
163  // FIXME: Move this to TargetJITInfo!
164  if (DefRelocModel == Reloc::Default)
165    setRelocationModel(Reloc::Static);
166
167  // Machine code emitter pass for ARM.
168  PM.add(createARMJITCodeEmitterPass(*this, JCE));
169  return false;
170}
171