Skip to content

Commit e6b713f

Browse files
committed
[LICM][WIP] Make an integer version of hoistFPAssociation.
This is a naive copy/paste of the FP code. We could do more integration to share code. Posting for discussion.
1 parent 689ace5 commit e6b713f

File tree

2 files changed

+1152
-0
lines changed

2 files changed

+1152
-0
lines changed

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ STATISTIC(NumAddSubHoisted, "Number of add/subtract expressions reassociated "
110110
"and hoisted out of the loop");
111111
STATISTIC(NumFPAssociationsHoisted, "Number of invariant FP expressions "
112112
"reassociated and hoisted out of the loop");
113+
STATISTIC(NumIntAssociationsHoisted,
114+
"Number of invariant int expressions "
115+
"reassociated and hoisted out of the loop");
113116

114117
/// Memory promotion is enabled by default.
115118
static cl::opt<bool>
@@ -135,6 +138,12 @@ cl::opt<unsigned> FPAssociationUpperLimit(
135138
"Set upper limit for the number of transformations performed "
136139
"during a single round of hoisting the reassociated expressions."));
137140

141+
cl::opt<unsigned> IntAssociationUpperLimit(
142+
"licm-max-num-int-reassociations", cl::init(5U), cl::Hidden,
143+
cl::desc(
144+
"Set upper limit for the number of transformations performed "
145+
"during a single round of hoisting the reassociated expressions."));
146+
138147
// Experimental option to allow imprecision in LICM in pathological cases, in
139148
// exchange for faster compile. This is to be removed if MemorySSA starts to
140149
// address the same issue. LICM calls MemorySSAWalker's
@@ -2719,6 +2728,65 @@ static bool hoistFPAssociation(Instruction &I, Loop &L,
27192728
return true;
27202729
}
27212730

2731+
static bool hoistIntAssociation(Instruction &I, Loop &L,
2732+
ICFLoopSafetyInfo &SafetyInfo,
2733+
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
2734+
DominatorTree *DT) {
2735+
using namespace PatternMatch;
2736+
Value *VariantOp = nullptr, *InvariantOp = nullptr;
2737+
2738+
if (!match(&I, m_Mul(m_Value(VariantOp), m_Value(InvariantOp))))
2739+
return false;
2740+
if (L.isLoopInvariant(VariantOp))
2741+
std::swap(VariantOp, InvariantOp);
2742+
if (L.isLoopInvariant(VariantOp) || !L.isLoopInvariant(InvariantOp))
2743+
return false;
2744+
Value *Factor = InvariantOp;
2745+
2746+
// First, we need to make sure we should do the transformation.
2747+
SmallVector<Use *> Changes;
2748+
SmallVector<BinaryOperator *> Worklist;
2749+
if (BinaryOperator *VariantBinOp = dyn_cast<BinaryOperator>(VariantOp))
2750+
Worklist.push_back(VariantBinOp);
2751+
while (!Worklist.empty()) {
2752+
BinaryOperator *BO = Worklist.pop_back_val();
2753+
if (!BO->hasOneUse())
2754+
return false;
2755+
BinaryOperator *Op0, *Op1;
2756+
if (match(BO, m_Add(m_BinOp(Op0), m_BinOp(Op1)))) {
2757+
Worklist.push_back(Op0);
2758+
Worklist.push_back(Op1);
2759+
continue;
2760+
}
2761+
if (BO->getOpcode() != Instruction::Mul || L.isLoopInvariant(BO))
2762+
return false;
2763+
Use &U0 = BO->getOperandUse(0);
2764+
Use &U1 = BO->getOperandUse(1);
2765+
if (L.isLoopInvariant(U0))
2766+
Changes.push_back(&U0);
2767+
else if (L.isLoopInvariant(U1))
2768+
Changes.push_back(&U1);
2769+
else
2770+
return false;
2771+
if (Changes.size() > IntAssociationUpperLimit)
2772+
return false;
2773+
}
2774+
if (Changes.empty())
2775+
return false;
2776+
2777+
// We know we should do it so let's do the transformation.
2778+
auto *Preheader = L.getLoopPreheader();
2779+
assert(Preheader && "Loop is not in simplify form?");
2780+
IRBuilder<> Builder(Preheader->getTerminator());
2781+
for (auto *U : Changes) {
2782+
assert(L.isLoopInvariant(U->get()));
2783+
U->set(Builder.CreateMul(U->get(), Factor, "factor.op.mul"));
2784+
}
2785+
I.replaceAllUsesWith(VariantOp);
2786+
eraseInstruction(I, SafetyInfo, MSSAU);
2787+
return true;
2788+
}
2789+
27222790
static bool hoistArithmetics(Instruction &I, Loop &L,
27232791
ICFLoopSafetyInfo &SafetyInfo,
27242792
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
@@ -2752,6 +2820,12 @@ static bool hoistArithmetics(Instruction &I, Loop &L,
27522820
return true;
27532821
}
27542822

2823+
if (hoistIntAssociation(I, L, SafetyInfo, MSSAU, AC, DT)) {
2824+
++NumHoisted;
2825+
++NumIntAssociationsHoisted;
2826+
return true;
2827+
}
2828+
27552829
return false;
27562830
}
27572831

0 commit comments

Comments
 (0)