#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
class Reassociate : public FunctionPass {
DenseMap<BasicBlock*, unsigned> RankMap;
DenseMap<AssertingVH<Value>, unsigned> ValueRankMap;
- SetVector<AssertingVH<Instruction> > RedoInsts;
+ SmallVector<WeakVH, 8> RedoInsts;
+ SmallVector<WeakVH, 8> DeadInsts;
bool MadeChange;
public:
static char ID; // Pass identification, replacement for typeid
Value *OptimizeMul(BinaryOperator *I, SmallVectorImpl<ValueEntry> &Ops);
void LinearizeExprTree(BinaryOperator *I, SmallVectorImpl<ValueEntry> &Ops);
Value *RemoveFactorFromExpression(Value *V, Value *Factor);
- void OptimizeInst(Instruction *I);
+ void ReassociateInst(BasicBlock::iterator &BBI);
+
+ void RemoveDeadBinaryOp(Value *V);
};
}
return 0;
}
+void Reassociate::RemoveDeadBinaryOp(Value *V) {
+ BinaryOperator *Op = dyn_cast<BinaryOperator>(V);
+ if (!Op)
+ return;
+
+ ValueRankMap.erase(Op);
+ DeadInsts.push_back(Op);
+
+ BinaryOperator *LHS = isReassociableOp(Op->getOperand(0), Op->getOpcode());
+ BinaryOperator *RHS = isReassociableOp(Op->getOperand(1), Op->getOpcode());
+ Op->setOperand(0, UndefValue::get(Op->getType()));
+ Op->setOperand(1, UndefValue::get(Op->getType()));
+
+ if (LHS)
+ RemoveDeadBinaryOp(LHS);
+ if (RHS)
+ RemoveDeadBinaryOp(RHS);
+}
+
static bool isUnmovableInstruction(Instruction *I) {
if (I->getOpcode() == Instruction::PHI ||
I->getOpcode() == Instruction::LandingPad ||
/// LowerNegateToMultiply - Replace 0-X with X*-1.
///
-static BinaryOperator *LowerNegateToMultiply(Instruction *Neg) {
+static BinaryOperator *LowerNegateToMultiply(Instruction *Neg,
+ DenseMap<AssertingVH<Value>, unsigned> &ValueRankMap) {
Constant *Cst = Constant::getAllOnesValue(Neg->getType());
BinaryOperator *Res =
BinaryOperator::CreateMul(Neg->getOperand(1), Cst, "",Neg);
+ ValueRankMap.erase(Neg);
Res->takeName(Neg);
Neg->replaceAllUsesWith(Res);
Res->setDebugLoc(Neg->getDebugLoc());
+ Neg->eraseFromParent();
return Res;
}
BinaryOperator *BO = dyn_cast<BinaryOperator>(Op);
if (Opcode == Instruction::Mul && BO && BinaryOperator::isNeg(BO)) {
DEBUG(dbgs() << "MORPH LEAF: " << *Op << " (" << Weight << ") TO ");
- BO = LowerNegateToMultiply(BO);
+ BO = LowerNegateToMultiply(BO, ValueRankMap);
DEBUG(dbgs() << *BO << 'n');
Worklist.push_back(std::make_pair(BO, Weight));
MadeChange = true;
// Throw away any left over nodes from the original expression.
for (unsigned i = 0, e = NodesToRewrite.size(); i != e; ++i)
- RedoInsts.insert(NodesToRewrite[i]);
+ RemoveDeadBinaryOp(NodesToRewrite[i]);
}
/// NegateValue - Insert instructions before the instruction pointed to by BI,
/// BreakUpSubtract - If we have (X-Y), and if either X is an add, or if this is
/// only used by an add, transform this into (X+(0-Y)) to promote better
/// reassociation.
-static BinaryOperator *BreakUpSubtract(Instruction *Sub) {
+static Instruction *BreakUpSubtract(Instruction *Sub,
+ DenseMap<AssertingVH<Value>, unsigned> &ValueRankMap) {
// Convert a subtract into an add and a neg instruction. This allows sub
// instructions to be commuted with other add instructions.
//
// and set it as the RHS of the add instruction we just made.
//
Value *NegVal = NegateValue(Sub->getOperand(1), Sub);
- BinaryOperator *New =
+ Instruction *New =
BinaryOperator::CreateAdd(Sub->getOperand(0), NegVal, "", Sub);
New->takeName(Sub);
// Everyone now refers to the add instruction.
+ ValueRankMap.erase(Sub);
Sub->replaceAllUsesWith(New);
New->setDebugLoc(Sub->getDebugLoc());
+ Sub->eraseFromParent();
DEBUG(dbgs() << "Negated: " << *New << '\n');
return New;
/// ConvertShiftToMul - If this is a shift of a reassociable multiply or is used
/// by one, change this into a multiply by a constant to assist with further
/// reassociation.
-static BinaryOperator *ConvertShiftToMul(Instruction *Shl) {
- Constant *MulCst = ConstantInt::get(Shl->getType(), 1);
- MulCst = ConstantExpr::getShl(MulCst, cast<Constant>(Shl->getOperand(1)));
-
- BinaryOperator *Mul =
- BinaryOperator::CreateMul(Shl->getOperand(0), MulCst, "", Shl);
- Mul->takeName(Shl);
- Shl->replaceAllUsesWith(Mul);
- Mul->setDebugLoc(Shl->getDebugLoc());
- return Mul;
+static Instruction *ConvertShiftToMul(Instruction *Shl,
+ DenseMap<AssertingVH<Value>, unsigned> &ValueRankMap) {
+ // If an operand of this shift is a reassociable multiply, or if the shift
+ // is used by a reassociable multiply or add, turn into a multiply.
+ if (isReassociableOp(Shl->getOperand(0), Instruction::Mul) ||
+ (Shl->hasOneUse() &&
+ (isReassociableOp(Shl->use_back(), Instruction::Mul) ||
+ isReassociableOp(Shl->use_back(), Instruction::Add)))) {
+ Constant *MulCst = ConstantInt::get(Shl->getType(), 1);
+ MulCst = ConstantExpr::getShl(MulCst, cast<Constant>(Shl->getOperand(1)));
+
+ Instruction *Mul =
+ BinaryOperator::CreateMul(Shl->getOperand(0), MulCst, "", Shl);
+ ValueRankMap.erase(Shl);
+ Mul->takeName(Shl);
+ Shl->replaceAllUsesWith(Mul);
+ Mul->setDebugLoc(Shl->getDebugLoc());
+ Shl->eraseFromParent();
+ return Mul;
+ }
+ return 0;
}
/// FindInOperandList - Scan backwards and forwards among values with the same
// If this was just a single multiply, remove the multiply and return the only
// remaining operand.
if (Factors.size() == 1) {
- RedoInsts.insert(BO);
+ RemoveDeadBinaryOp(BO);
V = Factors[0].Op;
} else {
RewriteExprTree(BO, Factors);
// Now that we have inserted a multiply, optimize it. This allows us to
// handle cases that require multiple factoring steps, such as this:
// (X*2) + (X*2) + (X*2) -> (X*2)*3 -> X*6
- RedoInsts.insert(cast<Instruction>(Mul));
+ RedoInsts.push_back(Mul);
// If every add operand was a duplicate, return the multiply.
if (Ops.empty())
// A*A*B + A*A*C --> A*(A*B+A*C) --> A*(A*(B+C))
assert(NumAddedValues > 1 && "Each occurrence should contribute a value");
(void)NumAddedValues;
- if (Instruction *VI = dyn_cast<Instruction>(V))
- RedoInsts.insert(VI);
+ RedoInsts.push_back(V);
// Create the multiply.
- Instruction *V2 = BinaryOperator::CreateMul(V, MaxOccVal, "tmp", I);
+ Value *V2 = BinaryOperator::CreateMul(V, MaxOccVal, "tmp", I);
// Rerun associate on the multiply in case the inner expression turned into
// a multiply. We want to make sure that we keep things in canonical form.
- RedoInsts.insert(V2);
+ RedoInsts.push_back(V2);
// If every add operand included the factor (e.g. "A*B + A*C"), then the
// entire result expression is just the multiply "A*(B+C)".
// Reset the base value of the first factor to the new expression tree.
// We'll remove all the factors with the same power in a second pass.
- Value *M = Factors[LastIdx].Base = buildMultiplyTree(Builder, InnerProduct);
- if (Instruction *MI = dyn_cast<Instruction>(M))
- RedoInsts.insert(MI);
+ Factors[LastIdx].Base = buildMultiplyTree(Builder, InnerProduct);
+ RedoInsts.push_back(Factors[LastIdx].Base);
LastIdx = Idx;
}
SmallVectorImpl<ValueEntry> &Ops) {
// Now that we have the linearized expression tree, try to optimize it.
// Start by folding any constants that we found.
+ bool IterateOptimization = false;
if (Ops.size() == 1) return Ops[0].Op;
unsigned Opcode = I->getOpcode();
break;
}
- if (Ops.size() != NumOps)
+ if (IterateOptimization || Ops.size() != NumOps)
return OptimizeExpression(I, Ops);
return 0;
}
-/// OptimizeInst - Inspect and optimize the given instruction, possibly erasing
-/// it.
-void Reassociate::OptimizeInst(Instruction *I) {
- // Reassociation can expose instructions as dead. Erasing them, removing uses,
- // can free up their operands for reassociation.
- if (isInstructionTriviallyDead(I)) {
- SmallVector<Value*, 8> Ops(I->op_begin(), I->op_end());
- // Erase the dead instruction.
- ValueRankMap.erase(I);
- I->eraseFromParent();
- // Optimize its operands.
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- if (Instruction *Op = dyn_cast<Instruction>(Ops[i])) {
- // If this is a node in an expression tree, climb to the expression root
- // and add that since that's where optimization actually happens.
- unsigned Opcode = Op->getOpcode();
- while (Op->hasOneUse() && Op->use_back()->getOpcode() == Opcode)
- Op = Op->use_back();
- RedoInsts.insert(Op);
- }
- return;
- }
-
- // Only consider operations that we understand.
- if (!isa<BinaryOperator>(I))
- return;
-
- if (I->getOpcode() == Instruction::Shl &&
- isa<ConstantInt>(I->getOperand(1)))
- // If an operand of this shift is a reassociable multiply, or if the shift
- // is used by a reassociable multiply or add, turn into a multiply.
- if (isReassociableOp(I->getOperand(0), Instruction::Mul) ||
- (I->hasOneUse() &&
- (isReassociableOp(I->use_back(), Instruction::Mul) ||
- isReassociableOp(I->use_back(), Instruction::Add)))) {
- Instruction *NI = ConvertShiftToMul(I);
- ValueRankMap.erase(I);
- I->eraseFromParent();
+/// ReassociateInst - Inspect and reassociate the instruction at the
+/// given position, post-incrementing the position.
+void Reassociate::ReassociateInst(BasicBlock::iterator &BBI) {
+ Instruction *BI = BBI++;
+ if (BI->getOpcode() == Instruction::Shl &&
+ isa<ConstantInt>(BI->getOperand(1)))
+ if (Instruction *NI = ConvertShiftToMul(BI, ValueRankMap)) {
MadeChange = true;
- I = NI;
+ BI = NI;
}
// Floating point binary operators are not associative, but we can still
// commute (some) of them, to canonicalize the order of their operands.
// This can potentially expose more CSE opportunities, and makes writing
// other transformations simpler.
- if ((I->getType()->isFloatingPointTy() || I->getType()->isVectorTy())) {
+ if (isa<BinaryOperator>(BI) &&
+ (BI->getType()->isFloatingPointTy() || BI->getType()->isVectorTy())) {
// FAdd and FMul can be commuted.
- if (I->getOpcode() != Instruction::FMul &&
- I->getOpcode() != Instruction::FAdd)
+ if (BI->getOpcode() != Instruction::FMul &&
+ BI->getOpcode() != Instruction::FAdd)
return;
- Value *LHS = I->getOperand(0);
- Value *RHS = I->getOperand(1);
+ Value *LHS = BI->getOperand(0);
+ Value *RHS = BI->getOperand(1);
unsigned LHSRank = getRank(LHS);
unsigned RHSRank = getRank(RHS);
// Sort the operands by rank.
if (RHSRank < LHSRank) {
- I->setOperand(0, RHS);
- I->setOperand(1, LHS);
+ BI->setOperand(0, RHS);
+ BI->setOperand(1, LHS);
}
return;
}
+ // Do not reassociate operations that we do not understand.
+ if (!isa<BinaryOperator>(BI))
+ return;
+
// Do not reassociate boolean (i1) expressions. We want to preserve the
// original order of evaluation for short-circuited comparisons that
// SimplifyCFG has folded to AND/OR expressions. If the expression
// is not further optimized, it is likely to be transformed back to a
// short-circuited form for code gen, and the source order may have been
// optimized for the most likely conditions.
- if (I->getType()->isIntegerTy(1))
+ if (BI->getType()->isIntegerTy(1))
return;
// If this is a subtract instruction which is not already in negate form,
// see if we can convert it to X+-Y.
- if (I->getOpcode() == Instruction::Sub) {
- if (ShouldBreakUpSubtract(I)) {
- Instruction *NI = BreakUpSubtract(I);
- ValueRankMap.erase(I);
- I->eraseFromParent();
+ if (BI->getOpcode() == Instruction::Sub) {
+ if (ShouldBreakUpSubtract(BI)) {
+ BI = BreakUpSubtract(BI, ValueRankMap);
+ // Reset the BBI iterator in case BreakUpSubtract changed the
+ // instruction it points to.
+ BBI = BI;
+ ++BBI;
MadeChange = true;
- I = NI;
- } else if (BinaryOperator::isNeg(I)) {
+ } else if (BinaryOperator::isNeg(BI)) {
// Otherwise, this is a negation. See if the operand is a multiply tree
// and if this is not an inner node of a multiply tree.
- if (isReassociableOp(I->getOperand(1), Instruction::Mul) &&
- (!I->hasOneUse() ||
- !isReassociableOp(I->use_back(), Instruction::Mul))) {
- Instruction *NI = LowerNegateToMultiply(I);
- ValueRankMap.erase(I);
- I->eraseFromParent();
+ if (isReassociableOp(BI->getOperand(1), Instruction::Mul) &&
+ (!BI->hasOneUse() ||
+ !isReassociableOp(BI->use_back(), Instruction::Mul))) {
+ BI = LowerNegateToMultiply(BI, ValueRankMap);
MadeChange = true;
- I = NI;
}
}
}
- // If this instruction is an associative binary operator, process it.
- if (!I->isAssociative()) return;
- BinaryOperator *BO = cast<BinaryOperator>(I);
+ // If this instruction is a commutative binary operator, process it.
+ if (!BI->isAssociative()) return;
+ BinaryOperator *I = cast<BinaryOperator>(BI);
// If this is an interior node of a reassociable tree, ignore it until we
// get to the root of the tree, to avoid N^2 analysis.
- if (BO->hasOneUse() && BO->use_back()->getOpcode() == BO->getOpcode())
+ if (I->hasOneUse() && isReassociableOp(I->use_back(), I->getOpcode()))
return;
// If this is an add tree that is used by a sub instruction, ignore it
// until we process the subtract.
- if (BO->hasOneUse() && BO->getOpcode() == Instruction::Add &&
- cast<Instruction>(BO->use_back())->getOpcode() == Instruction::Sub)
+ if (I->hasOneUse() && I->getOpcode() == Instruction::Add &&
+ cast<Instruction>(I->use_back())->getOpcode() == Instruction::Sub)
return;
- ReassociateExpression(BO);
+ ReassociateExpression(I);
}
Value *Reassociate::ReassociateExpression(BinaryOperator *I) {
I->replaceAllUsesWith(V);
if (Instruction *VI = dyn_cast<Instruction>(V))
VI->setDebugLoc(I->getDebugLoc());
- RedoInsts.insert(I);
+ RemoveDeadBinaryOp(I);
++NumAnnihil;
return V;
}
I->replaceAllUsesWith(Ops[0].Op);
if (Instruction *OI = dyn_cast<Instruction>(Ops[0].Op))
OI->setDebugLoc(I->getDebugLoc());
- RedoInsts.insert(I);
+ RemoveDeadBinaryOp(I);
return Ops[0].Op;
}
}
bool Reassociate::runOnFunction(Function &F) {
- // Calculate the rank map for F
+ // Recalculate the rank map for F
BuildRankMap(F);
MadeChange = false;
- for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI)
- for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE; ) {
- // Optimize the current instruction, possibly erasing it. If this creates
- // new instructions that need optimizing then optimize all such too before
- // moving on to the next instruction.
- RedoInsts.insert(AssertingVH<Instruction>(II));
- while (!RedoInsts.empty()) {
- Instruction *I = RedoInsts.pop_back_val();
- if ((Instruction*)II == I)
- ++II;
- OptimizeInst(I);
- }
+ for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
+ for (BasicBlock::iterator BBI = FI->begin(); BBI != FI->end(); )
+ ReassociateInst(BBI);
+
+ // Now that we're done, revisit any instructions which are likely to
+ // have secondary reassociation opportunities.
+ while (!RedoInsts.empty())
+ if (Value *V = RedoInsts.pop_back_val()) {
+ BasicBlock::iterator BBI = cast<Instruction>(V);
+ ReassociateInst(BBI);
}
// We are done with the rank map.
RankMap.clear();
ValueRankMap.clear();
+ // Now that we're done, delete any instructions which are no longer used.
+ while (!DeadInsts.empty())
+ if (Value *V = DeadInsts.pop_back_val())
+ RecursivelyDeleteTriviallyDeadInstructions(V);
+
return MadeChange;
}