Skip to content

Commit 3af0c12

Browse files
author
v01dxyz
committed
[SimplifyIndVar] Push more users to worklist for simplifyUsers
Instead of considering only users that are inside the loop, consider all the users with parent dominated by the loop header.
1 parent 4b5e0a1 commit 3af0c12

File tree

3 files changed

+61
-37
lines changed

3 files changed

+61
-37
lines changed

llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,11 @@ class IVVisitor {
5252
/// where the first entry indicates that the function makes changes and the
5353
/// second entry indicates that it introduced new opportunities for loop
5454
/// unswitching.
55-
std::pair<bool, bool> simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE,
56-
DominatorTree *DT, LoopInfo *LI,
57-
const TargetTransformInfo *TTI,
58-
SmallVectorImpl<WeakTrackingVH> &Dead,
59-
SCEVExpander &Rewriter,
60-
IVVisitor *V = nullptr);
55+
std::pair<bool, bool>
56+
simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
57+
LoopInfo *LI, const TargetTransformInfo *TTI,
58+
SmallVectorImpl<WeakTrackingVH> &Dead, SCEVExpander &Rewriter,
59+
unsigned MaxDepthOutOfLoop = 1, IVVisitor *V = nullptr);
6160

6261
/// SimplifyLoopIVs - Simplify users of induction variables within this
6362
/// loop. This does not actually change or add IVs.

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ static cl::opt<bool>
124124
AllowIVWidening("indvars-widen-indvars", cl::Hidden, cl::init(true),
125125
cl::desc("Allow widening of indvars to eliminate s/zext"));
126126

