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