[TTI] Unify FavorPostInc and FavorBackedgeIndex into getPreferredAddressingMode

This refactors shouldFavorPostInc() and shouldFavorBackedgeIndex() into
getPreferredAddressingMode() so that we have one interface to steer LSR in
generating the preferred addressing mode.

Differential Revision: https://reviews.llvm.org/D96600
This commit is contained in:
Sjoerd Meijer 2021-02-12 15:15:05 +00:00
parent 4bd5bd4009
commit cd6de0e8de
8 changed files with 55 additions and 45 deletions

View File

@ -638,13 +638,15 @@ public:
DominatorTree *DT, AssumptionCache *AC, DominatorTree *DT, AssumptionCache *AC,
TargetLibraryInfo *LibInfo) const; TargetLibraryInfo *LibInfo) const;
/// \return True is LSR should make efforts to create/preserve post-inc enum AddressingModeKind {
/// addressing mode expressions. AMK_PreIndexed,
bool shouldFavorPostInc() const; AMK_PostIndexed,
AMK_None
};
/// Return true if LSR should make efforts to generate indexed addressing /// Return the preferred addressing mode LSR should make efforts to generate.
/// modes that operate across loop iterations. AddressingModeKind getPreferredAddressingMode(const Loop *L,
bool shouldFavorBackedgeIndex(const Loop *L) const; ScalarEvolution *SE) const;
/// Return true if the target supports masked store. /// Return true if the target supports masked store.
bool isLegalMaskedStore(Type *DataType, Align Alignment) const; bool isLegalMaskedStore(Type *DataType, Align Alignment) const;
@ -1454,8 +1456,8 @@ public:
virtual bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, virtual bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE,
LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC,
TargetLibraryInfo *LibInfo) = 0; TargetLibraryInfo *LibInfo) = 0;
virtual bool shouldFavorPostInc() const = 0; virtual AddressingModeKind
virtual bool shouldFavorBackedgeIndex(const Loop *L) const = 0; getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const = 0;
virtual bool isLegalMaskedStore(Type *DataType, Align Alignment) = 0; virtual bool isLegalMaskedStore(Type *DataType, Align Alignment) = 0;
virtual bool isLegalMaskedLoad(Type *DataType, Align Alignment) = 0; virtual bool isLegalMaskedLoad(Type *DataType, Align Alignment) = 0;
virtual bool isLegalNTStore(Type *DataType, Align Alignment) = 0; virtual bool isLegalNTStore(Type *DataType, Align Alignment) = 0;
@ -1796,9 +1798,10 @@ public:
TargetLibraryInfo *LibInfo) override { TargetLibraryInfo *LibInfo) override {
return Impl.canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo); return Impl.canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo);
} }
bool shouldFavorPostInc() const override { return Impl.shouldFavorPostInc(); } AddressingModeKind
bool shouldFavorBackedgeIndex(const Loop *L) const override { getPreferredAddressingMode(const Loop *L,
return Impl.shouldFavorBackedgeIndex(L); ScalarEvolution *SE) const override {
return Impl.getPreferredAddressingMode(L, SE);
} }
bool isLegalMaskedStore(Type *DataType, Align Alignment) override { bool isLegalMaskedStore(Type *DataType, Align Alignment) override {
return Impl.isLegalMaskedStore(DataType, Alignment); return Impl.isLegalMaskedStore(DataType, Alignment);

View File

@ -209,9 +209,10 @@ public:
return false; return false;
} }
bool shouldFavorPostInc() const { return false; } TTI::AddressingModeKind
getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const {
bool shouldFavorBackedgeIndex(const Loop *L) const { return false; } return TTI::AMK_None;
}
bool isLegalMaskedStore(Type *DataType, Align Alignment) const { bool isLegalMaskedStore(Type *DataType, Align Alignment) const {
return false; return false;

View File

@ -409,12 +409,10 @@ bool TargetTransformInfo::canSaveCmp(Loop *L, BranchInst **BI,
return TTIImpl->canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo); return TTIImpl->canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo);
} }
bool TargetTransformInfo::shouldFavorPostInc() const { TTI::AddressingModeKind
return TTIImpl->shouldFavorPostInc(); TargetTransformInfo::getPreferredAddressingMode(const Loop *L,
} ScalarEvolution *SE) const {
return TTIImpl->getPreferredAddressingMode(L, SE);
bool TargetTransformInfo::shouldFavorBackedgeIndex(const Loop *L) const {
return TTIImpl->shouldFavorBackedgeIndex(L);
} }
bool TargetTransformInfo::isLegalMaskedStore(Type *DataType, bool TargetTransformInfo::isLegalMaskedStore(Type *DataType,

View File

@ -100,18 +100,20 @@ bool ARMTTIImpl::areInlineCompatible(const Function *Caller,
return MatchExact && MatchSubset; return MatchExact && MatchSubset;
} }
bool ARMTTIImpl::shouldFavorBackedgeIndex(const Loop *L) const { TTI::AddressingModeKind
if (L->getHeader()->getParent()->hasOptSize()) ARMTTIImpl::getPreferredAddressingMode(const Loop *L,
return false; ScalarEvolution *SE) const {
if (ST->hasMVEIntegerOps()) if (ST->hasMVEIntegerOps())
return false; return TTI::AMK_PostIndexed;
return ST->isMClass() && ST->isThumb2() && L->getNumBlocks() == 1;
}
bool ARMTTIImpl::shouldFavorPostInc() const { if (L->getHeader()->getParent()->hasOptSize())
if (ST->hasMVEIntegerOps()) return TTI::AMK_None;
return true;
return false; if (ST->isMClass() && ST->isThumb2() &&
L->getNumBlocks() == 1)
return TTI::AMK_PreIndexed;
return TTI::AMK_None;
} }
Optional<Instruction *> Optional<Instruction *>

View File

@ -103,8 +103,8 @@ public:
bool enableInterleavedAccessVectorization() { return true; } bool enableInterleavedAccessVectorization() { return true; }
bool shouldFavorBackedgeIndex(const Loop *L) const; TTI::AddressingModeKind
bool shouldFavorPostInc() const; getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const;
/// Floating-point computation using ARMv8 AArch32 Advanced /// Floating-point computation using ARMv8 AArch32 Advanced
/// SIMD instructions remains unchanged from ARMv7. Only AArch64 SIMD /// SIMD instructions remains unchanged from ARMv7. Only AArch64 SIMD

View File

@ -80,8 +80,9 @@ void HexagonTTIImpl::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
} }
} }
bool HexagonTTIImpl::shouldFavorPostInc() const { AddressingModeKind::getPreferredAddressingMode(const Loop *L,
return true; ScalarEvolution *SE) const {
return AMK_PostIndexed;
} }
/// --- Vector TTI begin --- /// --- Vector TTI begin ---

