[llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp
Reid Spencer
reid at x10sys.com
Sun Dec 3 21:20:05 PST 2006
Changes in directory llvm/lib/VMCore:
Constants.cpp updated: 1.175 -> 1.176
---
Log message:
For PR950: http://llvm.org/PR950 : Fix constant expressions to properly support ICmp and FCmp type expressions.
---
Diffs of the changes: (+127 -59)
Constants.cpp | 186 +++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 127 insertions(+), 59 deletions(-)
Index: llvm/lib/VMCore/Constants.cpp
diff -u llvm/lib/VMCore/Constants.cpp:1.175 llvm/lib/VMCore/Constants.cpp:1.176
--- llvm/lib/VMCore/Constants.cpp:1.175 Sun Dec 3 20:43:42 2006
+++ llvm/lib/VMCore/Constants.cpp Sun Dec 3 23:19:50 2006
@@ -442,6 +442,10 @@
return Instruction::isCast(getOpcode());
}
+bool ConstantExpr::isCompare() const {
+ return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
+}
+
/// ConstantExpr::get* - Return some common constants without having to
/// specify the full Instruction::OPCODE identifier.
///
@@ -510,23 +514,6 @@
Constant *ConstantExpr::getSetGE(Constant *C1, Constant *C2) {
return get(Instruction::SetGE, C1, C2);
}
-Constant *
-ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
- assert(LHS->getType() == RHS->getType());
- assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
- pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
- CompareConstantExpr *Result =
- new CompareConstantExpr(Instruction::ICmp, pred, LHS, RHS);
- return Result;
-}
-Constant *
-ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
- assert(LHS->getType() == RHS->getType());
- assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid ICmp Predicate");
- CompareConstantExpr *Result =
- new CompareConstantExpr(Instruction::FCmp, pred, LHS, RHS);
- return Result;
-}
unsigned ConstantExpr::getPredicate() const {
assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
return dynamic_cast<const CompareConstantExpr*>(this)->predicate;
@@ -1370,41 +1357,68 @@
//---- ConstantExpr::get() implementations...
//
-typedef std::pair<unsigned, std::vector<Constant*> > ExprMapKeyType;
+struct ExprMapKeyType {
+ explicit ExprMapKeyType(unsigned opc, std::vector<Constant*> ops,
+ unsigned short pred = 0) : opcode(opc), operands(ops), predicate(pred) { }
+ unsigned opcode;
+ std::vector<Constant*> operands;
+ unsigned short predicate;
+ bool operator==(const ExprMapKeyType& that) const {
+ return this->opcode == that.opcode &&
+ this->predicate == that.predicate &&
+ this->operands == that.operands;
+ }
+ bool operator<(const ExprMapKeyType & that) const {
+ return this->opcode < that.opcode ||
+ (this->opcode == that.opcode && this->predicate < that.predicate) ||
+ (this->opcode == that.opcode && this->predicate == that.predicate &&
+ this->operands < that.operands);
+ }
+
+ bool operator!=(const ExprMapKeyType& that) const {
+ return !(*this == that);
+ }
+};
namespace llvm {
template<>
struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V,
unsigned short pred = 0) {
- if (Instruction::isCast(V.first))
- return new UnaryConstantExpr(V.first, V.second[0], Ty);
- if ((V.first >= Instruction::BinaryOpsBegin &&
- V.first < Instruction::BinaryOpsEnd) ||
- V.first == Instruction::Shl ||
- V.first == Instruction::LShr ||
- V.first == Instruction::AShr)
- return new BinaryConstantExpr(V.first, V.second[0], V.second[1]);
- if (V.first == Instruction::Select)
- return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]);
- if (V.first == Instruction::ExtractElement)
- return new ExtractElementConstantExpr(V.second[0], V.second[1]);
- if (V.first == Instruction::InsertElement)
- return new InsertElementConstantExpr(V.second[0], V.second[1],
- V.second[2]);
- if (V.first == Instruction::ShuffleVector)
- return new ShuffleVectorConstantExpr(V.second[0], V.second[1],
- V.second[2]);
- if (V.first == Instruction::ICmp)
- return new CompareConstantExpr(Instruction::ICmp, pred,
- V.second[0], V.second[1]);
- if (V.first == Instruction::FCmp)
- return new CompareConstantExpr(Instruction::FCmp, pred,
- V.second[0], V.second[1]);
-
- assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
- std::vector<Constant*> IdxList(V.second.begin()+1, V.second.end());
- return new GetElementPtrConstantExpr(V.second[0], IdxList, Ty);
+ if (Instruction::isCast(V.opcode))
+ return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
+ if ((V.opcode >= Instruction::BinaryOpsBegin &&
+ V.opcode < Instruction::BinaryOpsEnd) ||
+ V.opcode == Instruction::Shl ||
+ V.opcode == Instruction::LShr ||
+ V.opcode == Instruction::AShr)
+ return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]);
+ if (V.opcode == Instruction::Select)
+ return new SelectConstantExpr(V.operands[0], V.operands[1],
+ V.operands[2]);
+ if (V.opcode == Instruction::ExtractElement)
+ return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
+ if (V.opcode == Instruction::InsertElement)
+ return new InsertElementConstantExpr(V.operands[0], V.operands[1],
+ V.operands[2]);
+ if (V.opcode == Instruction::ShuffleVector)
+ return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
+ V.operands[2]);
+ if (V.opcode == Instruction::GetElementPtr) {
+ std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
+ return new GetElementPtrConstantExpr(V.operands[0], IdxList, Ty);
+ }
+
+ // The compare instructions are weird. We have to encode the predicate
+ // value and it is combined with the instruction opcode by multiplying
+ // the opcode by one hundred. We must decode this to get the predicate.
+ if (V.opcode == Instruction::ICmp)
+ return new CompareConstantExpr(Instruction::ICmp, V.predicate,
+ V.operands[0], V.operands[1]);
+ if (V.opcode == Instruction::FCmp)
+ return new CompareConstantExpr(Instruction::FCmp, V.predicate,
+ V.operands[0], V.operands[1]);
+ assert(0 && "Invalid ConstantExpr!");
}
};
@@ -1465,7 +1479,8 @@
Operands.reserve(CE->getNumOperands());
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
Operands.push_back(cast<Constant>(CE->getOperand(i)));
- return ExprMapKeyType(CE->getOpcode(), Operands);
+ return ExprMapKeyType(CE->getOpcode(), Operands,
+ CE->isCompare() ? CE->getPredicate() : 0);
}
static ManagedStatic<ValueMap<ExprMapKeyType, Type,
@@ -1482,7 +1497,7 @@
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> argVec(1, C);
- ExprMapKeyType Key = std::make_pair(opc, argVec);
+ ExprMapKeyType Key(opc, argVec);
return ExprConstants->getOrCreate(Ty, Key);
}
@@ -1627,10 +1642,15 @@
}
Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
- Constant *C1, Constant *C2) {
+ Constant *C1, Constant *C2, unsigned short pred) {
if (Opcode == Instruction::Shl || Opcode == Instruction::LShr ||
Opcode == Instruction::AShr)
return getShiftTy(ReqTy, Opcode, C1, C2);
+ if (Opcode == Instruction::ICmp)
+ return getICmp(pred, C1, C2);
+ if (Opcode == Instruction::FCmp)
+ return getFCmp(pred, C1, C2);
+
// Check the operands for consistency first
assert(Opcode >= Instruction::BinaryOpsBegin &&
Opcode < Instruction::BinaryOpsEnd &&
@@ -1644,11 +1664,11 @@
return FC; // Fold a few common cases...
std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
- ExprMapKeyType Key = std::make_pair(Opcode, argVec);
+ ExprMapKeyType Key(Opcode, argVec, pred);
return ExprConstants->getOrCreate(ReqTy, Key);
}
-Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
+Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, unsigned short pred) {
#ifndef NDEBUG
switch (Opcode) {
case Instruction::Add:
@@ -1696,6 +1716,10 @@
case Instruction::SetGE: case Instruction::SetEQ: case Instruction::SetNE:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
break;
+ case Instruction::FCmp:
+ case Instruction::ICmp:
+ assert(C1->getType() == C2->getType() && "Op types should be identical!");
+ break;
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
@@ -1709,9 +1733,9 @@
#endif
if (Instruction::isComparison(Opcode))
- return getTy(Type::BoolTy, Opcode, C1, C2);
+ return getTy(Type::BoolTy, Opcode, C1, C2, pred);
else
- return getTy(C1->getType(), Opcode, C1, C2);
+ return getTy(C1->getType(), Opcode, C1, C2, pred);
}
Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
@@ -1727,7 +1751,7 @@
std::vector<Constant*> argVec(3, C);
argVec[1] = V1;
argVec[2] = V2;
- ExprMapKeyType Key = std::make_pair(Instruction::Select, argVec);
+ ExprMapKeyType Key(Instruction::Select, argVec);
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -1747,7 +1771,7 @@
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
- ExprMapKeyType Key = std::make_pair(Opcode, argVec);
+ ExprMapKeyType Key(Opcode, argVec);
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -1768,7 +1792,7 @@
ArgVec.push_back(C);
for (unsigned i = 0, e = IdxList.size(); i != e; ++i)
ArgVec.push_back(cast<Constant>(IdxList[i]));
- const ExprMapKeyType &Key = std::make_pair(Instruction::GetElementPtr,ArgVec);
+ const ExprMapKeyType Key(Instruction::GetElementPtr,ArgVec);
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -1792,6 +1816,41 @@
return getGetElementPtrTy(PointerType::get(Ty), C, IdxList);
}
+Constant *
+ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+ assert(LHS->getType() == RHS->getType());
+ assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
+ pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
+
+ if (Constant *FC = ConstantFoldCompare(Instruction::ICmp, LHS, RHS, pred))
+ return FC; // Fold a few common cases...
+
+ // Look up the constant in the table first to ensure uniqueness
+ std::vector<Constant*> ArgVec;
+ ArgVec.push_back(LHS);
+ ArgVec.push_back(RHS);
+ // Fake up an opcode value that encodes both the opcode and predicate
+ const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
+ return ExprConstants->getOrCreate(Type::BoolTy, Key);
+}
+
+Constant *
+ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+ assert(LHS->getType() == RHS->getType());
+ assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
+
+ if (Constant *FC = ConstantFoldCompare(Instruction::FCmp, LHS, RHS, pred))
+ return FC; // Fold a few common cases...
+
+ // Look up the constant in the table first to ensure uniqueness
+ std::vector<Constant*> ArgVec;
+ ArgVec.push_back(LHS);
+ ArgVec.push_back(RHS);
+ // Fake up an opcode value that encodes both the opcode and predicate
+ const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
+ return ExprConstants->getOrCreate(Type::BoolTy, Key);
+}
+
Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
Constant *Idx) {
if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
@@ -1799,7 +1858,7 @@
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, Val);
ArgVec.push_back(Idx);
- const ExprMapKeyType &Key = std::make_pair(Instruction::ExtractElement,ArgVec);
+ const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec);
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -1820,7 +1879,7 @@
std::vector<Constant*> ArgVec(1, Val);
ArgVec.push_back(Elt);
ArgVec.push_back(Idx);
- const ExprMapKeyType &Key = std::make_pair(Instruction::InsertElement,ArgVec);
+ const ExprMapKeyType Key(Instruction::InsertElement,ArgVec);
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -1844,7 +1903,7 @@
std::vector<Constant*> ArgVec(1, V1);
ArgVec.push_back(V2);
ArgVec.push_back(Mask);
- const ExprMapKeyType &Key = std::make_pair(Instruction::ShuffleVector,ArgVec);
+ const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -2071,6 +2130,15 @@
if (C2 == From) C2 = To;
if (C3 == From) C3 = To;
Replacement = ConstantExpr::getShuffleVector(C1, C2, C3);
+ } else if (isCompare()) {
+ Constant *C1 = getOperand(0);
+ Constant *C2 = getOperand(1);
+ if (C1 == From) C1 = To;
+ if (C2 == From) C2 = To;
+ if (getOpcode() == Instruction::ICmp)
+ Replacement = ConstantExpr::getICmp(getPredicate(), C1, C2);
+ else
+ Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2);
} else if (getNumOperands() == 2) {
Constant *C1 = getOperand(0);
Constant *C2 = getOperand(1);
More information about the llvm-commits
mailing list