AArch64TargetMachine.cpp revision c8db087b3b6d8767db4fa54057ac8fa448d812ca
1//===-- AArch64TargetMachine.cpp - Define TargetMachine for AArch64 -------===// 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 "AArch64.h" 14#include "AArch64TargetMachine.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> 24EnableCCMP("aarch64-ccmp", cl::desc("Enable the CCMP formation pass"), 25 cl::init(true), cl::Hidden); 26 27static cl::opt<bool> 28EnableStPairSuppress("aarch64-stp-suppress", cl::desc("Suppress STP for AArch64"), 29 cl::init(true), cl::Hidden); 30 31static cl::opt<bool> 32EnableAdvSIMDScalar("aarch64-simd-scalar", cl::desc("Enable use of AdvSIMD scalar" 33 " integer instructions"), cl::init(false), cl::Hidden); 34 35static cl::opt<bool> 36EnablePromoteConstant("aarch64-promote-const", cl::desc("Enable the promote " 37 "constant pass"), cl::init(true), cl::Hidden); 38 39static cl::opt<bool> 40EnableCollectLOH("aarch64-collect-loh", cl::desc("Enable the pass that emits the" 41 " linker optimization hints (LOH)"), cl::init(true), 42 cl::Hidden); 43 44static cl::opt<bool> 45EnableDeadRegisterElimination("aarch64-dead-def-elimination", cl::Hidden, 46 cl::desc("Enable the pass that removes dead" 47 " definitons and replaces stores to" 48 " them with stores to the zero" 49 " register"), 50 cl::init(true)); 51 52static cl::opt<bool> 53EnableLoadStoreOpt("aarch64-load-store-opt", cl::desc("Enable the load/store pair" 54 " optimization pass"), cl::init(true), cl::Hidden); 55 56static cl::opt<bool> 57EnableAtomicTidy("aarch64-atomic-cfg-tidy", cl::Hidden, 58 cl::desc("Run SimplifyCFG after expanding atomic operations" 59 " to make use of cmpxchg flow-based information"), 60 cl::init(true)); 61 62extern "C" void LLVMInitializeAArch64Target() { 63 // Register the target. 64 RegisterTargetMachine<AArch64leTargetMachine> X(TheAArch64leTarget); 65 RegisterTargetMachine<AArch64beTargetMachine> Y(TheAArch64beTarget); 66 67 RegisterTargetMachine<AArch64leTargetMachine> Z(TheARM64leTarget); 68 RegisterTargetMachine<AArch64beTargetMachine> W(TheARM64beTarget); 69} 70 71/// TargetMachine ctor - Create an AArch64 architecture model. 72/// 73AArch64TargetMachine::AArch64TargetMachine(const Target &T, StringRef TT, 74 StringRef CPU, StringRef FS, 75 const TargetOptions &Options, 76 Reloc::Model RM, CodeModel::Model CM, 77 CodeGenOpt::Level OL, 78 bool LittleEndian) 79 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 80 Subtarget(TT, CPU, FS, *this, LittleEndian) { 81 initAsmInfo(); 82} 83 84void AArch64leTargetMachine::anchor() { } 85 86AArch64leTargetMachine:: 87AArch64leTargetMachine(const Target &T, StringRef TT, 88 StringRef CPU, StringRef FS, const TargetOptions &Options, 89 Reloc::Model RM, CodeModel::Model CM, 90 CodeGenOpt::Level OL) 91 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 92 93void AArch64beTargetMachine::anchor() { } 94 95AArch64beTargetMachine:: 96AArch64beTargetMachine(const Target &T, StringRef TT, 97 StringRef CPU, StringRef FS, const TargetOptions &Options, 98 Reloc::Model RM, CodeModel::Model CM, 99 CodeGenOpt::Level OL) 100 : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 101 102namespace { 103/// AArch64 Code Generator Pass Configuration Options. 104class AArch64PassConfig : public TargetPassConfig { 105public: 106 AArch64PassConfig(AArch64TargetMachine *TM, PassManagerBase &PM) 107 : TargetPassConfig(TM, PM) {} 108 109 AArch64TargetMachine &getAArch64TargetMachine() const { 110 return getTM<AArch64TargetMachine>(); 111 } 112 113 void addIRPasses() override; 114 bool addPreISel() override; 115 bool addInstSelector() override; 116 bool addILPOpts() override; 117 bool addPreRegAlloc() override; 118 bool addPostRegAlloc() override; 119 bool addPreSched2() override; 120 bool addPreEmitPass() override; 121}; 122} // namespace 123 124void AArch64TargetMachine::addAnalysisPasses(PassManagerBase &PM) { 125 // Add first the target-independent BasicTTI pass, then our AArch64 pass. This 126 // allows the AArch64 pass to delegate to the target independent layer when 127 // appropriate. 128 PM.add(createBasicTargetTransformInfoPass(this)); 129 PM.add(createAArch64TargetTransformInfoPass(this)); 130} 131 132TargetPassConfig *AArch64TargetMachine::createPassConfig(PassManagerBase &PM) { 133 return new AArch64PassConfig(this, PM); 134} 135 136void AArch64PassConfig::addIRPasses() { 137 // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg 138 // ourselves. 139 addPass(createAtomicExpandLoadLinkedPass(TM)); 140 141 // Cmpxchg instructions are often used with a subsequent comparison to 142 // determine whether it succeeded. We can exploit existing control-flow in 143 // ldrex/strex loops to simplify this, but it needs tidying up. 144 if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) 145 addPass(createCFGSimplificationPass()); 146 147 TargetPassConfig::addIRPasses(); 148} 149 150// Pass Pipeline Configuration 151bool AArch64PassConfig::addPreISel() { 152 // Run promote constant before global merge, so that the promoted constants 153 // get a chance to be merged 154 if (TM->getOptLevel() != CodeGenOpt::None && EnablePromoteConstant) 155 addPass(createAArch64PromoteConstantPass()); 156 if (TM->getOptLevel() != CodeGenOpt::None) 157 addPass(createGlobalMergePass(TM)); 158 if (TM->getOptLevel() != CodeGenOpt::None) 159 addPass(createAArch64AddressTypePromotionPass()); 160 161 return false; 162} 163 164bool AArch64PassConfig::addInstSelector() { 165 addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel())); 166 167 // For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many 168 // references to _TLS_MODULE_BASE_ as possible. 169 if (TM->getSubtarget<AArch64Subtarget>().isTargetELF() && 170 getOptLevel() != CodeGenOpt::None) 171 addPass(createAArch64CleanupLocalDynamicTLSPass()); 172 173 return false; 174} 175 176bool AArch64PassConfig::addILPOpts() { 177 if (EnableCCMP) 178 addPass(createAArch64ConditionalCompares()); 179 addPass(&EarlyIfConverterID); 180 if (EnableStPairSuppress) 181 addPass(createAArch64StorePairSuppressPass()); 182 return true; 183} 184 185bool AArch64PassConfig::addPreRegAlloc() { 186 // Use AdvSIMD scalar instructions whenever profitable. 187 if (TM->getOptLevel() != CodeGenOpt::None && EnableAdvSIMDScalar) 188 addPass(createAArch64AdvSIMDScalar()); 189 return true; 190} 191 192bool AArch64PassConfig::addPostRegAlloc() { 193 // Change dead register definitions to refer to the zero register. 194 if (TM->getOptLevel() != CodeGenOpt::None && EnableDeadRegisterElimination) 195 addPass(createAArch64DeadRegisterDefinitions()); 196 return true; 197} 198 199bool AArch64PassConfig::addPreSched2() { 200 // Expand some pseudo instructions to allow proper scheduling. 201 addPass(createAArch64ExpandPseudoPass()); 202 // Use load/store pair instructions when possible. 203 if (TM->getOptLevel() != CodeGenOpt::None && EnableLoadStoreOpt) 204 addPass(createAArch64LoadStoreOptimizationPass()); 205 return true; 206} 207 208bool AArch64PassConfig::addPreEmitPass() { 209 // Relax conditional branch instructions if they're otherwise out of 210 // range of their destination. 211 addPass(createAArch64BranchRelaxation()); 212 if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH && 213 TM->getSubtarget<AArch64Subtarget>().isTargetMachO()) 214 addPass(createAArch64CollectLOHPass()); 215 return true; 216} 217