X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FAArch64%2FAArch64TargetMachine.cpp;h=439bde101d99d5ee61819bf8b18aaac1ea45ef69;hp=f99b90b800f4b505e99270f6793c9506c410e470;hb=de246de95876149b4f4086819968686462a4fd09;hpb=9b4509a7599005fc562b8fc8996643dbf67cb1a7 diff --git a/lib/Target/AArch64/AArch64TargetMachine.cpp b/lib/Target/AArch64/AArch64TargetMachine.cpp index f99b90b800f..439bde101d9 100644 --- a/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -12,8 +12,10 @@ #include "AArch64.h" #include "AArch64TargetMachine.h" -#include "llvm/PassManager.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/RegAllocRegistry.h" +#include "llvm/IR/Function.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetOptions.h" @@ -24,6 +26,10 @@ static cl::opt EnableCCMP("aarch64-ccmp", cl::desc("Enable the CCMP formation pass"), cl::init(true), cl::Hidden); +static cl::opt EnableMCR("aarch64-mcr", + cl::desc("Enable the machine combiner pass"), + cl::init(true), cl::Hidden); + static cl::opt EnableStPairSuppress("aarch64-stp-suppress", cl::desc("Suppress STP for AArch64"), cl::init(true), cl::Hidden); @@ -59,13 +65,26 @@ EnableAtomicTidy("aarch64-atomic-cfg-tidy", cl::Hidden, " to make use of cmpxchg flow-based information"), cl::init(true)); +static cl::opt +EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden, + cl::desc("Run early if-conversion"), + cl::init(true)); + +static cl::opt +EnableCondOpt("aarch64-condopt", + cl::desc("Enable the condition optimizer pass"), + cl::init(true), cl::Hidden); + +static cl::opt +EnableA53Fix835769("aarch64-fix-cortex-a53-835769", cl::Hidden, + cl::desc("Work around Cortex-A53 erratum 835769"), + cl::init(false)); + extern "C" void LLVMInitializeAArch64Target() { // Register the target. RegisterTargetMachine X(TheAArch64leTarget); RegisterTargetMachine Y(TheAArch64beTarget); - - RegisterTargetMachine Z(TheARM64leTarget); - RegisterTargetMachine W(TheARM64beTarget); + RegisterTargetMachine Z(TheARM64Target); } /// TargetMachine ctor - Create an AArch64 architecture model. @@ -77,10 +96,36 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, StringRef TT, CodeGenOpt::Level OL, bool LittleEndian) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), - Subtarget(TT, CPU, FS, *this, LittleEndian) { + Subtarget(TT, CPU, FS, *this, LittleEndian), isLittle(LittleEndian) { initAsmInfo(); } +const AArch64Subtarget * +AArch64TargetMachine::getSubtargetImpl(const Function &F) const { + AttributeSet FnAttrs = F.getAttributes(); + Attribute CPUAttr = + FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu"); + Attribute FSAttr = + FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features"); + + std::string CPU = !CPUAttr.hasAttribute(Attribute::None) + ? CPUAttr.getValueAsString().str() + : TargetCPU; + std::string FS = !FSAttr.hasAttribute(Attribute::None) + ? FSAttr.getValueAsString().str() + : TargetFS; + + auto &I = SubtargetMap[CPU + FS]; + if (!I) { + // This needs to be done before we create a new subtarget since any + // creation will depend on the TM and the code generation flags on the + // function that reside in TargetOptions. + resetTargetOptions(F); + I = llvm::make_unique(TargetTriple, CPU, FS, *this, isLittle); + } + return I.get(); +} + void AArch64leTargetMachine::anchor() { } AArch64leTargetMachine:: @@ -104,7 +149,10 @@ namespace { class AArch64PassConfig : public TargetPassConfig { public: AArch64PassConfig(AArch64TargetMachine *TM, PassManagerBase &PM) - : TargetPassConfig(TM, PM) {} + : TargetPassConfig(TM, PM) { + if (TM->getOptLevel() != CodeGenOpt::None) + substitutePass(&PostRASchedulerID, &PostMachineSchedulerID); + } AArch64TargetMachine &getAArch64TargetMachine() const { return getTM(); @@ -136,7 +184,7 @@ TargetPassConfig *AArch64TargetMachine::createPassConfig(PassManagerBase &PM) { void AArch64PassConfig::addIRPasses() { // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg // ourselves. - addPass(createAtomicExpandLoadLinkedPass(TM)); + addPass(createAtomicExpandPass(TM)); // Cmpxchg instructions are often used with a subsequent comparison to // determine whether it succeeded. We can exploit existing control-flow in @@ -174,9 +222,14 @@ bool AArch64PassConfig::addInstSelector() { } bool AArch64PassConfig::addILPOpts() { + if (EnableCondOpt) + addPass(createAArch64ConditionOptimizerPass()); if (EnableCCMP) addPass(createAArch64ConditionalCompares()); - addPass(&EarlyIfConverterID); + if (EnableMCR) + addPass(&MachineCombinerID); + if (EnableEarlyIfConversion) + addPass(&EarlyIfConverterID); if (EnableStPairSuppress) addPass(createAArch64StorePairSuppressPass()); return true; @@ -184,8 +237,12 @@ bool AArch64PassConfig::addILPOpts() { bool AArch64PassConfig::addPreRegAlloc() { // Use AdvSIMD scalar instructions whenever profitable. - if (TM->getOptLevel() != CodeGenOpt::None && EnableAdvSIMDScalar) + if (TM->getOptLevel() != CodeGenOpt::None && EnableAdvSIMDScalar) { addPass(createAArch64AdvSIMDScalar()); + // The AdvSIMD pass may produce copies that can be rewritten to + // be register coaleascer friendly. + addPass(&PeepholeOptimizerID); + } return true; } @@ -193,6 +250,11 @@ bool AArch64PassConfig::addPostRegAlloc() { // Change dead register definitions to refer to the zero register. if (TM->getOptLevel() != CodeGenOpt::None && EnableDeadRegisterElimination) addPass(createAArch64DeadRegisterDefinitions()); + if (TM->getOptLevel() != CodeGenOpt::None && + TM->getSubtarget().isCortexA57() && + usingDefaultRegAlloc()) + // Improve performance for some FP/SIMD code for A57. + addPass(createAArch64A57FPLoadBalancing()); return true; } @@ -206,6 +268,8 @@ bool AArch64PassConfig::addPreSched2() { } bool AArch64PassConfig::addPreEmitPass() { + if (EnableA53Fix835769) + addPass(createAArch64A53Fix835769()); // Relax conditional branch instructions if they're otherwise out of // range of their destination. addPass(createAArch64BranchRelaxation());