blob: f4a79963790125f87e9b523ff5b3434f8ce0b871 [file] [log] [blame]
Tim Northover00ed9962014-03-29 10:18:08 +00001//===-- ARM64TargetMachine.cpp - Define TargetMachine for ARM64 -----------===//
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 "ARM64.h"
14#include "ARM64TargetMachine.h"
15#include "llvm/PassManager.h"
16#include "llvm/CodeGen/Passes.h"
17#include "llvm/Support/CommandLine.h"
18#include "llvm/Support/TargetRegistry.h"
19#include "llvm/Target/TargetOptions.h"
20#include "llvm/Transforms/Scalar.h"
21using namespace llvm;
22
23static cl::opt<bool> EnableCCMP("arm64-ccmp",
24 cl::desc("Enable the CCMP formation pass"),
25 cl::init(true));
26
27static cl::opt<bool> EnableStPairSuppress("arm64-stp-suppress", cl::Hidden,
28 cl::desc("Suppress STP for ARM64"),
29 cl::init(true));
30
31static cl::opt<bool>
32EnablePromoteConstant("arm64-promote-const", cl::Hidden,
33 cl::desc("Enable the promote constant pass"),
34 cl::init(true));
35
36static cl::opt<bool>
37EnableCollectLOH("arm64-collect-loh", cl::Hidden,
38 cl::desc("Enable the pass that emits the linker"
39 " optimization hints (LOH)"),
40 cl::init(true));
41
Louis Gerbarg6d2e3c62014-04-14 21:05:02 +000042static cl::opt<bool>
43EnableDeadRegisterElimination("arm64-dead-def-elimination", cl::Hidden,
44 cl::desc("Enable the pass that removes dead"
45 " definitons and replaces stores to"
46 " them with stores to the zero"
47 " register"),
48 cl::init(true));
49
Tim Northover00ed9962014-03-29 10:18:08 +000050extern "C" void LLVMInitializeARM64Target() {
51 // Register the target.
52 RegisterTargetMachine<ARM64TargetMachine> X(TheARM64Target);
53}
54
55/// TargetMachine ctor - Create an ARM64 architecture model.
56///
57ARM64TargetMachine::ARM64TargetMachine(const Target &T, StringRef TT,
58 StringRef CPU, StringRef FS,
59 const TargetOptions &Options,
60 Reloc::Model RM, CodeModel::Model CM,
61 CodeGenOpt::Level OL)
62 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
63 Subtarget(TT, CPU, FS),
64 DL(Subtarget.isTargetMachO() ? "e-m:o-i64:64-i128:128-n32:64-S128"
65 : "e-m:e-i64:64-i128:128-n32:64-S128"),
66 InstrInfo(Subtarget), TLInfo(*this), FrameLowering(*this, Subtarget),
67 TSInfo(*this) {
68 initAsmInfo();
69}
70
71namespace {
72/// ARM64 Code Generator Pass Configuration Options.
73class ARM64PassConfig : public TargetPassConfig {
74public:
75 ARM64PassConfig(ARM64TargetMachine *TM, PassManagerBase &PM)
76 : TargetPassConfig(TM, PM) {}
77
78 ARM64TargetMachine &getARM64TargetMachine() const {
79 return getTM<ARM64TargetMachine>();
80 }
81
82 virtual bool addPreISel();
83 virtual bool addInstSelector();
84 virtual bool addILPOpts();
85 virtual bool addPreRegAlloc();
86 virtual bool addPostRegAlloc();
87 virtual bool addPreSched2();
88 virtual bool addPreEmitPass();
89};
90} // namespace
91
92void ARM64TargetMachine::addAnalysisPasses(PassManagerBase &PM) {
93 // Add first the target-independent BasicTTI pass, then our ARM64 pass. This
94 // allows the ARM64 pass to delegate to the target independent layer when
95 // appropriate.
96 PM.add(createBasicTargetTransformInfoPass(this));
97 PM.add(createARM64TargetTransformInfoPass(this));
98}
99
100TargetPassConfig *ARM64TargetMachine::createPassConfig(PassManagerBase &PM) {
101 return new ARM64PassConfig(this, PM);
102}
103
104// Pass Pipeline Configuration
105bool ARM64PassConfig::addPreISel() {
106 // Run promote constant before global merge, so that the promoted constants
107 // get a chance to be merged
108 if (TM->getOptLevel() != CodeGenOpt::None && EnablePromoteConstant)
109 addPass(createARM64PromoteConstantPass());
110 if (TM->getOptLevel() != CodeGenOpt::None)
111 addPass(createGlobalMergePass(TM));
112 if (TM->getOptLevel() != CodeGenOpt::None)
113 addPass(createARM64AddressTypePromotionPass());
114 return false;
115}
116
117bool ARM64PassConfig::addInstSelector() {
118 addPass(createARM64ISelDag(getARM64TargetMachine(), getOptLevel()));
119
120 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
121 // references to _TLS_MODULE_BASE_ as possible.
122 if (TM->getSubtarget<ARM64Subtarget>().isTargetELF() &&
123 getOptLevel() != CodeGenOpt::None)
124 addPass(createARM64CleanupLocalDynamicTLSPass());
125
126 return false;
127}
128
129bool ARM64PassConfig::addILPOpts() {
130 if (EnableCCMP)
131 addPass(createARM64ConditionalCompares());
132 addPass(&EarlyIfConverterID);
133 if (EnableStPairSuppress)
134 addPass(createARM64StorePairSuppressPass());
135 return true;
136}
137
138bool ARM64PassConfig::addPreRegAlloc() {
139 // Use AdvSIMD scalar instructions whenever profitable.
140 addPass(createARM64AdvSIMDScalar());
141 return true;
142}
143
144bool ARM64PassConfig::addPostRegAlloc() {
145 // Change dead register definitions to refer to the zero register.
Louis Gerbarg6d2e3c62014-04-14 21:05:02 +0000146 if (EnableDeadRegisterElimination)
147 addPass(createARM64DeadRegisterDefinitions());
Tim Northover00ed9962014-03-29 10:18:08 +0000148 return true;
149}
150
151bool ARM64PassConfig::addPreSched2() {
152 // Expand some pseudo instructions to allow proper scheduling.
153 addPass(createARM64ExpandPseudoPass());
154 // Use load/store pair instructions when possible.
155 addPass(createARM64LoadStoreOptimizationPass());
156 return true;
157}
158
159bool ARM64PassConfig::addPreEmitPass() {
160 // Relax conditional branch instructions if they're otherwise out of
161 // range of their destination.
162 addPass(createARM64BranchRelaxation());
163 if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH)
164 addPass(createARM64CollectLOHPass());
165 return true;
166}