1 //===-- ARM64TargetMachine.cpp - Define TargetMachine for ARM64 -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
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"
24 EnableCCMP("arm64-ccmp", cl::desc("Enable the CCMP formation pass"),
25 cl::init(true), cl::Hidden);
28 EnableEarlyIfConvert("arm64-early-ifcvt", cl::desc("Enable the early if "
29 "converter pass"), cl::init(true), cl::Hidden);
32 EnableStPairSuppress("arm64-stp-suppress", cl::desc("Suppress STP for ARM64"),
33 cl::init(true), cl::Hidden);
36 EnableAdvSIMDScalar("arm64-simd-scalar", cl::desc("Enable use of AdvSIMD scalar"
37 " integer instructions"), cl::init(false), cl::Hidden);
40 EnablePromoteConstant("arm64-promote-const", cl::desc("Enable the promote "
41 "constant pass"), cl::init(true), cl::Hidden);
44 EnableCollectLOH("arm64-collect-loh", cl::desc("Enable the pass that emits the"
45 " linker optimization hints (LOH)"), cl::init(true),
49 EnableDeadRegisterElimination("arm64-dead-def-elimination", cl::Hidden,
50 cl::desc("Enable the pass that removes dead"
51 " definitons and replaces stores to"
52 " them with stores to the zero"
57 EnableLoadStoreOpt("arm64-load-store-opt", cl::desc("Enable the load/store pair"
58 " optimization pass"), cl::init(true), cl::Hidden);
60 extern "C" void LLVMInitializeARM64Target() {
61 // Register the target.
62 RegisterTargetMachine<ARM64leTargetMachine> X(TheARM64leTarget);
63 RegisterTargetMachine<ARM64beTargetMachine> Y(TheARM64beTarget);
66 /// TargetMachine ctor - Create an ARM64 architecture model.
68 ARM64TargetMachine::ARM64TargetMachine(const Target &T, StringRef TT,
69 StringRef CPU, StringRef FS,
70 const TargetOptions &Options,
71 Reloc::Model RM, CodeModel::Model CM,
74 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
75 Subtarget(TT, CPU, FS, LittleEndian),
76 // This nested ternary is horrible, but DL needs to be properly initialized
77 // before TLInfo is constructed.
78 DL(Subtarget.isTargetMachO() ?
79 "e-m:o-i64:64-i128:128-n32:64-S128" :
81 "e-m:e-i64:64-i128:128-n32:64-S128" :
82 "E-m:e-i64:64-i128:128-n32:64-S128")),
83 InstrInfo(Subtarget), TLInfo(*this), FrameLowering(*this, Subtarget),
88 void ARM64leTargetMachine::anchor() { }
90 ARM64leTargetMachine::
91 ARM64leTargetMachine(const Target &T, StringRef TT,
92 StringRef CPU, StringRef FS, const TargetOptions &Options,
93 Reloc::Model RM, CodeModel::Model CM,
95 : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
97 void ARM64beTargetMachine::anchor() { }
99 ARM64beTargetMachine::
100 ARM64beTargetMachine(const Target &T, StringRef TT,
101 StringRef CPU, StringRef FS, const TargetOptions &Options,
102 Reloc::Model RM, CodeModel::Model CM,
103 CodeGenOpt::Level OL)
104 : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
107 /// ARM64 Code Generator Pass Configuration Options.
108 class ARM64PassConfig : public TargetPassConfig {
110 ARM64PassConfig(ARM64TargetMachine *TM, PassManagerBase &PM)
111 : TargetPassConfig(TM, PM) {}
113 ARM64TargetMachine &getARM64TargetMachine() const {
114 return getTM<ARM64TargetMachine>();
117 bool addPreISel() override;
118 bool addInstSelector() override;
119 bool addILPOpts() override;
120 bool addPreRegAlloc() override;
121 bool addPostRegAlloc() override;
122 bool addPreSched2() override;
123 bool addPreEmitPass() override;
127 void ARM64TargetMachine::addAnalysisPasses(PassManagerBase &PM) {
128 // Add first the target-independent BasicTTI pass, then our ARM64 pass. This
129 // allows the ARM64 pass to delegate to the target independent layer when
131 PM.add(createBasicTargetTransformInfoPass(this));
132 PM.add(createARM64TargetTransformInfoPass(this));
135 TargetPassConfig *ARM64TargetMachine::createPassConfig(PassManagerBase &PM) {
136 return new ARM64PassConfig(this, PM);
139 // Pass Pipeline Configuration
140 bool ARM64PassConfig::addPreISel() {
141 // Run promote constant before global merge, so that the promoted constants
142 // get a chance to be merged
143 if (TM->getOptLevel() != CodeGenOpt::None && EnablePromoteConstant)
144 addPass(createARM64PromoteConstantPass());
145 if (TM->getOptLevel() != CodeGenOpt::None)
146 addPass(createGlobalMergePass(TM));
147 if (TM->getOptLevel() != CodeGenOpt::None)
148 addPass(createARM64AddressTypePromotionPass());
150 // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
152 addPass(createAtomicExpandLoadLinkedPass(TM));
157 bool ARM64PassConfig::addInstSelector() {
158 addPass(createARM64ISelDag(getARM64TargetMachine(), getOptLevel()));
160 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
161 // references to _TLS_MODULE_BASE_ as possible.
162 if (TM->getSubtarget<ARM64Subtarget>().isTargetELF() &&
163 getOptLevel() != CodeGenOpt::None)
164 addPass(createARM64CleanupLocalDynamicTLSPass());
169 bool ARM64PassConfig::addILPOpts() {
171 addPass(createARM64ConditionalCompares());
172 if (EnableEarlyIfConvert)
173 addPass(&EarlyIfConverterID);
174 if (EnableStPairSuppress)
175 addPass(createARM64StorePairSuppressPass());
179 bool ARM64PassConfig::addPreRegAlloc() {
180 // Use AdvSIMD scalar instructions whenever profitable.
181 if (TM->getOptLevel() != CodeGenOpt::None && EnableAdvSIMDScalar)
182 addPass(createARM64AdvSIMDScalar());
186 bool ARM64PassConfig::addPostRegAlloc() {
187 // Change dead register definitions to refer to the zero register.
188 if (TM->getOptLevel() != CodeGenOpt::None && EnableDeadRegisterElimination)
189 addPass(createARM64DeadRegisterDefinitions());
193 bool ARM64PassConfig::addPreSched2() {
194 // Expand some pseudo instructions to allow proper scheduling.
195 addPass(createARM64ExpandPseudoPass());
196 // Use load/store pair instructions when possible.
197 if (TM->getOptLevel() != CodeGenOpt::None && EnableLoadStoreOpt)
198 addPass(createARM64LoadStoreOptimizationPass());
202 bool ARM64PassConfig::addPreEmitPass() {
203 // Relax conditional branch instructions if they're otherwise out of
204 // range of their destination.
205 addPass(createARM64BranchRelaxation());
206 if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH &&
207 TM->getSubtarget<ARM64Subtarget>().isTargetMachO())
208 addPass(createARM64CollectLOHPass());