diff options
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64TargetMachine.cpp')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64TargetMachine.cpp | 86 |
1 files changed, 77 insertions, 9 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index bec1758a931b..99bcb2f4649a 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -158,9 +158,23 @@ static cl::opt<bool> EnableFalkorHWPFFix("aarch64-enable-falkor-hwpf-fix", static cl::opt<bool> EnableBranchTargets("aarch64-enable-branch-targets", cl::Hidden, - cl::desc("Enable the AAcrh64 branch target pass"), + cl::desc("Enable the AArch64 branch target pass"), cl::init(true)); +static cl::opt<unsigned> SVEVectorBitsMaxOpt( + "aarch64-sve-vector-bits-max", + cl::desc("Assume SVE vector registers are at most this big, " + "with zero meaning no maximum size is assumed."), + cl::init(0), cl::Hidden); + +static cl::opt<unsigned> SVEVectorBitsMinOpt( + "aarch64-sve-vector-bits-min", + cl::desc("Assume SVE vector registers are at least this big, " + "with zero meaning no minimum size is assumed."), + cl::init(0), cl::Hidden); + +extern cl::opt<bool> EnableHomogeneousPrologEpilog; + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() { // Register the target. RegisterTargetMachine<AArch64leTargetMachine> X(getTheAArch64leTarget()); @@ -182,6 +196,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() { initializeAArch64ExpandPseudoPass(*PR); initializeAArch64LoadStoreOptPass(*PR); initializeAArch64SIMDInstrOptPass(*PR); + initializeAArch64O0PreLegalizerCombinerPass(*PR); initializeAArch64PreLegalizerCombinerPass(*PR); initializeAArch64PostLegalizerCombinerPass(*PR); initializeAArch64PostLegalizerLoweringPass(*PR); @@ -197,6 +212,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() { initializeAArch64SLSHardeningPass(*PR); initializeAArch64StackTaggingPass(*PR); initializeAArch64StackTaggingPreRAPass(*PR); + initializeAArch64LowerHomogeneousPrologEpilogPass(*PR); } //===----------------------------------------------------------------------===// @@ -345,14 +361,54 @@ AArch64TargetMachine::getSubtargetImpl(const Function &F) const { std::string FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; - auto &I = SubtargetMap[CPU + FS]; + SmallString<512> Key; + + unsigned MinSVEVectorSize = 0; + unsigned MaxSVEVectorSize = 0; + Attribute VScaleRangeAttr = F.getFnAttribute(Attribute::VScaleRange); + if (VScaleRangeAttr.isValid()) { + std::tie(MinSVEVectorSize, MaxSVEVectorSize) = + VScaleRangeAttr.getVScaleRangeArgs(); + MinSVEVectorSize *= 128; + MaxSVEVectorSize *= 128; + } else { + MinSVEVectorSize = SVEVectorBitsMinOpt; + MaxSVEVectorSize = SVEVectorBitsMaxOpt; + } + + assert(MinSVEVectorSize % 128 == 0 && + "SVE requires vector length in multiples of 128!"); + assert(MaxSVEVectorSize % 128 == 0 && + "SVE requires vector length in multiples of 128!"); + assert((MaxSVEVectorSize >= MinSVEVectorSize || MaxSVEVectorSize == 0) && + "Minimum SVE vector size should not be larger than its maximum!"); + + // Sanitize user input in case of no asserts + if (MaxSVEVectorSize == 0) + MinSVEVectorSize = (MinSVEVectorSize / 128) * 128; + else { + MinSVEVectorSize = + (std::min(MinSVEVectorSize, MaxSVEVectorSize) / 128) * 128; + MaxSVEVectorSize = + (std::max(MinSVEVectorSize, MaxSVEVectorSize) / 128) * 128; + } + + Key += "SVEMin"; + Key += std::to_string(MinSVEVectorSize); + Key += "SVEMax"; + Key += std::to_string(MaxSVEVectorSize); + Key += CPU; + Key += FS; + + auto &I = SubtargetMap[Key]; 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 = std::make_unique<AArch64Subtarget>(TargetTriple, CPU, FS, *this, - isLittle); + isLittle, MinSVEVectorSize, + MaxSVEVectorSize); } return I.get(); } @@ -428,6 +484,7 @@ public: void addPostRegAlloc() override; void addPreSched2() override; void addPreEmitPass() override; + void addPreEmitPass2() override; std::unique_ptr<CSEConfigBase> getCSEConfig() const override; }; @@ -558,8 +615,10 @@ bool AArch64PassConfig::addIRTranslator() { } void AArch64PassConfig::addPreLegalizeMachineIR() { - bool IsOptNone = getOptLevel() == CodeGenOpt::None; - addPass(createAArch64PreLegalizerCombiner(IsOptNone)); + if (getOptLevel() == CodeGenOpt::None) + addPass(createAArch64O0PreLegalizerCombiner()); + else + addPass(createAArch64PreLegalizerCombiner()); } bool AArch64PassConfig::addLegalizeMachineIR() { @@ -584,7 +643,7 @@ void AArch64PassConfig::addPreGlobalInstructionSelect() { } bool AArch64PassConfig::addGlobalInstructionSelect() { - addPass(new InstructionSelect()); + addPass(new InstructionSelect(getOptLevel())); if (getOptLevel() != CodeGenOpt::None) addPass(createAArch64PostSelectOptimize()); return false; @@ -634,6 +693,9 @@ void AArch64PassConfig::addPostRegAlloc() { } void AArch64PassConfig::addPreSched2() { + // Lower homogeneous frame instructions + if (EnableHomogeneousPrologEpilog) + addPass(createAArch64LowerHomogeneousPrologEpilogPass()); // Expand some pseudo instructions to allow proper scheduling. addPass(createAArch64ExpandPseudoPass()); // Use load/store pair instructions when possible. @@ -676,9 +738,12 @@ void AArch64PassConfig::addPreEmitPass() { if (BranchRelaxation) addPass(&BranchRelaxationPassID); - // Identify valid longjmp targets for Windows Control Flow Guard. - if (TM->getTargetTriple().isOSWindows()) + if (TM->getTargetTriple().isOSWindows()) { + // Identify valid longjmp targets for Windows Control Flow Guard. addPass(createCFGuardLongjmpPass()); + // Identify valid eh continuation targets for Windows EHCont Guard. + addPass(createEHContGuardCatchretPass()); + } if (TM->getOptLevel() != CodeGenOpt::None && EnableCompressJumpTables) addPass(createAArch64CompressJumpTablesPass()); @@ -686,8 +751,11 @@ void AArch64PassConfig::addPreEmitPass() { if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH && TM->getTargetTriple().isOSBinFormatMachO()) addPass(createAArch64CollectLOHPass()); +} - // SVE bundles move prefixes with destructive operations. +void AArch64PassConfig::addPreEmitPass2() { + // SVE bundles move prefixes with destructive operations. BLR_RVMARKER pseudo + // instructions are lowered to bundles as well. addPass(createUnpackMachineBundles(nullptr)); } |
