mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-22 23:24:59 +00:00
Simplify GVN's value expression structure, allowing the elimination of a lot of
almost-but-not-quite-identical code. No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122760 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -72,62 +72,20 @@ static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
|
|||||||
/// two values.
|
/// two values.
|
||||||
namespace {
|
namespace {
|
||||||
struct Expression {
|
struct Expression {
|
||||||
enum ExpressionOpcode {
|
uint32_t opcode;
|
||||||
ADD = Instruction::Add,
|
|
||||||
FADD = Instruction::FAdd,
|
|
||||||
SUB = Instruction::Sub,
|
|
||||||
FSUB = Instruction::FSub,
|
|
||||||
MUL = Instruction::Mul,
|
|
||||||
FMUL = Instruction::FMul,
|
|
||||||
UDIV = Instruction::UDiv,
|
|
||||||
SDIV = Instruction::SDiv,
|
|
||||||
FDIV = Instruction::FDiv,
|
|
||||||
UREM = Instruction::URem,
|
|
||||||
SREM = Instruction::SRem,
|
|
||||||
FREM = Instruction::FRem,
|
|
||||||
SHL = Instruction::Shl,
|
|
||||||
LSHR = Instruction::LShr,
|
|
||||||
ASHR = Instruction::AShr,
|
|
||||||
AND = Instruction::And,
|
|
||||||
OR = Instruction::Or,
|
|
||||||
XOR = Instruction::Xor,
|
|
||||||
TRUNC = Instruction::Trunc,
|
|
||||||
ZEXT = Instruction::ZExt,
|
|
||||||
SEXT = Instruction::SExt,
|
|
||||||
FPTOUI = Instruction::FPToUI,
|
|
||||||
FPTOSI = Instruction::FPToSI,
|
|
||||||
UITOFP = Instruction::UIToFP,
|
|
||||||
SITOFP = Instruction::SIToFP,
|
|
||||||
FPTRUNC = Instruction::FPTrunc,
|
|
||||||
FPEXT = Instruction::FPExt,
|
|
||||||
PTRTOINT = Instruction::PtrToInt,
|
|
||||||
INTTOPTR = Instruction::IntToPtr,
|
|
||||||
BITCAST = Instruction::BitCast,
|
|
||||||
ICMPEQ, ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE,
|
|
||||||
ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ,
|
|
||||||
FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE,
|
|
||||||
FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE,
|
|
||||||
FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT,
|
|
||||||
SHUFFLE, SELECT, GEP, CALL, CONSTANT,
|
|
||||||
INSERTVALUE, EXTRACTVALUE, EMPTY, TOMBSTONE };
|
|
||||||
|
|
||||||
ExpressionOpcode opcode;
|
|
||||||
const Type* type;
|
const Type* type;
|
||||||
SmallVector<uint32_t, 4> varargs;
|
SmallVector<uint32_t, 4> varargs;
|
||||||
Value *function;
|
|
||||||
|
|
||||||
Expression() { }
|
Expression() { }
|
||||||
Expression(ExpressionOpcode o) : opcode(o) { }
|
Expression(uint32_t o) : opcode(o) { }
|
||||||
|
|
||||||
bool operator==(const Expression &other) const {
|
bool operator==(const Expression &other) const {
|
||||||
if (opcode != other.opcode)
|
if (opcode != other.opcode)
|
||||||
return false;
|
return false;
|
||||||
else if (opcode == EMPTY || opcode == TOMBSTONE)
|
else if (opcode == ~0U || opcode == ~1U)
|
||||||
return true;
|
return true;
|
||||||
else if (type != other.type)
|
else if (type != other.type)
|
||||||
return false;
|
return false;
|
||||||
else if (function != other.function)
|
|
||||||
return false;
|
|
||||||
else if (varargs != other.varargs)
|
else if (varargs != other.varargs)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -148,19 +106,7 @@ namespace {
|
|||||||
|
|
||||||
uint32_t nextValueNumber;
|
uint32_t nextValueNumber;
|
||||||
|
|
||||||
Expression::ExpressionOpcode getOpcode(CmpInst* C);
|
Expression create_expression(Instruction* I);
|
||||||
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);
|
|
||||||
Expression create_expression(GetElementPtrInst* G);
|
|
||||||
Expression create_expression(CallInst* C);
|
|
||||||
Expression create_expression(ExtractValueInst* C);
|
|
||||||
Expression create_expression(InsertValueInst* C);
|
|
||||||
|
|
||||||
uint32_t lookup_or_add_call(CallInst* C);
|
uint32_t lookup_or_add_call(CallInst* C);
|
||||||
public:
|
public:
|
||||||
ValueTable() : nextValueNumber(1) { }
|
ValueTable() : nextValueNumber(1) { }
|
||||||
@@ -181,11 +127,11 @@ namespace {
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
template <> struct DenseMapInfo<Expression> {
|
template <> struct DenseMapInfo<Expression> {
|
||||||
static inline Expression getEmptyKey() {
|
static inline Expression getEmptyKey() {
|
||||||
return Expression(Expression::EMPTY);
|
return ~0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Expression getTombstoneKey() {
|
static inline Expression getTombstoneKey() {
|
||||||
return Expression(Expression::TOMBSTONE);
|
return ~1U;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned getHashValue(const Expression e) {
|
static unsigned getHashValue(const Expression e) {
|
||||||
@@ -197,11 +143,7 @@ template <> struct DenseMapInfo<Expression> {
|
|||||||
for (SmallVector<uint32_t, 4>::const_iterator I = e.varargs.begin(),
|
for (SmallVector<uint32_t, 4>::const_iterator I = e.varargs.begin(),
|
||||||
E = e.varargs.end(); I != E; ++I)
|
E = e.varargs.end(); I != E; ++I)
|
||||||
hash = *I + hash * 37;
|
hash = *I + hash * 37;
|
||||||
|
|
||||||
hash = ((unsigned)((uintptr_t)e.function >> 4) ^
|
|
||||||
(unsigned)((uintptr_t)e.function >> 9)) +
|
|
||||||
hash * 37;
|
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
static bool isEqual(const Expression &LHS, const Expression &RHS) {
|
static bool isEqual(const Expression &LHS, const Expression &RHS) {
|
||||||
@@ -215,185 +157,27 @@ template <> struct DenseMapInfo<Expression> {
|
|||||||
// ValueTable Internal Functions
|
// ValueTable Internal Functions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) {
|
|
||||||
if (isa<ICmpInst>(C)) {
|
Expression ValueTable::create_expression(Instruction *I) {
|
||||||
switch (C->getPredicate()) {
|
Expression e;
|
||||||
default: // THIS SHOULD NEVER HAPPEN
|
e.type = I->getType();
|
||||||
llvm_unreachable("Comparison with unknown predicate?");
|
e.opcode = I->getOpcode();
|
||||||
case ICmpInst::ICMP_EQ: return Expression::ICMPEQ;
|
for (Instruction::op_iterator OI = I->op_begin(), OE = I->op_end();
|
||||||
case ICmpInst::ICMP_NE: return Expression::ICMPNE;
|
OI != OE; ++OI)
|
||||||
case ICmpInst::ICMP_UGT: return Expression::ICMPUGT;
|
e.varargs.push_back(lookup_or_add(*OI));
|
||||||
case ICmpInst::ICMP_UGE: return Expression::ICMPUGE;
|
|
||||||
case ICmpInst::ICMP_ULT: return Expression::ICMPULT;
|
if (CmpInst *C = dyn_cast<CmpInst>(I))
|
||||||
case ICmpInst::ICMP_ULE: return Expression::ICMPULE;
|
e.opcode = (C->getOpcode() << 8) | C->getPredicate();
|
||||||
case ICmpInst::ICMP_SGT: return Expression::ICMPSGT;
|
else if (ExtractValueInst *E = dyn_cast<ExtractValueInst>(I)) {
|
||||||
case ICmpInst::ICMP_SGE: return Expression::ICMPSGE;
|
for (ExtractValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
|
||||||
case ICmpInst::ICMP_SLT: return Expression::ICMPSLT;
|
II != IE; ++II)
|
||||||
case ICmpInst::ICMP_SLE: return Expression::ICMPSLE;
|
e.varargs.push_back(*II);
|
||||||
}
|
} else if (InsertValueInst *E = dyn_cast<InsertValueInst>(I)) {
|
||||||
} else {
|
for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
|
||||||
switch (C->getPredicate()) {
|
II != IE; ++II)
|
||||||
default: // THIS SHOULD NEVER HAPPEN
|
e.varargs.push_back(*II);
|
||||||
llvm_unreachable("Comparison with unknown predicate?");
|
|
||||||
case FCmpInst::FCMP_OEQ: return Expression::FCMPOEQ;
|
|
||||||
case FCmpInst::FCMP_OGT: return Expression::FCMPOGT;
|
|
||||||
case FCmpInst::FCMP_OGE: return Expression::FCMPOGE;
|
|
||||||
case FCmpInst::FCMP_OLT: return Expression::FCMPOLT;
|
|
||||||
case FCmpInst::FCMP_OLE: return Expression::FCMPOLE;
|
|
||||||
case FCmpInst::FCMP_ONE: return Expression::FCMPONE;
|
|
||||||
case FCmpInst::FCMP_ORD: return Expression::FCMPORD;
|
|
||||||
case FCmpInst::FCMP_UNO: return Expression::FCMPUNO;
|
|
||||||
case FCmpInst::FCMP_UEQ: return Expression::FCMPUEQ;
|
|
||||||
case FCmpInst::FCMP_UGT: return Expression::FCMPUGT;
|
|
||||||
case FCmpInst::FCMP_UGE: return Expression::FCMPUGE;
|
|
||||||
case FCmpInst::FCMP_ULT: return Expression::FCMPULT;
|
|
||||||
case FCmpInst::FCMP_ULE: return Expression::FCMPULE;
|
|
||||||
case FCmpInst::FCMP_UNE: return Expression::FCMPUNE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(CallInst* C) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.type = C->getType();
|
|
||||||
e.function = C->getCalledFunction();
|
|
||||||
e.opcode = Expression::CALL;
|
|
||||||
|
|
||||||
CallSite CS(C);
|
|
||||||
for (CallInst::op_iterator I = CS.arg_begin(), E = CS.arg_end();
|
|
||||||
I != E; ++I)
|
|
||||||
e.varargs.push_back(lookup_or_add(*I));
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(BinaryOperator* BO) {
|
|
||||||
Expression e;
|
|
||||||
e.varargs.push_back(lookup_or_add(BO->getOperand(0)));
|
|
||||||
e.varargs.push_back(lookup_or_add(BO->getOperand(1)));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = BO->getType();
|
|
||||||
e.opcode = static_cast<Expression::ExpressionOpcode>(BO->getOpcode());
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(CmpInst* C) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(C->getOperand(0)));
|
|
||||||
e.varargs.push_back(lookup_or_add(C->getOperand(1)));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = C->getType();
|
|
||||||
e.opcode = getOpcode(C);
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(CastInst* C) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(C->getOperand(0)));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = C->getType();
|
|
||||||
e.opcode = static_cast<Expression::ExpressionOpcode>(C->getOpcode());
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(ShuffleVectorInst* S) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(S->getOperand(0)));
|
|
||||||
e.varargs.push_back(lookup_or_add(S->getOperand(1)));
|
|
||||||
e.varargs.push_back(lookup_or_add(S->getOperand(2)));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = S->getType();
|
|
||||||
e.opcode = Expression::SHUFFLE;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(ExtractElementInst* E) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(E->getOperand(0)));
|
|
||||||
e.varargs.push_back(lookup_or_add(E->getOperand(1)));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = E->getType();
|
|
||||||
e.opcode = Expression::EXTRACT;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(InsertElementInst* I) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(I->getOperand(0)));
|
|
||||||
e.varargs.push_back(lookup_or_add(I->getOperand(1)));
|
|
||||||
e.varargs.push_back(lookup_or_add(I->getOperand(2)));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = I->getType();
|
|
||||||
e.opcode = Expression::INSERT;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(SelectInst* I) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(I->getCondition()));
|
|
||||||
e.varargs.push_back(lookup_or_add(I->getTrueValue()));
|
|
||||||
e.varargs.push_back(lookup_or_add(I->getFalseValue()));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = I->getType();
|
|
||||||
e.opcode = Expression::SELECT;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(GetElementPtrInst* G) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(G->getPointerOperand()));
|
|
||||||
e.function = 0;
|
|
||||||
e.type = G->getType();
|
|
||||||
e.opcode = Expression::GEP;
|
|
||||||
|
|
||||||
for (GetElementPtrInst::op_iterator I = G->idx_begin(), E = G->idx_end();
|
|
||||||
I != E; ++I)
|
|
||||||
e.varargs.push_back(lookup_or_add(*I));
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(ExtractValueInst* E) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(E->getAggregateOperand()));
|
|
||||||
for (ExtractValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
|
|
||||||
II != IE; ++II)
|
|
||||||
e.varargs.push_back(*II);
|
|
||||||
e.function = 0;
|
|
||||||
e.type = E->getType();
|
|
||||||
e.opcode = Expression::EXTRACTVALUE;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression ValueTable::create_expression(InsertValueInst* E) {
|
|
||||||
Expression e;
|
|
||||||
|
|
||||||
e.varargs.push_back(lookup_or_add(E->getAggregateOperand()));
|
|
||||||
e.varargs.push_back(lookup_or_add(E->getInsertedValueOperand()));
|
|
||||||
for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
|
|
||||||
II != IE; ++II)
|
|
||||||
e.varargs.push_back(*II);
|
|
||||||
e.function = 0;
|
|
||||||
e.type = E->getType();
|
|
||||||
e.opcode = Expression::INSERTVALUE;
|
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,12 +336,8 @@ uint32_t ValueTable::lookup_or_add(Value *V) {
|
|||||||
case Instruction::And:
|
case Instruction::And:
|
||||||
case Instruction::Or :
|
case Instruction::Or :
|
||||||
case Instruction::Xor:
|
case Instruction::Xor:
|
||||||
exp = create_expression(cast<BinaryOperator>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::ICmp:
|
case Instruction::ICmp:
|
||||||
case Instruction::FCmp:
|
case Instruction::FCmp:
|
||||||
exp = create_expression(cast<CmpInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::Trunc:
|
case Instruction::Trunc:
|
||||||
case Instruction::ZExt:
|
case Instruction::ZExt:
|
||||||
case Instruction::SExt:
|
case Instruction::SExt:
|
||||||
@@ -570,28 +350,14 @@ uint32_t ValueTable::lookup_or_add(Value *V) {
|
|||||||
case Instruction::PtrToInt:
|
case Instruction::PtrToInt:
|
||||||
case Instruction::IntToPtr:
|
case Instruction::IntToPtr:
|
||||||
case Instruction::BitCast:
|
case Instruction::BitCast:
|
||||||
exp = create_expression(cast<CastInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::Select:
|
case Instruction::Select:
|
||||||
exp = create_expression(cast<SelectInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::ExtractElement:
|
case Instruction::ExtractElement:
|
||||||
exp = create_expression(cast<ExtractElementInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::InsertElement:
|
case Instruction::InsertElement:
|
||||||
exp = create_expression(cast<InsertElementInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::ShuffleVector:
|
case Instruction::ShuffleVector:
|
||||||
exp = create_expression(cast<ShuffleVectorInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::ExtractValue:
|
case Instruction::ExtractValue:
|
||||||
exp = create_expression(cast<ExtractValueInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::InsertValue:
|
case Instruction::InsertValue:
|
||||||
exp = create_expression(cast<InsertValueInst>(I));
|
|
||||||
break;
|
|
||||||
case Instruction::GetElementPtr:
|
case Instruction::GetElementPtr:
|
||||||
exp = create_expression(cast<GetElementPtrInst>(I));
|
exp = create_expression(I);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
valueNumbering[V] = nextValueNumber;
|
valueNumbering[V] = nextValueNumber;
|
||||||
|
Reference in New Issue
Block a user