View File

@ -67,7 +67,8 @@ public:
TTI::PeelingPreferences &PP); TTI::PeelingPreferences &PP);
/// Bias LSR towards creating post-increment opportunities. /// Bias LSR towards creating post-increment opportunities.
bool shouldFavorPostInc() const; AddressingModeKind getPreferredAddressingMode(const Loop *L,
ScalarEvolution *SE) const;
// L1 cache prefetch. // L1 cache prefetch.
unsigned getPrefetchDistance() const override; unsigned getPrefetchDistance() const override;

View File

@ -1227,13 +1227,15 @@ static unsigned getSetupCost(const SCEV *Reg, unsigned Depth) {
/// Tally up interesting quantities from the given register. /// Tally up interesting quantities from the given register.
void Cost::RateRegister(const Formula &F, const SCEV *Reg, void Cost::RateRegister(const Formula &F, const SCEV *Reg,
SmallPtrSetImpl<const SCEV *> &Regs) { SmallPtrSetImpl<const SCEV *> &Regs) {
TTI::AddressingModeKind AMK = TTI->getPreferredAddressingMode(L, SE);
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Reg)) { if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Reg)) {
// If this is an addrec for another loop, it should be an invariant // If this is an addrec for another loop, it should be an invariant
// with respect to L since L is the innermost loop (at least // with respect to L since L is the innermost loop (at least
// for now LSR only handles innermost loops). // for now LSR only handles innermost loops).
if (AR->getLoop() != L) { if (AR->getLoop() != L) {
// If the AddRec exists, consider it's register free and leave it alone. // If the AddRec exists, consider it's register free and leave it alone.
if (isExistingPhi(AR, *SE) && !TTI->shouldFavorPostInc()) if (isExistingPhi(AR, *SE) && AMK != TTI::AMK_PostIndexed)
return; return;
// It is bad to allow LSR for current loop to add induction variables // It is bad to allow LSR for current loop to add induction variables
@ -1254,13 +1256,11 @@ void Cost::RateRegister(const Formula &F, const SCEV *Reg,
// If the step size matches the base offset, we could use pre-indexed // If the step size matches the base offset, we could use pre-indexed
// addressing. // addressing.
if (TTI->shouldFavorBackedgeIndex(L)) { if (AMK == TTI::AMK_PreIndexed) {
if (auto *Step = dyn_cast<SCEVConstant>(AR->getStepRecurrence(*SE))) if (auto *Step = dyn_cast<SCEVConstant>(AR->getStepRecurrence(*SE)))
if (Step->getAPInt() == F.BaseOffset) if (Step->getAPInt() == F.BaseOffset)
LoopCost = 0; LoopCost = 0;
} } else if (AMK == TTI::AMK_PostIndexed) {
if (TTI->shouldFavorPostInc()) {
const SCEV *LoopStep = AR->getStepRecurrence(*SE); const SCEV *LoopStep = AR->getStepRecurrence(*SE);
if (isa<SCEVConstant>(LoopStep)) { if (isa<SCEVConstant>(LoopStep)) {
const SCEV *LoopStart = AR->getStart(); const SCEV *LoopStart = AR->getStart();
@ -3575,7 +3575,8 @@ void LSRInstance::GenerateReassociationsImpl(LSRUse &LU, unsigned LUIdx,
// may generate a post-increment operator. The reason is that the // may generate a post-increment operator. The reason is that the
// reassociations cause extra base+register formula to be created, // reassociations cause extra base+register formula to be created,
// and possibly chosen, but the post-increment is more efficient. // and possibly chosen, but the post-increment is more efficient.
if (TTI.shouldFavorPostInc() && mayUsePostIncMode(TTI, LU, BaseReg, L, SE)) TTI::AddressingModeKind AMK = TTI.getPreferredAddressingMode(L, &SE);
if (AMK == TTI::AMK_PostIndexed && mayUsePostIncMode(TTI, LU, BaseReg, L, SE))
return; return;
SmallVector<const SCEV *, 8> AddOps; SmallVector<const SCEV *, 8> AddOps;
const SCEV *Remainder = CollectSubexprs(BaseReg, nullptr, AddOps, L, SE); const SCEV *Remainder = CollectSubexprs(BaseReg, nullptr, AddOps, L, SE);
@ -4239,7 +4240,8 @@ void LSRInstance::GenerateCrossUseConstantOffsets() {
NewF.BaseOffset = (uint64_t)NewF.BaseOffset + Imm; NewF.BaseOffset = (uint64_t)NewF.BaseOffset + Imm;
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset,
LU.Kind, LU.AccessTy, NewF)) { LU.Kind, LU.AccessTy, NewF)) {
if (TTI.shouldFavorPostInc() && if (TTI.getPreferredAddressingMode(this->L, &SE) ==
TTI::AMK_PostIndexed &&
mayUsePostIncMode(TTI, LU, OrigReg, this->L, SE)) mayUsePostIncMode(TTI, LU, OrigReg, this->L, SE))
continue; continue;
if (!TTI.isLegalAddImmediate((uint64_t)NewF.UnfoldedOffset + Imm)) if (!TTI.isLegalAddImmediate((uint64_t)NewF.UnfoldedOffset + Imm))
@ -4679,7 +4681,7 @@ void LSRInstance::NarrowSearchSpaceByFilterFormulaWithSameScaledReg() {
/// If we are over the complexity limit, filter out any post-inc prefering /// If we are over the complexity limit, filter out any post-inc prefering
/// variables to only post-inc values. /// variables to only post-inc values.
void LSRInstance::NarrowSearchSpaceByFilterPostInc() { void LSRInstance::NarrowSearchSpaceByFilterPostInc() {
if (!TTI.shouldFavorPostInc()) if (TTI.getPreferredAddressingMode(L, &SE) != TTI::AMK_PostIndexed)
return; return;
if (EstimateSearchSpaceComplexity() < ComplexityLimit) if (EstimateSearchSpaceComplexity() < ComplexityLimit)
return; return;
@ -4978,7 +4980,8 @@ void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
// This can sometimes (notably when trying to favour postinc) lead to // This can sometimes (notably when trying to favour postinc) lead to
// sub-optimial decisions. There it is best left to the cost modelling to // sub-optimial decisions. There it is best left to the cost modelling to
// get correct. // get correct.
if (!TTI.shouldFavorPostInc() || LU.Kind != LSRUse::Address) { if (TTI.getPreferredAddressingMode(L, &SE) != TTI::AMK_PostIndexed ||
LU.Kind != LSRUse::Address) {
int NumReqRegsToFind = std::min(F.getNumRegs(), ReqRegs.size()); int NumReqRegsToFind = std::min(F.getNumRegs(), ReqRegs.size());
for (const SCEV *Reg : ReqRegs) { for (const SCEV *Reg : ReqRegs) {
if ((F.ScaledReg && F.ScaledReg == Reg) || if ((F.ScaledReg && F.ScaledReg == Reg) ||
@ -5560,7 +5563,8 @@ LSRInstance::LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE,
TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU) TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU)
: IU(IU), SE(SE), DT(DT), LI(LI), AC(AC), TLI(TLI), TTI(TTI), L(L), : IU(IU), SE(SE), DT(DT), LI(LI), AC(AC), TLI(TLI), TTI(TTI), L(L),
MSSAU(MSSAU), FavorBackedgeIndex(EnableBackedgeIndexing && MSSAU(MSSAU), FavorBackedgeIndex(EnableBackedgeIndexing &&
TTI.shouldFavorBackedgeIndex(L)) { TTI.getPreferredAddressingMode(L, &SE) ==
TTI::AMK_PreIndexed) {
// If LoopSimplify form is not available, stay out of trouble. // If LoopSimplify form is not available, stay out of trouble.
if (!L->isLoopSimplifyForm()) if (!L->isLoopSimplifyForm())
return; return;