//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/DerivedTypes.h"
#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>
+#include <map>
using namespace llvm;
STATISTIC(NumLinear , "Number of insts linearized");
}
}
+#ifndef NDEBUG
/// PrintOps - Print out the expression identified in the Ops list.
///
static void PrintOps(Instruction *I, const std::vector<ValueEntry> &Ops) {
Module *M = I->getParent()->getParent()->getParent();
cerr << Instruction::getOpcodeName(I->getOpcode()) << " "
- << *Ops[0].Op->getType();
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- WriteAsOperand(*cerr.stream() << " ", Ops[i].Op, false, M)
- << "," << Ops[i].Rank;
+ << *Ops[0].Op->getType();
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
+ WriteAsOperand(*cerr.stream() << " ", Ops[i].Op, false, M);
+ cerr << "," << Ops[i].Rank;
+ }
}
+#endif
-namespace {
+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
+ Reassociate() : FunctionPass(&ID) {}
+
bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
void RemoveDeadBinaryOp(Value *V);
};
-
- RegisterPass<Reassociate> X("reassociate", "Reassociate expressions");
}
+char Reassociate::ID = 0;
+static RegisterPass<Reassociate> X("reassociate", "Reassociate expressions");
+
// Public interface to the Reassociate pass
FunctionPass *llvm::createReassociatePass() { return new Reassociate(); }
I->getOpcode() == Instruction::Load ||
I->getOpcode() == Instruction::Malloc ||
I->getOpcode() == Instruction::Invoke ||
- I->getOpcode() == Instruction::Call ||
+ (I->getOpcode() == Instruction::Call &&
+ !isa<DbgInfoIntrinsic>(I)) ||
I->getOpcode() == Instruction::UDiv ||
I->getOpcode() == Instruction::SDiv ||
I->getOpcode() == Instruction::FDiv ||
// 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);
+ 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
std::swap(LHS, RHS);
bool Success = !I->swapOperands();
assert(Success && "swapOperands failed");
+ Success = false;
MadeChange = true;
}
} else if (RHSBO) {
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(LLVMContext &Context, Instruction *Sub) {
+ // If this is a negation, we can't split it up!
+ if (BinaryOperator::isNeg(Sub))
+ return false;
+
+ // Don't bother to break this up unless either the LHS is an associable add or
+ // subtract or if this is only used by one.
+ if (isReassociableOp(Sub->getOperand(0), Instruction::Add) ||
+ isReassociableOp(Sub->getOperand(0), Instruction::Sub))
+ return true;
+ if (isReassociableOp(Sub->getOperand(1), Instruction::Add) ||
+ isReassociableOp(Sub->getOperand(1), Instruction::Sub))
+ return true;
+ if (Sub->hasOneUse() &&
+ (isReassociableOp(Sub->use_back(), Instruction::Add) ||
+ isReassociableOp(Sub->use_back(), Instruction::Sub)))
+ return true;
+
+ 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) {
- // Don't bother to break this up unless either the LHS is an associable add or
- // if this is only used by one.
- if (!isReassociableOp(Sub->getOperand(0), Instruction::Add) &&
- !isReassociableOp(Sub->getOperand(1), Instruction::Add) &&
- !(Sub->hasOneUse() &&isReassociableOp(Sub->use_back(), Instruction::Add)))
- return 0;
-
+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);
+ 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,
+ Instruction *Mul = BinaryOperator::CreateMul(Shl->getOperand(0), MulCst,
"", Shl);
+ ValueRankMap.erase(Shl);
Mul->takeName(Shl);
Shl->replaceAllUsesWith(Mul);
Shl->eraseFromParent();
Value *V1 = Ops.back();
Ops.pop_back();
Value *V2 = EmitAddTreeOfValues(I, Ops);
- return BinaryOperator::createAdd(V2, V1, "tmp", I);
+ return BinaryOperator::CreateAdd(V2, V1, "tmp", I);
}
/// RemoveFactorFromExpression - If V is an expression tree that is a
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);
}
switch (Opcode) {
default: break;
case Instruction::And:
- if (CstVal->isNullValue()) { // ... & 0 -> 0
+ if (CstVal->isZero()) { // ... & 0 -> 0
++NumAnnihil;
return CstVal;
} else if (CstVal->isAllOnesValue()) { // ... & -1 -> ...
}
break;
case Instruction::Mul:
- if (CstVal->isNullValue()) { // ... * 0 -> 0
+ if (CstVal->isZero()) { // ... * 0 -> 0
++NumAnnihil;
return CstVal;
- } else if (cast<ConstantInt>(CstVal)->getZExtValue() == 1) {
+ } else if (cast<ConstantInt>(CstVal)->isOne()) {
Ops.pop_back(); // ... * 1 -> ...
}
break;
// FALLTHROUGH!
case Instruction::Add:
case Instruction::Xor:
- if (CstVal->isNullValue()) // ... [|^+] 0 -> ...
+ if (CstVal->isZero()) // ... [|^+] 0 -> ...
Ops.pop_back();
break;
}
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)
// this, we could otherwise run into situations where removing a factor
// from an expression will drop a use of maxocc, and this can cause
// RemoveFactorFromExpression on successive values to behave differently.
- Instruction *DummyInst = BinaryOperator::createAdd(MaxOccVal, MaxOccVal);
+ Instruction *DummyInst = BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal);
std::vector<Value*> NewMulOps;
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
if (Value *V = RemoveFactorFromExpression(Ops[i].Op, MaxOccVal)) {
unsigned NumAddedValues = NewMulOps.size();
Value *V = EmitAddTreeOfValues(I, NewMulOps);
- Value *V2 = BinaryOperator::createMul(V, MaxOccVal, "tmp", I);
+ Value *V2 = BinaryOperator::CreateMul(V, MaxOccVal, "tmp", I);
// Now that we have inserted V and its sole use, optimize it. This allows
// us to handle cases that require multiple factoring steps, such as this:
++NumFactor;
- if (Ops.size() == 0)
+ if (Ops.empty())
return V2;
// Add the new value to the list of things being added.
/// 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 (!BinaryOperator::isNeg(BI)) {
- if (Instruction *NI = BreakUpSubtract(BI)) {
- MadeChange = true;
- BI = NI;
- }
- } else {
+ 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
// and if this is not an inner node of 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;
}
}