#include "llvm/Transforms/Scalar.h"
#include "llvm/Instructions.h"
#include "llvm/Function.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE,
FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE,
FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT,
- SHUFFLE, SELECT };
+ SHUFFLE, SELECT, TRUNC, ZEXT, SEXT, FPTOUI,
+ FPTOSI, UITOFP, SITOFP, FPTRUNC, FPEXT,
+ PTRTOINT, INTTOPTR, BITCAST};
ExpressionOpcode opcode;
+ const Type* type;
uint32_t firstVN;
uint32_t secondVN;
uint32_t thirdVN;
return true;
else if (opcode > other.opcode)
return false;
+ else if (type < other.type)
+ return true;
+ else if (type > other.type)
+ return false;
else if (firstVN < other.firstVN)
return true;
else if (firstVN > other.firstVN)
Expression::ExpressionOpcode getOpcode(BinaryOperator* BO);
Expression::ExpressionOpcode getOpcode(CmpInst* C);
+ Expression::ExpressionOpcode getOpcode(CastInst* C);
Expression create_expression(BinaryOperator* BO);
Expression create_expression(CmpInst* C);
Expression create_expression(ShuffleVectorInst* V);
Expression create_expression(ExtractElementInst* C);
Expression create_expression(InsertElementInst* V);
Expression create_expression(SelectInst* V);
+ Expression create_expression(CastInst* C);
public:
ValueTable() { nextValueNumber = 1; }
uint32_t lookup_or_add(Value* V);
}
}
+ValueTable::Expression::ExpressionOpcode
+ ValueTable::getOpcode(CastInst* C) {
+ switch(C->getOpcode()) {
+ case Instruction::Trunc:
+ return Expression::TRUNC;
+ case Instruction::ZExt:
+ return Expression::ZEXT;
+ case Instruction::SExt:
+ return Expression::SEXT;
+ case Instruction::FPToUI:
+ return Expression::FPTOUI;
+ case Instruction::FPToSI:
+ return Expression::FPTOSI;
+ case Instruction::UIToFP:
+ return Expression::UITOFP;
+ case Instruction::SIToFP:
+ return Expression::SITOFP;
+ case Instruction::FPTrunc:
+ return Expression::FPTRUNC;
+ case Instruction::FPExt:
+ return Expression::FPEXT;
+ case Instruction::PtrToInt:
+ return Expression::PTRTOINT;
+ case Instruction::IntToPtr:
+ return Expression::INTTOPTR;
+ case Instruction::BitCast:
+ return Expression::BITCAST;
+
+ // THIS SHOULD NEVER HAPPEN
+ default:
+ assert(0 && "Cast operator with unknown opcode?");
+ return Expression::BITCAST;
+ }
+}
+
ValueTable::Expression ValueTable::create_expression(BinaryOperator* BO) {
Expression e;
e.firstVN = lookup_or_add(BO->getOperand(0));
e.secondVN = lookup_or_add(BO->getOperand(1));
e.thirdVN = 0;
+ e.type = BO->getType();
e.opcode = getOpcode(BO);
return e;
e.firstVN = lookup_or_add(C->getOperand(0));
e.secondVN = lookup_or_add(C->getOperand(1));
e.thirdVN = 0;
+ e.type = C->getType();
+ e.opcode = getOpcode(C);
+
+ return e;
+}
+
+ValueTable::Expression ValueTable::create_expression(CastInst* C) {
+ Expression e;
+
+ e.firstVN = lookup_or_add(C->getOperand(0));
+ e.secondVN = 0;
+ e.thirdVN = 0;
+ e.type = C->getType();
e.opcode = getOpcode(C);
return e;
e.firstVN = lookup_or_add(S->getOperand(0));
e.secondVN = lookup_or_add(S->getOperand(1));
e.thirdVN = lookup_or_add(S->getOperand(2));
+ e.type = S->getType();
e.opcode = Expression::SHUFFLE;
return e;
e.firstVN = lookup_or_add(E->getOperand(0));
e.secondVN = lookup_or_add(E->getOperand(1));
e.thirdVN = 0;
+ e.type = E->getType();
e.opcode = Expression::EXTRACT;
return e;
e.firstVN = lookup_or_add(I->getOperand(0));
e.secondVN = lookup_or_add(I->getOperand(1));
e.thirdVN = lookup_or_add(I->getOperand(2));
+ e.type = I->getType();
e.opcode = Expression::INSERT;
return e;
e.firstVN = lookup_or_add(I->getCondition());
e.secondVN = lookup_or_add(I->getTrueValue());
e.thirdVN = lookup_or_add(I->getFalseValue());
+ e.type = I->getType();
e.opcode = Expression::SELECT;
return e;
} else if (SelectInst* U = dyn_cast<SelectInst>(V)) {
Expression e = create_expression(U);
+ std::map<Expression, uint32_t>::iterator EI = expressionNumbering.find(e);
+ if (EI != expressionNumbering.end()) {
+ valueNumbering.insert(std::make_pair(V, EI->second));
+ return EI->second;
+ } else {
+ expressionNumbering.insert(std::make_pair(e, nextValueNumber));
+ valueNumbering.insert(std::make_pair(V, nextValueNumber));
+
+ return nextValueNumber++;
+ }
+ } else if (CastInst* U = dyn_cast<CastInst>(V)) {
+ Expression e = create_expression(U);
+
std::map<Expression, uint32_t>::iterator EI = expressionNumbering.find(e);
if (EI != expressionNumbering.end()) {
valueNumbering.insert(std::make_pair(V, EI->second));
if (V == 0)
return 0;
+ // Unary Operations
+ if (isa<CastInst>(V)) {
+ User* U = cast<User>(V);
+
+ Value* newOp1 = 0;
+ if (isa<Instruction>(U->getOperand(0)))
+ newOp1 = phi_translate(U->getOperand(0), pred, succ);
+ else
+ newOp1 = U->getOperand(0);
+
+ if (newOp1 == 0)
+ return 0;
+
+ if (newOp1 != U->getOperand(0)) {
+ Instruction* newVal = 0;
+ if (CastInst* C = dyn_cast<CastInst>(U))
+ newVal = CastInst::create(C->getOpcode(),
+ newOp1, C->getType(),
+ C->getName()+".expr");
+
+ uint32_t v = VN.lookup_or_add(newVal);
+
+ Value* leader = find_leader(availableOut[pred], v);
+ if (leader == 0) {
+ createdExpressions.push_back(newVal);
+ return newVal;
+ } else {
+ VN.erase(newVal);
+ delete newVal;
+ return leader;
+ }
+ }
+
// Binary Operations
- if (isa<BinaryOperator>(V) || isa<CmpInst>(V) ||
+ } if (isa<BinaryOperator>(V) || isa<CmpInst>(V) ||
isa<ExtractElementInst>(V)) {
User* U = cast<User>(V);
for (unsigned i = 0; i < worklist.size(); ++i) {
Value* v = worklist[i];
+ // Handle unary ops
+ if (isa<CastInst>(v)) {
+ User* U = cast<User>(v);
+
+ bool lhsValid = !isa<Instruction>(U->getOperand(0));
+ lhsValid |= presentInSet.test(VN.lookup(U->getOperand(0)));
+ if (lhsValid)
+ lhsValid = !dependsOnInvoke(U->getOperand(0));
+
+ if (!lhsValid) {
+ set.erase(U);
+ presentInSet.flip(VN.lookup(U));
+ }
+
// Handle binary ops
- if (isa<BinaryOperator>(v) || isa<CmpInst>(v) ||
+ } else if (isa<BinaryOperator>(v) || isa<CmpInst>(v) ||
isa<ExtractElementInst>(v)) {
User* U = cast<User>(v);
while (!stack.empty()) {
Value* e = stack.back();
-
+
+ // Handle unary ops
+ if (isa<CastInst>(e)) {
+ User* U = cast<User>(e);
+ Value* l = find_leader(set, VN.lookup(U->getOperand(0)));
+
+ if (l != 0 && isa<Instruction>(l) &&
+ visited.count(l) == 0)
+ stack.push_back(l);
+ else {
+ vec.push_back(e);
+ visited.insert(e);
+ stack.pop_back();
+ }
+
// Handle binary ops
- if (isa<BinaryOperator>(e) || isa<CmpInst>(e) ||
+ } else if (isa<BinaryOperator>(e) || isa<CmpInst>(e) ||
isa<ExtractElementInst>(e)) {
User* U = cast<User>(e);
Value* l = find_leader(set, VN.lookup(U->getOperand(0)));
if (isa<BinaryOperator>(BI) || isa<CmpInst>(BI) ||
isa<ShuffleVectorInst>(BI) || isa<InsertElementInst>(BI) ||
- isa<ExtractElementInst>(BI) || isa<SelectInst>(BI)) {
+ isa<ExtractElementInst>(BI) || isa<SelectInst>(BI) ||
+ isa<CastInst>(BI)) {
Value *leader = find_leader(availableOut[BB], VN.lookup(BI));
if (leader != 0)
availNumbers.resize(VN.size());
currPhis.insert(p);
+
+ // Handle unary ops
+ } else if (isa<CastInst>(I)) {
+ User* U = cast<User>(I);
+ Value* leftValue = U->getOperand(0);
+
+ unsigned num = VN.lookup_or_add(U);
+ expNumbers.resize(VN.size());
+ availNumbers.resize(VN.size());
+
+ if (isa<Instruction>(leftValue))
+ if (!expNumbers.test(VN.lookup(leftValue))) {
+ currExps.insert(leftValue);
+ expNumbers.set(VN.lookup(leftValue));
+ }
+ if (!expNumbers.test(VN.lookup(U))) {
+ currExps.insert(U);
+ expNumbers.set(num);
+ }
+
// Handle binary ops
} else if (isa<BinaryOperator>(I) || isa<CmpInst>(I) ||
isa<ExtractElementInst>(I)) {
isa<ShuffleVectorInst>(U->getOperand(0)) ||
isa<ExtractElementInst>(U->getOperand(0)) ||
isa<InsertElementInst>(U->getOperand(0)) ||
- isa<SelectInst>(U->getOperand(0)))
+ isa<SelectInst>(U->getOperand(0)) ||
+ isa<CastInst>(U->getOperand(0)))
s1 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(0)));
else
s1 = U->getOperand(0);
Value* s2 = 0;
- if (isa<BinaryOperator>(U->getOperand(1)) ||
- isa<CmpInst>(U->getOperand(1)) ||
- isa<ShuffleVectorInst>(U->getOperand(1)) ||
- isa<ExtractElementInst>(U->getOperand(1)) ||
- isa<InsertElementInst>(U->getOperand(1)) ||
- isa<SelectInst>(U->getOperand(1)))
- s2 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(1)));
- else
- s2 = U->getOperand(1);
+
+ if (isa<BinaryOperator>(U) ||
+ isa<CmpInst>(U) ||
+ isa<ShuffleVectorInst>(U) ||
+ isa<ExtractElementInst>(U) ||
+ isa<InsertElementInst>(U) ||
+ isa<SelectInst>(U))
+ if (isa<BinaryOperator>(U->getOperand(1)) ||
+ isa<CmpInst>(U->getOperand(1)) ||
+ isa<ShuffleVectorInst>(U->getOperand(1)) ||
+ isa<ExtractElementInst>(U->getOperand(1)) ||
+ isa<InsertElementInst>(U->getOperand(1)) ||
+ isa<SelectInst>(U->getOperand(1)) ||
+ isa<CastInst>(U->getOperand(1))) {
+ s2 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(1)));
+ } else {
+ s2 = U->getOperand(1);
+ }
// Ternary Operators
Value* s3 = 0;
isa<ShuffleVectorInst>(U->getOperand(2)) ||
isa<ExtractElementInst>(U->getOperand(2)) ||
isa<InsertElementInst>(U->getOperand(2)) ||
- isa<SelectInst>(U->getOperand(2)))
+ isa<SelectInst>(U->getOperand(2)) ||
+ isa<CastInst>(U->getOperand(2))) {
s3 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(2)));
- else
+ } else {
s3 = U->getOperand(2);
+ }
Value* newVal = 0;
if (BinaryOperator* BO = dyn_cast<BinaryOperator>(U))
newVal = new SelectInst(S->getCondition(), S->getTrueValue(),
S->getFalseValue(), S->getName()+".gvnpre",
(*PI)->getTerminator());
+ else if (CastInst* C = dyn_cast<CastInst>(U))
+ newVal = CastInst::create(C->getOpcode(), s1, C->getType(),
+ C->getName()+".gvnpre",
+ (*PI)->getTerminator());
VN.add(newVal, VN.lookup(U));
if (isa<BinaryOperator>(e) || isa<CmpInst>(e) ||
isa<ExtractElementInst>(e) || isa<InsertElementInst>(e) ||
- isa<ShuffleVectorInst>(e) || isa<SelectInst>(e)) {
+ isa<ShuffleVectorInst>(e) || isa<SelectInst>(e) || isa<CastInst>(e)) {
if (find_leader(availableOut[D->getIDom()->getBlock()],
VN.lookup(e)) != 0)
continue;