127+
static cl::opt<unsigned> MaxDepthOutOfLoop(
128+
"indvars-max-depth-out-of-loop", cl::Hidden, cl::init(1),
129+
cl::desc(
130+
"Strict upper bound for the number of successive out-of-loop blocks "
131+
"when traversing use-def chains. 0 enables full traversal"));
132+
127133
namespace {
128134

129135
class IndVarSimplify {
@@ -624,8 +630,9 @@ bool IndVarSimplify::simplifyAndExtend(Loop *L,
624630
// Information about sign/zero extensions of CurrIV.
625631
IndVarSimplifyVisitor Visitor(CurrIV, SE, TTI, DT);
626632

627-
const auto &[C, U] = simplifyUsersOfIV(CurrIV, SE, DT, LI, TTI, DeadInsts,
628-
Rewriter, &Visitor);
633+
const auto &[C, U] =
634+
simplifyUsersOfIV(CurrIV, SE, DT, LI, TTI, DeadInsts, Rewriter,
635+
MaxDepthOutOfLoop, &Visitor);
629636

630637
Changed |= C;
631638
RunUnswitching |= U;

llvm/lib/Transforms/Utils/SimplifyIndVar.cpp

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,18 @@ namespace {
6262
bool Changed = false;
6363
bool RunUnswitching = false;
6464

65+
// When following the def-use chains, it can go outside the loop.
66+
// Strict upper bound on number of traversed out-of-loop blocks.
67+
unsigned MaxDepthOutOfLoop;
68+
6569
public:
6670
SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, DominatorTree *DT,
6771
LoopInfo *LI, const TargetTransformInfo *TTI,
6872
SCEVExpander &Rewriter,
69-
SmallVectorImpl<WeakTrackingVH> &Dead)
73+
SmallVectorImpl<WeakTrackingVH> &Dead,
74+
unsigned MaxDepthOutOfLoop = 1)
7075
: L(Loop), LI(LI), SE(SE), DT(DT), TTI(TTI), Rewriter(Rewriter),
71-
DeadInsts(Dead) {
76+
DeadInsts(Dead), MaxDepthOutOfLoop(MaxDepthOutOfLoop) {
7277
assert(LI && "IV simplification requires LoopInfo");
7378
}
7479

@@ -509,8 +514,8 @@ bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) {
509514
!DT->isReachableFromEntry(cast<Instruction>(U)->getParent()))
510515
continue;
511516
ICmpInst *ICI = dyn_cast<ICmpInst>(U);
512-
if (!ICI) return false;
513-
assert(L->contains(ICI->getParent()) && "LCSSA form broken?");
517+
if (!ICI)
518+
return false;
514519
if (!(ICI->getOperand(0) == TI && L->isLoopInvariant(ICI->getOperand(1))) &&
515520
!(ICI->getOperand(1) == TI && L->isLoopInvariant(ICI->getOperand(0))))
516521
return false;
@@ -839,10 +844,12 @@ bool SimplifyIndvar::strengthenRightShift(BinaryOperator *BO,
839844
}
840845

841846
/// Add all uses of Def to the current IV's worklist.
842-
static void pushIVUsers(
843-
Instruction *Def, Loop *L,
844-
SmallPtrSet<Instruction*,16> &Simplified,
845-
SmallVectorImpl< std::pair<Instruction*,Instruction*> > &SimpleIVUsers) {
847+
static void
848+
pushIVUsers(Instruction *Def, Loop *L, DominatorTree *DT,
849+
SmallPtrSet<Instruction *, 16> &Simplified,
850+
SmallVectorImpl<std::tuple<Instruction *, Instruction *, unsigned>>
851+
&SimpleIVUsers,
852+
unsigned OutOfLoopChainCounter, unsigned MaxOutOfLoopChainCounter) {
846853

847854
for (User *U : Def->users()) {
848855
Instruction *UI = cast<Instruction>(U);
@@ -854,16 +861,23 @@ static void pushIVUsers(
854861
if (UI == Def)
855862
continue;
856863

857-
// Only change the current Loop, do not change the other parts (e.g. other
858-
// Loops).
859-
if (!L->contains(UI))
864+
// Avoid adding Defs that SCEV expand to themselves, e.g. the LoopPhis
865+
// of the outter loops.
866+
if (!DT->dominates(L->getHeader(), UI->getParent()))
860867
continue;
861868

862869
// Do not push the same instruction more than once.
863870
if (!Simplified.insert(UI).second)
864871
continue;
865872

866-
SimpleIVUsers.push_back(std::make_pair(UI, Def));
873+
unsigned Counter =
874+
L->contains(UI)
875+
? 0 // reset depth if we go back inside the loop.
876+
: OutOfLoopChainCounter + (UI->getParent() != Def->getParent());
877+
878+
if (!MaxOutOfLoopChainCounter || Counter < MaxOutOfLoopChainCounter) {
879+
SimpleIVUsers.push_back(std::make_tuple(UI, Def, Counter));
880+
}
867881
}
868882
}
869883

@@ -908,17 +922,17 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
908922
SmallPtrSet<Instruction*,16> Simplified;
909923

910924
// Use-def pairs if IV users waiting to be processed for CurrIV.
911-
SmallVector<std::pair<Instruction*, Instruction*>, 8> SimpleIVUsers;
925+
SmallVector<std::tuple<Instruction *, Instruction *, unsigned>, 8>
926+
SimpleIVUsers;
912927

913928
// Push users of the current LoopPhi. In rare cases, pushIVUsers may be
914929
// called multiple times for the same LoopPhi. This is the proper thing to
915930
// do for loop header phis that use each other.
916-
pushIVUsers(CurrIV, L, Simplified, SimpleIVUsers);
931+
pushIVUsers(CurrIV, L, DT, Simplified, SimpleIVUsers, 0, MaxDepthOutOfLoop);
917932

918933
while (!SimpleIVUsers.empty()) {
919-
std::pair<Instruction*, Instruction*> UseOper =
920-
SimpleIVUsers.pop_back_val();
921-
Instruction *UseInst = UseOper.first;
934+
auto [UseInst, IVOperand, OutOfLoopChainCounter] =
935+
SimpleIVUsers.pop_back_val();
922936

923937
// If a user of the IndVar is trivially dead, we prefer just to mark it dead
924938
// rather than try to do some complex analysis or transformation (such as
@@ -942,11 +956,11 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
942956
if ((isa<PtrToIntInst>(UseInst)) || (isa<TruncInst>(UseInst)))
943957
for (Use &U : UseInst->uses()) {
944958
Instruction *User = cast<Instruction>(U.getUser());
945-
if (replaceIVUserWithLoopInvariant(User))
959+
if (DT->dominates(L->getHeader(), User->getParent()) &&
960+
replaceIVUserWithLoopInvariant(User))
946961
break; // done replacing
947962
}
948963

949-
Instruction *IVOperand = UseOper.second;
950964
for (unsigned N = 0; IVOperand; ++N) {
951965
assert(N <= Simplified.size() && "runaway iteration");
952966
(void) N;
@@ -960,22 +974,25 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
960974
continue;
961975

962976
if (eliminateIVUser(UseInst, IVOperand)) {
963-
pushIVUsers(IVOperand, L, Simplified, SimpleIVUsers);
977+
pushIVUsers(IVOperand, L, DT, Simplified, SimpleIVUsers,
978+
OutOfLoopChainCounter, MaxDepthOutOfLoop);
964979
continue;
965980
}
966981

967982
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(UseInst)) {
968983
if (strengthenBinaryOp(BO, IVOperand)) {
969984
// re-queue uses of the now modified binary operator and fall
970985
// through to the checks that remain.
971-
pushIVUsers(IVOperand, L, Simplified, SimpleIVUsers);
986+
pushIVUsers(IVOperand, L, DT, Simplified, SimpleIVUsers,
987+
OutOfLoopChainCounter, MaxDepthOutOfLoop);
972988
}
973989
}
974990

975991
// Try to use integer induction for FPToSI of float induction directly.
976992
if (replaceFloatIVWithIntegerIV(UseInst)) {
977993
// Re-queue the potentially new direct uses of IVOperand.
978-
pushIVUsers(IVOperand, L, Simplified, SimpleIVUsers);
994+
pushIVUsers(IVOperand, L, DT, Simplified, SimpleIVUsers,
995+
OutOfLoopChainCounter, MaxDepthOutOfLoop);
979996
continue;
980997
}
981998

@@ -985,7 +1002,8 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
9851002
continue;
9861003
}
9871004
if (isSimpleIVUser(UseInst, L, SE)) {
988-
pushIVUsers(UseInst, L, Simplified, SimpleIVUsers);
1005+
pushIVUsers(UseInst, L, DT, Simplified, SimpleIVUsers,
1006+
OutOfLoopChainCounter, MaxDepthOutOfLoop);
9891007
}
9901008
}
9911009
}
@@ -999,13 +1017,13 @@ void IVVisitor::anchor() { }
9991017
/// Returns a pair where the first entry indicates that the function makes
10001018
/// changes and the second entry indicates that it introduced new opportunities
10011019
/// for loop unswitching.
1002-
std::pair<bool, bool> simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE,
1003-
DominatorTree *DT, LoopInfo *LI,
1004-
const TargetTransformInfo *TTI,
1005-
SmallVectorImpl<WeakTrackingVH> &Dead,
1006-
SCEVExpander &Rewriter, IVVisitor *V) {
1020+
std::pair<bool, bool>
1021+
simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
1022+
LoopInfo *LI, const TargetTransformInfo *TTI,
1023+
SmallVectorImpl<WeakTrackingVH> &Dead, SCEVExpander &Rewriter,
1024+
unsigned MaxDepthOutOfLoop, IVVisitor *V) {
10071025
SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, TTI,
1008-
Rewriter, Dead);
1026+
Rewriter, Dead, MaxDepthOutOfLoop);
10091027
SIV.simplifyUsers(CurrIV, V);
10101028
return {SIV.hasChanged(), SIV.runUnswitching()};
10111029
}

0 commit comments

Comments
 (0)