Skip to content

Commit 499eaa5

Browse files
committed
LICM: hoist BO assoc when BinOp is in RHS
Extend hoistBOAssociation smoothly to handle the case when the inner BinaryOperator is in the RHS of the outer BinaryOperator. This completes the generalization of hoistBOAssociation, and the only limitation after this patch is the fact that only Add and Mul are hoisted.
1 parent f663ddc commit 499eaa5

File tree

2 files changed

+525
-24
lines changed

2 files changed

+525
-24
lines changed

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,18 +2804,12 @@ static bool hoistMulAddAssociation(Instruction &I, Loop &L,
28042804
/// Reassociate binary expressions of the form
28052805
///
28062806
/// 1. "(LV op C1) op C2" ==> "LV op (C1 op C2)" if op is an associative BinOp
2807-
///
2808-
/// where LV is a loop variant, and C1 and C2 are loop invariants that we want
2809-
/// to hoist.
2810-
///
28112807
/// 2. "(C1 op LV) op C2" ==> "LV op (C1 op C2)" if op is a commutative BinOp
2808+
/// 3. "C2 op (C1 op LV)" ==> "(C2 op C1) op LV" if op an associative BinOp
2809+
/// 4. "C2 op (LV op C1)" ==> "(C2 op C1) op LV" if op is a commutative BinOp
28122810
///
28132811
/// where LV is a loop variant, and C1 and C2 are loop invariants that we want
28142812
/// to hoist.
2815-
///
2816-
/// TODO: This can be extended to more cases such as
2817-
/// 1. "C1 op (C2 op LV)" ==> "(C1 op C2) op LV" if op an associative BinOp
2818-
/// 2. "C1 op (LV op C2)" ==> "(C1 op C2) op LV" if op is a commutative BinOp
28192813
static bool hoistBOAssociation(Instruction &I, Loop &L,
28202814
ICFLoopSafetyInfo &SafetyInfo,
28212815
MemorySSAUpdater &MSSAU, AssumptionCache *AC,
@@ -2829,21 +2823,24 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
28292823
if (Opcode != Instruction::Add && Opcode != Instruction::Mul)
28302824
return false;
28312825

2832-
auto *BO0 = dyn_cast<BinaryOperator>(BO->getOperand(0));
2826+
bool BinOpInRHS = isa<BinaryOperator>(BO->getOperand(1));
2827+
auto *BO0 = dyn_cast<BinaryOperator>(BO->getOperand(BinOpInRHS));
28332828
if (!BO0 || BO0->getOpcode() != Opcode || BO0->hasNUsesOrMore(3))
28342829
return false;
28352830

28362831
Value *LV = BO0->getOperand(0);
28372832
Value *C1 = BO0->getOperand(1);
2838-
Value *C2 = BO->getOperand(1);
2833+
Value *C2 = BO->getOperand(!BinOpInRHS);
28392834

28402835
if (!L.isLoopInvariant(C2))
28412836
return false;
2837+
bool BothAssociative = BO->isAssociative() && BO0->isAssociative();
2838+
bool BothCommutative = BO->isCommutative() && BO0->isCommutative();
28422839
if (!L.isLoopInvariant(LV) && L.isLoopInvariant(C1)) {
2843-
if (!BO->isAssociative() || !BO0->isAssociative())
2840+
if ((!BinOpInRHS && !BothAssociative) || (BinOpInRHS && !BothCommutative))
28442841
return false;
28452842
} else if (L.isLoopInvariant(LV) && !L.isLoopInvariant(C1)) {
2846-
if (!BO->isCommutative() || !BO0->isCommutative())
2843+
if ((!BinOpInRHS && !BothCommutative) || (BinOpInRHS && !BothAssociative))
28472844
return false;
28482845
std::swap(LV, C1);
28492846
} else
@@ -2852,11 +2849,19 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
28522849
auto *Preheader = L.getLoopPreheader();
28532850
assert(Preheader && "Loop is not in simplify form?");
28542851

2852+
// To create C2 op C1, instead of C1 op C2.
2853+
if (BinOpInRHS)
2854+
std::swap(C1, C2);
2855+
28552856
IRBuilder<> Builder(Preheader->getTerminator());
28562857
auto *Inv = Builder.CreateBinOp(Opcode, C1, C2, "invariant.op");
28572858

2858-
auto *NewBO = BinaryOperator::Create(
2859-
Opcode, LV, Inv, BO->getName() + ".reass", BO->getIterator());
2859+
auto *NewBO =
2860+
BinOpInRHS
2861+
? BinaryOperator::Create(Opcode, Inv, LV, BO->getName() + ".reass",
2862+
BO->getIterator())
2863+
: BinaryOperator::Create(Opcode, LV, Inv, BO->getName() + ".reass",
2864+
BO->getIterator());
28602865

28612866
// Copy NUW for ADDs if both instructions have it.
28622867
if (Opcode == Instruction::Add && BO->hasNoUnsignedWrap() &&

0 commit comments

Comments
 (0)