aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-10-31 17:12:59 +0000
committerChris Lattner <sabre@nondot.org>2002-10-31 17:12:59 +0000
commite4b730441dab4aff9a69aeddbdea98990e7703c4 (patch)
tree0ad535cd437f6ccd4191d5be1f05b01688657808 /lib/Transforms
parent2fe6626eade0f21654b710023eec769f4dba6dc9 (diff)
downloadexternal_llvm-e4b730441dab4aff9a69aeddbdea98990e7703c4.zip
external_llvm-e4b730441dab4aff9a69aeddbdea98990e7703c4.tar.gz
external_llvm-e4b730441dab4aff9a69aeddbdea98990e7703c4.tar.bz2
Fixes to the reassociate pass to make it respect dominance properties
Huge thanks go to Casey Carter for writing this fix, reassociate is now reoperational! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4471 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp111
1 files changed, 54 insertions, 57 deletions
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index 50d89ec..546dd1c 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -14,6 +14,9 @@
// (starting at 2), which effectively gives values in deep loops higher rank
// than values not in loops.
//
+// This code was originally written by Chris Lattner, and was then cleaned up
+// and perfected by Casey Carter.
+//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h"
@@ -86,24 +89,6 @@ unsigned Reassociate::getRank(Value *V) {
}
-// isCommutativeOperator - Return true if the specified instruction is
-// commutative and associative. If the instruction is not commutative and
-// associative, we can not reorder its operands!
-//
-static inline BinaryOperator *isCommutativeOperator(Instruction *I) {
- // Floating point operations do not commute!
- if (I->getType()->isFloatingPoint()) return 0;
-
- if (I->getOpcode() == Instruction::Add ||
- I->getOpcode() == Instruction::Mul ||
- I->getOpcode() == Instruction::And ||
- I->getOpcode() == Instruction::Or ||
- I->getOpcode() == Instruction::Xor)
- return cast<BinaryOperator>(I);
- return 0;
-}
-
-
bool Reassociate::ReassociateExpr(BinaryOperator *I) {
Value *LHS = I->getOperand(0);
Value *RHS = I->getOperand(1);
@@ -114,7 +99,9 @@ bool Reassociate::ReassociateExpr(BinaryOperator *I) {
// Make sure the LHS of the operand always has the greater rank...
if (LHSRank < RHSRank) {
- I->swapOperands();
+ bool Success = !I->swapOperands();
+ assert(Success && "swapOperands failed");
+
std::swap(LHS, RHS);
std::swap(LHSRank, RHSRank);
Changed = true;
@@ -137,15 +124,28 @@ bool Reassociate::ReassociateExpr(BinaryOperator *I) {
// Convert ((a + 12) + 10) into (a + (12 + 10))
I->setOperand(0, LHSI->getOperand(TakeOp));
- LHSI->setOperand(TakeOp, RHS);
- I->setOperand(1, LHSI);
+
+ // Move the LHS expression forward, to ensure that it is dominated by
+ // its operands.
+ std::string Name = LHSI->getName();
+ LHSI->setName("");
+ BinaryOperator *NewLHS =
+ BinaryOperator::create(LHSI->getOpcode(),
+ LHSI->getOperand(0), LHSI->getOperand(1),
+ Name, I);
+
+ NewLHS->setOperand(TakeOp, RHS);
+ I->setOperand(1, NewLHS);
+
+ assert(LHSI->use_size() == 0 && "References to LHS shouldn't exist!");
+ LHSI->getParent()->getInstList().erase(LHSI);
++NumChanged;
DEBUG(std::cerr << "Reassociated: " << I << " Result BB: "
<< I->getParent());
// Since we modified the RHS instruction, make sure that we recheck it.
- ReassociateExpr(LHSI);
+ ReassociateExpr(NewLHS);
return true;
}
}
@@ -159,7 +159,7 @@ bool Reassociate::ReassociateExpr(BinaryOperator *I) {
// version of the value is returned, and BI is left pointing at the instruction
// that should be processed next by the reassociation pass.
//
-static Value *NegateValue(Value *V, BasicBlock *BB, BasicBlock::iterator &BI) {
+static Value *NegateValue(Value *V, BasicBlock::iterator &BI) {
// We are trying to expose opportunity for reassociation. One of the things
// that we want to do to achieve this is to push a negation as deep into an
// expression chain as possible, to expose the add instructions. In practice,
@@ -171,8 +171,8 @@ static Value *NegateValue(Value *V, BasicBlock *BB, BasicBlock::iterator &BI) {
//
if (Instruction *I = dyn_cast<Instruction>(V))
if (I->getOpcode() == Instruction::Add && I->use_size() == 1) {
- Value *RHS = NegateValue(I->getOperand(1), BB, BI);
- Value *LHS = NegateValue(I->getOperand(0), BB, BI);
+ Value *RHS = NegateValue(I->getOperand(1), BI);
+ Value *LHS = NegateValue(I->getOperand(0), BI);
// We must actually insert a new add instruction here, because the neg
// instructions do not dominate the old add instruction in general. By
@@ -187,12 +187,7 @@ static Value *NegateValue(Value *V, BasicBlock *BB, BasicBlock::iterator &BI) {
// Insert a 'neg' instruction that subtracts the value from zero to get the
// negation.
//
- Instruction *Neg =
- BinaryOperator::create(Instruction::Sub,
- Constant::getNullValue(V->getType()), V,
- V->getName()+".neg", BI);
- --BI;
- return Neg;
+ return BI = BinaryOperator::createNeg(V, V->getName() + ".neg", BI);
}
@@ -200,10 +195,37 @@ bool Reassociate::ReassociateBB(BasicBlock *BB) {
bool Changed = false;
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) {
+ if (BI->getOpcode() == Instruction::Sub && !BinaryOperator::isNeg(BI)) {
+ // Convert a subtract into an add and a neg instruction... so that sub
+ // instructions can be commuted with other add instructions...
+ //
+ // Calculate the negative value of Operand 1 of the sub instruction...
+ // and set it as the RHS of the add instruction we just made...
+ //
+ std::string Name = BI->getName();
+ BI->setName("");
+ Instruction *New =
+ BinaryOperator::create(Instruction::Add, BI->getOperand(0),
+ BI->getOperand(1), Name, BI);
+
+ // Everyone now refers to the add instruction...
+ BI->replaceAllUsesWith(New);
+
+ // Put the new add in the place of the subtract... deleting the subtract
+ BB->getInstList().erase(BI);
+
+ BI = New;
+ New->setOperand(1, NegateValue(New->getOperand(1), BI));
+
+ Changed = true;
+ DEBUG(std::cerr << "Negated: " << New << " Result BB: " << BB);
+ }
+
// If this instruction is a commutative binary operator, and the ranks of
// the two operands are sorted incorrectly, fix it now.
//
- if (BinaryOperator *I = isCommutativeOperator(BI)) {
+ if (BI->isAssociative()) {
+ BinaryOperator *I = cast<BinaryOperator>(&*BI);
if (!I->use_empty()) {
// Make sure that we don't have a tree-shaped computation. If we do,
// linearize it. Convert (A+B)+(C+D) into ((A+B)+C)+D
@@ -234,31 +256,6 @@ bool Reassociate::ReassociateBB(BasicBlock *BB) {
//
Changed |= ReassociateExpr(I);
}
-
- } else if (BI->getOpcode() == Instruction::Sub &&
- BI->getOperand(0) != Constant::getNullValue(BI->getType())) {
- // Convert a subtract into an add and a neg instruction... so that sub
- // instructions can be commuted with other add instructions...
- //
- Instruction *New = BinaryOperator::create(Instruction::Add,
- BI->getOperand(0),
- BI->getOperand(1),
- BI->getName());
- Value *NegatedValue = BI->getOperand(1);
-
- // Everyone now refers to the add instruction...
- BI->replaceAllUsesWith(New);
-
- // Put the new add in the place of the subtract... deleting the subtract
- BI = BB->getInstList().erase(BI);
- BI = ++BB->getInstList().insert(BI, New);
-
- // Calculate the negative value of Operand 1 of the sub instruction...
- // and set it as the RHS of the add instruction we just made...
- New->setOperand(1, NegateValue(NegatedValue, BB, BI));
- --BI;
- Changed = true;
- DEBUG(std::cerr << "Negated: " << New << " Result BB: " << BB);
}
}