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"
23 static cl::opt<bool> EnableCCMP("arm64-ccmp",
24 cl::desc("Enable the CCMP formation pass"),
27 static cl::opt<bool> EnableStPairSuppress("arm64-stp-suppress", cl::Hidden,
28 cl::desc("Suppress STP for ARM64"),
32 EnablePromoteConstant("arm64-promote-const", cl::Hidden,
33 cl::desc("Enable the promote constant pass"),
37 EnableCollectLOH("arm64-collect-loh", cl::Hidden,
38 cl::desc("Enable the pass that emits the linker"
39 " optimization hints (LOH)"),
43 EnableDeadRegisterElimination("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"
50 extern "C" void LLVMInitializeARM64Target() {
51 // Register the target.
52 RegisterTargetMachine<ARM64leTargetMachine> X(TheARM64leTarget);
53 RegisterTargetMachine<ARM64beTargetMachine> Y(TheARM64beTarget);
56 /// TargetMachine ctor - Create an ARM64 architecture model.
58 ARM64TargetMachine::ARM64TargetMachine(const Target &T, StringRef TT,
59 StringRef CPU, StringRef FS,
60 const TargetOptions &Options,
61 Reloc::Model RM, CodeModel::Model CM,
64 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
65 Subtarget(TT, CPU, FS, LittleEndian),
66 // This nested ternary is horrible, but DL needs to be properly initialized
67 // before TLInfo is constructed.
68 DL(Subtarget.isTargetMachO() ?
69 "e-m:o-i64:64-i128:128-n32:64-S128" :
71 "e-m:e-i64:64-i128:128-n32:64-S128" :
72 "E-m:e-i64:64-i128:128-n32:64-S128")),
73 InstrInfo(Subtarget), TLInfo(*this), FrameLowering(*this, Subtarget),
78 void ARM64leTargetMachine::anchor() { }
80 ARM64leTargetMachine::
81 ARM64leTargetMachine(const Target &T, StringRef TT,
82 StringRef CPU, StringRef FS, const TargetOptions &Options,
83 Reloc::Model RM, CodeModel::Model CM,
85 : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
87 void ARM64beTargetMachine::anchor() { }
89 ARM64beTargetMachine::
90 ARM64beTargetMachine(const Target &T, StringRef TT,
91 StringRef CPU, StringRef FS, const TargetOptions &Options,
92 Reloc::Model RM, CodeModel::Model CM,
94 : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
97 /// ARM64 Code Generator Pass Configuration Options.
98 class ARM64PassConfig : public TargetPassConfig {
100 ARM64PassConfig(ARM64TargetMachine *TM, PassManagerBase &PM)
101 : TargetPassConfig(TM, PM) {}
103 ARM64TargetMachine &getARM64TargetMachine() const {
104 return getTM<ARM64TargetMachine>();
107 virtual bool addPreISel();
108 virtual bool addInstSelector();
109 virtual bool addILPOpts();
110 virtual bool addPreRegAlloc();
111 virtual bool addPostRegAlloc();
112 virtual bool addPreSched2();
113 virtual bool addPreEmitPass();
117 void ARM64TargetMachine::addAnalysisPasses(PassManagerBase &PM) {
118 // Add first the target-independent BasicTTI pass, then our ARM64 pass. This
119 // allows the ARM64 pass to delegate to the target independent layer when
121 PM.add(createBasicTargetTransformInfoPass(this));
122 PM.add(createARM64TargetTransformInfoPass(this));
125 TargetPassConfig *ARM64TargetMachine::createPassConfig(PassManagerBase &PM) {
126 return new ARM64PassConfig(this, PM);
129 // Pass Pipeline Configuration
130 bool ARM64PassConfig::addPreISel() {
131 // Run promote constant before global merge, so that the promoted constants
132 // get a chance to be merged
133 if (TM->getOptLevel() != CodeGenOpt::None && EnablePromoteConstant)
134 addPass(createARM64PromoteConstantPass());
135 if (TM->getOptLevel() != CodeGenOpt::None)
136 addPass(createGlobalMergePass(TM));
137 if (TM->getOptLevel() != CodeGenOpt::None)
138 addPass(createARM64AddressTypePromotionPass());
140 // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
142 addPass(createAtomicExpandLoadLinkedPass(TM));
147 bool ARM64PassConfig::addInstSelector() {
148 addPass(createARM64ISelDag(getARM64TargetMachine(), getOptLevel()));
150 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
151 // references to _TLS_MODULE_BASE_ as possible.
152 if (TM->getSubtarget<ARM64Subtarget>().isTargetELF() &&
153 getOptLevel() != CodeGenOpt::None)
154 addPass(createARM64CleanupLocalDynamicTLSPass());
159 bool ARM64PassConfig::addILPOpts() {
161 addPass(createARM64ConditionalCompares());
162 addPass(&EarlyIfConverterID);
163 if (EnableStPairSuppress)
164 addPass(createARM64StorePairSuppressPass());
168 bool ARM64PassConfig::addPreRegAlloc() {
169 // Use AdvSIMD scalar instructions whenever profitable.
170 addPass(createARM64AdvSIMDScalar());
174 bool ARM64PassConfig::addPostRegAlloc() {
175 // Change dead register definitions to refer to the zero register.
176 if (EnableDeadRegisterElimination)
177 addPass(createARM64DeadRegisterDefinitions());
181 bool ARM64PassConfig::addPreSched2() {
182 // Expand some pseudo instructions to allow proper scheduling.
183 addPass(createARM64ExpandPseudoPass());
184 // Use load/store pair instructions when possible.
185 addPass(createARM64LoadStoreOptimizationPass());
189 bool ARM64PassConfig::addPreEmitPass() {
190 // Relax conditional branch instructions if they're otherwise out of
191 // range of their destination.
192 addPass(createARM64BranchRelaxation());
193 if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH &&
194 TM->getSubtarget<ARM64Subtarget>().isTargetMachO())
195 addPass(createARM64CollectLOHPass());