Skip to content

Commit 53416ba

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 e12be9c commit 53416ba

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 @@ static 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
@@ -2727,6 +2736,65 @@ static bool hoistFPAssociation(Instruction &I, Loop &L,
27272736
return true;
27282737
}
27292738

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

2831+
if (hoistIntAssociation(I, L, SafetyInfo, MSSAU, AC, DT)) {
2832+
++NumHoisted;
2833+
++NumIntAssociationsHoisted;
2834+
return true;
2835+
}
2836+
27632837
return false;
27642838
}
27652839

0 commit comments

Comments
 (0)