// live ranges, and should be used with caution on platforms that are very
// sensitive to register pressure.
//
+// Note that this pass does the value numbering itself, it does not use the
+// ValueNumbering analysis passes.
+//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "gvnpre"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <deque>
#include <map>
// ValueTable Class
//===----------------------------------------------------------------------===//
+namespace {
+
/// This class holds the mapping between values and value numbers. It is used
/// as an efficient mechanism to determine the expression-wise equivalence of
/// two values.
struct Expression {
- enum ExpressionOpcode { ADD, SUB, MUL, UDIV, SDIV, FDIV, UREM, SREM,
+ enum ExpressionOpcode { ADD, FADD, SUB, FSUB, MUL, FMUL,
+ UDIV, SDIV, FDIV, UREM, SREM,
FREM, SHL, LSHR, ASHR, AND, OR, XOR, ICMPEQ,
ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE,
ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ,
}
};
+}
namespace {
class VISIBILITY_HIDDEN ValueTable {
hash = e.secondVN + hash * 37;
hash = e.thirdVN + hash * 37;
- hash = (unsigned)((uintptr_t)e.type >> 4) ^
- (unsigned)((uintptr_t)e.type >> 9) +
- hash * 37;
+ hash = ((unsigned)((uintptr_t)e.type >> 4) ^
+ (unsigned)((uintptr_t)e.type >> 9)) +
+ hash * 37;
for (SmallVector<uint32_t, 4>::const_iterator I = e.varargs.begin(),
E = e.varargs.end(); I != E; ++I)
switch(BO->getOpcode()) {
case Instruction::Add:
return Expression::ADD;
+ case Instruction::FAdd:
+ return Expression::FADD;
case Instruction::Sub:
return Expression::SUB;
+ case Instruction::FSub:
+ return Expression::FSUB;
case Instruction::Mul:
return Expression::MUL;
+ case Instruction::FMul:
+ return Expression::FMUL;
case Instruction::UDiv:
return Expression::UDIV;
case Instruction::SDiv:
// THIS SHOULD NEVER HAPPEN
default:
- assert(0 && "Binary operator with unknown opcode?");
+ llvm_unreachable("Binary operator with unknown opcode?");
return Expression::ADD;
}
}
// THIS SHOULD NEVER HAPPEN
default:
- assert(0 && "Comparison with unknown predicate?");
+ llvm_unreachable("Comparison with unknown predicate?");
return Expression::ICMPEQ;
}
} else {
// THIS SHOULD NEVER HAPPEN
default:
- assert(0 && "Comparison with unknown predicate?");
+ llvm_unreachable("Comparison with unknown predicate?");
return Expression::FCMPOEQ;
}
}
// THIS SHOULD NEVER HAPPEN
default:
- assert(0 && "Cast operator with unknown opcode?");
+ llvm_unreachable("Cast operator with unknown opcode?");
return Expression::BITCAST;
}
}
if (VI != valueNumbering.end())
return VI->second;
else
- assert(0 && "Value not numbered?");
+ llvm_unreachable("Value not numbered?");
return 0;
}
return nextValueNumber;
}
+namespace {
+
//===----------------------------------------------------------------------===//
// ValueNumberedSet Class
//===----------------------------------------------------------------------===//
}
};
+}
+
//===----------------------------------------------------------------------===//
// GVNPRE Pass
//===----------------------------------------------------------------------===//
bool runOnFunction(Function &F);
public:
static char ID; // Pass identification, replacement for typeid
- GVNPRE() : FunctionPass((intptr_t)&ID) { }
+ GVNPRE() : FunctionPass(&ID) {}
private:
ValueTable VN;
if (v == VN.lookup(*I))
return *I;
- assert(0 && "No leader found, but present bit is set?");
+ llvm_unreachable("No leader found, but present bit is set?");
return 0;
}
Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) {
if (V == 0)
return 0;
+
+ LLVMContext &Context = V->getContext();
// Unary Operations
if (CastInst* U = dyn_cast<CastInst>(V)) {
if (newOp1 != U->getOperand(0)) {
Instruction* newVal = 0;
if (CastInst* C = dyn_cast<CastInst>(U))
- newVal = CastInst::create(C->getOpcode(),
+ newVal = CastInst::Create(C->getOpcode(),
newOp1, C->getType(),
C->getName()+".expr");
if (newOp1 != U->getOperand(0) || newOp2 != U->getOperand(1)) {
Instruction* newVal = 0;
if (BinaryOperator* BO = dyn_cast<BinaryOperator>(U))
- newVal = BinaryOperator::create(BO->getOpcode(),
+ newVal = BinaryOperator::Create(BO->getOpcode(),
newOp1, newOp2,
BO->getName()+".expr");
else if (CmpInst* C = dyn_cast<CmpInst>(U))
- newVal = CmpInst::create(C->getOpcode(),
+ newVal = CmpInst::Create(Context, C->getOpcode(),
C->getPredicate(),
newOp1, newOp2,
C->getName()+".expr");
else if (ExtractElementInst* E = dyn_cast<ExtractElementInst>(U))
- newVal = new ExtractElementInst(newOp1, newOp2, E->getName()+".expr");
+ newVal = ExtractElementInst::Create(newOp1, newOp2,
+ E->getName()+".expr");
uint32_t v = VN.lookup_or_add(newVal);
Instruction* newVal = 0;
if (ShuffleVectorInst* S = dyn_cast<ShuffleVectorInst>(U))
newVal = new ShuffleVectorInst(newOp1, newOp2, newOp3,
- S->getName()+".expr");
+ S->getName() + ".expr");
else if (InsertElementInst* I = dyn_cast<InsertElementInst>(U))
- newVal = new InsertElementInst(newOp1, newOp2, newOp3,
- I->getName()+".expr");
+ newVal = InsertElementInst::Create(newOp1, newOp2, newOp3,
+ I->getName() + ".expr");
else if (SelectInst* I = dyn_cast<SelectInst>(U))
- newVal = new SelectInst(newOp1, newOp2, newOp3, I->getName()+".expr");
+ newVal = SelectInst::Create(newOp1, newOp2, newOp3,
+ I->getName() + ".expr");
uint32_t v = VN.lookup_or_add(newVal);
}
if (newOp1 != U->getPointerOperand() || changed_idx) {
- Instruction* newVal = new GetElementPtrInst(newOp1,
- newIdx.begin(), newIdx.end(),
- U->getName()+".expr");
+ Instruction* newVal =
+ GetElementPtrInst::Create(newOp1,
+ newIdx.begin(), newIdx.end(),
+ U->getName()+".expr");
uint32_t v = VN.lookup_or_add(newVal);
void GVNPRE::insertion_pre(Value* e, BasicBlock* BB,
DenseMap<BasicBlock*, Value*>& avail,
std::map<BasicBlock*, ValueNumberedSet>& new_sets) {
+ LLVMContext &Context = e->getContext();
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
Value* e2 = avail[*PI];
if (!availableOut[*PI].test(VN.lookup(e2))) {
isa<ShuffleVectorInst>(U) ||
isa<ExtractElementInst>(U) ||
isa<InsertElementInst>(U) ||
- isa<SelectInst>(U))
+ isa<SelectInst>(U)) {
if (isa<BinaryOperator>(U->getOperand(1)) ||
isa<CmpInst>(U->getOperand(1)) ||
isa<ShuffleVectorInst>(U->getOperand(1)) ||
} else {
s2 = U->getOperand(1);
}
+ }
// Ternary Operators
Value* s3 = 0;
if (isa<ShuffleVectorInst>(U) ||
isa<InsertElementInst>(U) ||
- isa<SelectInst>(U))
+ isa<SelectInst>(U)) {
if (isa<BinaryOperator>(U->getOperand(2)) ||
isa<CmpInst>(U->getOperand(2)) ||
isa<ShuffleVectorInst>(U->getOperand(2)) ||
} else {
s3 = U->getOperand(2);
}
+ }
// Vararg operators
SmallVector<Value*, 4> sVarargs;
Value* newVal = 0;
if (BinaryOperator* BO = dyn_cast<BinaryOperator>(U))
- newVal = BinaryOperator::create(BO->getOpcode(), s1, s2,
+ newVal = BinaryOperator::Create(BO->getOpcode(), s1, s2,
BO->getName()+".gvnpre",
(*PI)->getTerminator());
else if (CmpInst* C = dyn_cast<CmpInst>(U))
- newVal = CmpInst::create(C->getOpcode(), C->getPredicate(), s1, s2,
+ newVal = CmpInst::Create(Context, C->getOpcode(),
+ C->getPredicate(), s1, s2,
C->getName()+".gvnpre",
(*PI)->getTerminator());
else if (ShuffleVectorInst* S = dyn_cast<ShuffleVectorInst>(U))
newVal = new ShuffleVectorInst(s1, s2, s3, S->getName()+".gvnpre",
(*PI)->getTerminator());
else if (InsertElementInst* S = dyn_cast<InsertElementInst>(U))
- newVal = new InsertElementInst(s1, s2, s3, S->getName()+".gvnpre",
- (*PI)->getTerminator());
+ newVal = InsertElementInst::Create(s1, s2, s3, S->getName()+".gvnpre",
+ (*PI)->getTerminator());
else if (ExtractElementInst* S = dyn_cast<ExtractElementInst>(U))
- newVal = new ExtractElementInst(s1, s2, S->getName()+".gvnpre",
+ newVal = ExtractElementInst::Create(s1, s2, S->getName()+".gvnpre",
(*PI)->getTerminator());
else if (SelectInst* S = dyn_cast<SelectInst>(U))
- newVal = new SelectInst(s1, s2, s3, S->getName()+".gvnpre",
- (*PI)->getTerminator());
+ newVal = SelectInst::Create(s1, s2, s3, S->getName()+".gvnpre",
+ (*PI)->getTerminator());
else if (CastInst* C = dyn_cast<CastInst>(U))
- newVal = CastInst::create(C->getOpcode(), s1, C->getType(),
+ newVal = CastInst::Create(C->getOpcode(), s1, C->getType(),
C->getName()+".gvnpre",
(*PI)->getTerminator());
else if (GetElementPtrInst* G = dyn_cast<GetElementPtrInst>(U))
- newVal = new GetElementPtrInst(s1, sVarargs.begin(), sVarargs.end(),
- G->getName()+".gvnpre",
- (*PI)->getTerminator());
-
-
+ newVal = GetElementPtrInst::Create(s1, sVarargs.begin(), sVarargs.end(),
+ G->getName()+".gvnpre",
+ (*PI)->getTerminator());
+
VN.add(newVal, VN.lookup(U));
ValueNumberedSet& predAvail = availableOut[*PI];
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
if (p == 0)
- p = new PHINode(avail[*PI]->getType(), "gvnpre-join", BB->begin());
+ p = PHINode::Create(avail[*PI]->getType(), "gvnpre-join", BB->begin());
p->addIncoming(avail[*PI], *PI);
}