#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/Statistic.h"
#include <algorithm>
namespace {
class VISIBILITY_HIDDEN Reassociate : public FunctionPass {
std::map<BasicBlock*, unsigned> RankMap;
- std::map<Value*, unsigned> ValueRankMap;
+ std::map<AssertingVH<>, unsigned> ValueRankMap;
bool MadeChange;
public:
static char ID; // Pass identification, replacement for typeid
// Assign distinct ranks to function arguments
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
- ValueRankMap[I] = ++i;
+ ValueRankMap[&*I] = ++i;
ReversePostOrderTraversal<Function*> RPOT(&F);
for (ReversePostOrderTraversal<Function*>::rpo_iterator I = RPOT.begin(),
// all different in the block.
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
if (isUnmovableInstruction(I))
- ValueRankMap[I] = ++BBRank;
+ ValueRankMap[&*I] = ++BBRank;
}
}
/// LowerNegateToMultiply - Replace 0-X with X*-1.
///
-static Instruction *LowerNegateToMultiply(Instruction *Neg) {
- Constant *Cst = ConstantInt::getAllOnesValue(Neg->getType());
+static Instruction *LowerNegateToMultiply(Instruction *Neg,
+ std::map<AssertingVH<>, unsigned> &ValueRankMap,
+ LLVMContext &Context) {
+ Constant *Cst = Neg->getContext().getAllOnesValue(Neg->getType());
Instruction *Res = BinaryOperator::CreateMul(Neg->getOperand(1), Cst, "",Neg);
+ ValueRankMap.erase(Neg);
Res->takeName(Neg);
Neg->replaceAllUsesWith(Res);
Neg->eraseFromParent();
std::vector<ValueEntry> &Ops) {
Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
unsigned Opcode = I->getOpcode();
+ LLVMContext &Context = I->getContext();
// First step, linearize the expression if it is in ((A+B)+(C+D)) form.
BinaryOperator *LHSBO = isReassociableOp(LHS, Opcode);
// transform them into multiplies by -1 so they can be reassociated.
if (I->getOpcode() == Instruction::Mul) {
if (!LHSBO && LHS->hasOneUse() && BinaryOperator::isNeg(LHS)) {
- LHS = LowerNegateToMultiply(cast<Instruction>(LHS));
+ LHS = LowerNegateToMultiply(cast<Instruction>(LHS),
+ ValueRankMap, Context);
LHSBO = isReassociableOp(LHS, Opcode);
}
if (!RHSBO && RHS->hasOneUse() && BinaryOperator::isNeg(RHS)) {
- RHS = LowerNegateToMultiply(cast<Instruction>(RHS));
+ RHS = LowerNegateToMultiply(cast<Instruction>(RHS),
+ ValueRankMap, Context);
RHSBO = isReassociableOp(RHS, Opcode);
}
}
Ops.push_back(ValueEntry(getRank(RHS), RHS));
// Clear the leaves out.
- I->setOperand(0, UndefValue::get(I->getType()));
- I->setOperand(1, UndefValue::get(I->getType()));
+ I->setOperand(0, Context.getUndef(I->getType()));
+ I->setOperand(1, Context.getUndef(I->getType()));
return;
} else {
// Turn X+(Y+Z) -> (Y+Z)+X
Ops.push_back(ValueEntry(getRank(RHS), RHS));
// Clear the RHS leaf out.
- I->setOperand(1, UndefValue::get(I->getType()));
+ I->setOperand(1, Context.getUndef(I->getType()));
}
// RewriteExprTree - Now that the operands for this expression tree are
// 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, Instruction *BI) {
+static Value *NegateValue(LLVMContext &Context, Value *V, Instruction *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,
if (Instruction *I = dyn_cast<Instruction>(V))
if (I->getOpcode() == Instruction::Add && I->hasOneUse()) {
// Push the negates through the add.
- I->setOperand(0, NegateValue(I->getOperand(0), BI));
- I->setOperand(1, NegateValue(I->getOperand(1), BI));
+ I->setOperand(0, NegateValue(Context, I->getOperand(0), BI));
+ I->setOperand(1, NegateValue(Context, I->getOperand(1), BI));
// We must move the add instruction here, because the neg instructions do
// not dominate the old add instruction in general. By moving it, we are
// Insert a 'neg' instruction that subtracts the value from zero to get the
// negation.
//
- return BinaryOperator::CreateNeg(V, V->getName() + ".neg", BI);
+ return BinaryOperator::CreateNeg(Context, V, V->getName() + ".neg", BI);
}
/// ShouldBreakUpSubtract - Return true if we should break up this subtract of
/// X-Y into (X + -Y).
-static bool ShouldBreakUpSubtract(Instruction *Sub) {
+static bool ShouldBreakUpSubtract(LLVMContext &Context, Instruction *Sub) {
// If this is a negation, we can't split it up!
if (BinaryOperator::isNeg(Sub))
return false;
/// 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 Instruction *BreakUpSubtract(Instruction *Sub) {
+static Instruction *BreakUpSubtract(LLVMContext &Context, Instruction *Sub,
+ std::map<AssertingVH<>, unsigned> &ValueRankMap) {
// 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...
//
- Value *NegVal = NegateValue(Sub->getOperand(1), Sub);
+ Value *NegVal = NegateValue(Context, Sub->getOperand(1), Sub);
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);
Sub->eraseFromParent();
/// 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 Instruction *ConvertShiftToMul(Instruction *Shl) {
+static Instruction *ConvertShiftToMul(Instruction *Shl,
+ std::map<AssertingVH<>, unsigned> &ValueRankMap,
+ LLVMContext &Context) {
// 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) ||
(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)));
+ MulCst =
+ Context.getConstantExprShl(MulCst, cast<Constant>(Shl->getOperand(1)));
Instruction *Mul = BinaryOperator::CreateMul(Shl->getOperand(0), MulCst,
"", Shl);
+ ValueRankMap.erase(Shl);
Mul->takeName(Shl);
Shl->replaceAllUsesWith(Mul);
Shl->eraseFromParent();
bool IterateOptimization = false;
if (Ops.size() == 1) return Ops[0].Op;
+ LLVMContext &Context = I->getContext();
+
unsigned Opcode = I->getOpcode();
if (Constant *V1 = dyn_cast<Constant>(Ops[Ops.size()-2].Op))
if (Constant *V2 = dyn_cast<Constant>(Ops.back().Op)) {
Ops.pop_back();
- Ops.back().Op = ConstantExpr::get(Opcode, V1, V2);
+ Ops.back().Op = Context.getConstantExpr(Opcode, V1, V2);
return OptimizeExpression(I, Ops);
}
if (FoundX != i) {
if (Opcode == Instruction::And) { // ...&X&~X = 0
++NumAnnihil;
- return Constant::getNullValue(X->getType());
+ return Context.getNullValue(X->getType());
} else if (Opcode == Instruction::Or) { // ...|X|~X = -1
++NumAnnihil;
- return ConstantInt::getAllOnesValue(X->getType());
+ return Context.getAllOnesValue(X->getType());
}
}
}
assert(Opcode == Instruction::Xor);
if (e == 2) {
++NumAnnihil;
- return Constant::getNullValue(Ops[0].Op->getType());
+ return Context.getNullValue(Ops[0].Op->getType());
}
// ... X^X -> ...
Ops.erase(Ops.begin()+i, Ops.begin()+i+2);
// Remove X and -X from the operand list.
if (Ops.size() == 2) {
++NumAnnihil;
- return Constant::getNullValue(X->getType());
+ return Context.getNullValue(X->getType());
} else {
Ops.erase(Ops.begin()+i);
if (i < FoundX)
/// ReassociateBB - Inspect all of the instructions in this basic block,
/// reassociating them as we go.
void Reassociate::ReassociateBB(BasicBlock *BB) {
+ LLVMContext &Context = BB->getContext();
+
for (BasicBlock::iterator BBI = BB->begin(); BBI != BB->end(); ) {
Instruction *BI = BBI++;
if (BI->getOpcode() == Instruction::Shl &&
isa<ConstantInt>(BI->getOperand(1)))
- if (Instruction *NI = ConvertShiftToMul(BI)) {
+ if (Instruction *NI = ConvertShiftToMul(BI, ValueRankMap, Context)) {
MadeChange = true;
BI = NI;
}
// If this is a subtract instruction which is not already in negate form,
// see if we can convert it to X+-Y.
if (BI->getOpcode() == Instruction::Sub) {
- if (ShouldBreakUpSubtract(BI)) {
- BI = BreakUpSubtract(BI);
+ if (ShouldBreakUpSubtract(Context, BI)) {
+ BI = BreakUpSubtract(Context, BI, ValueRankMap);
MadeChange = true;
} else if (BinaryOperator::isNeg(BI)) {
// Otherwise, this is a negation. See if the operand is a multiply tree
if (isReassociableOp(BI->getOperand(1), Instruction::Mul) &&
(!BI->hasOneUse() ||
!isReassociableOp(BI->use_back(), Instruction::Mul))) {
- BI = LowerNegateToMultiply(BI);
+ BI = LowerNegateToMultiply(BI, ValueRankMap, Context);
MadeChange = true;
}
}