}
+/// getVectorElements - This method, which is only valid on constant of vector
+/// type, returns the elements of the vector in the specified smallvector.
+/// This handles breaking down a vector undef into undef elements, etc. For
+/// constant exprs and other cases we can't handle, we return an empty vector.
+void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const {
+ assert(isa<VectorType>(getType()) && "Not a vector constant!");
+
+ if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) {
+ for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i)
+ Elts.push_back(CV->getOperand(i));
+ return;
+ }
+
+ const VectorType *VT = cast<VectorType>(getType());
+ if (isa<ConstantAggregateZero>(this)) {
+ Elts.assign(VT->getNumElements(),
+ Constant::getNullValue(VT->getElementType()));
+ return;
+ }
+
+ if (isa<UndefValue>(this)) {
+ Elts.assign(VT->getNumElements(), UndefValue::get(VT->getElementType()));
+ return;
+ }
+
+ // Unknown type, must be constant expr etc.
+}
+
+
+
//===----------------------------------------------------------------------===//
// ConstantInt
//===----------------------------------------------------------------------===//
}
bool ConstantExpr::isCompare() const {
- return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
+ return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp ||
+ getOpcode() == Instruction::VICmp || getOpcode() == Instruction::VFCmp;
}
bool ConstantExpr::hasIndices() const {
Op1 = (OpNo == 1) ? Op : getOperand(1);
Op2 = (OpNo == 2) ? Op : getOperand(2);
return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
- case Instruction::InsertValue: {
- const SmallVector<unsigned, 4> &Indices = getIndices();
- Op0 = (OpNo == 0) ? Op : getOperand(0);
- Op1 = (OpNo == 1) ? Op : getOperand(1);
- return ConstantExpr::getInsertValue(Op0, Op1,
- &Indices[0], Indices.size());
- }
- case Instruction::ExtractValue: {
- assert(OpNo == 0 && "ExtractaValue has only one operand!");
- const SmallVector<unsigned, 4> &Indices = getIndices();
- return
- ConstantExpr::getExtractValue(Op, &Indices[0], Indices.size());
- }
case Instruction::GetElementPtr: {
SmallVector<Constant*, 8> Ops;
Ops.resize(getNumOperands()-1);
return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
- case Instruction::InsertValue: {
- const SmallVector<unsigned, 4> &Indices = getIndices();
- return ConstantExpr::getInsertValue(Ops[0], Ops[1],
- &Indices[0], Indices.size());
- }
- case Instruction::ExtractValue: {
- const SmallVector<unsigned, 4> &Indices = getIndices();
- return ConstantExpr::getExtractValue(Ops[0],
- &Indices[0], Indices.size());
- }
case Instruction::GetElementPtr:
return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], Ops.size()-1);
case Instruction::ICmp:
case Instruction::FCmp:
+ case Instruction::VICmp:
+ case Instruction::VFCmp:
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
default:
assert(getNumOperands() == 2 && "Must be binary operator?");
/// necessary.
ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) {
MapKey Lookup(Ty, V);
- typename MapTy::iterator I = Map.lower_bound(Lookup);
+ typename MapTy::iterator I = Map.find(Lookup);
// Is it in the map?
- if (I != Map.end() && I->first == Lookup)
+ if (I != Map.end())
return static_cast<ConstantClass *>(I->second);
// If no preexisting value, create one now...
// If the type of the constant is abstract, make sure that an entry exists
// for it in the AbstractTypeMap.
if (Ty->isAbstract()) {
- typename AbstractTypeMapTy::iterator TI =
- AbstractTypeMap.lower_bound(Ty);
+ typename AbstractTypeMapTy::iterator TI = AbstractTypeMap.find(Ty);
- if (TI == AbstractTypeMap.end() || TI->first != Ty) {
+ if (TI == AbstractTypeMap.end()) {
// Add ourselves to the ATU list of the type.
cast<DerivedType>(Ty)->addAbstractTypeUser(this);
Constant *ConstantVector::get(const VectorType *Ty,
const std::vector<Constant*> &V) {
- // If this is an all-zero vector, return a ConstantAggregateZero object
- if (!V.empty()) {
- Constant *C = V[0];
- if (!C->isNullValue())
- return VectorConstants->getOrCreate(Ty, V);
+ assert(!V.empty() && "Vectors can't be empty");
+ // If this is an all-undef or alll-zero vector, return a
+ // ConstantAggregateZero or UndefValue.
+ Constant *C = V[0];
+ bool isZero = C->isNullValue();
+ bool isUndef = isa<UndefValue>(C);
+
+ if (isZero || isUndef) {
for (unsigned i = 1, e = V.size(); i != e; ++i)
- if (V[i] != C)
- return VectorConstants->getOrCreate(Ty, V);
+ if (V[i] != C) {
+ isZero = isUndef = false;
+ break;
+ }
}
- return ConstantAggregateZero::get(Ty);
+
+ if (isZero)
+ return ConstantAggregateZero::get(Ty);
+ if (isUndef)
+ return UndefValue::get(Ty);
+ return VectorConstants->getOrCreate(Ty, V);
}
Constant *ConstantVector::get(const std::vector<Constant*> &V) {
Constant *ConstantExpr::getCompareTy(unsigned short predicate,
Constant *C1, Constant *C2) {
+ bool isVectorType = C1->getType()->getTypeID() == Type::VectorTyID;
switch (predicate) {
default: assert(0 && "Invalid CmpInst predicate");
- case FCmpInst::FCMP_FALSE: case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_OGT:
- case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_OLE:
- case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_ORD: case FCmpInst::FCMP_UNO:
- case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UGT: case FCmpInst::FCMP_UGE:
- case FCmpInst::FCMP_ULT: case FCmpInst::FCMP_ULE: case FCmpInst::FCMP_UNE:
- case FCmpInst::FCMP_TRUE:
- return getFCmp(predicate, C1, C2);
- case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGT:
- case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE:
- case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: case ICmpInst::ICMP_SLT:
- case ICmpInst::ICMP_SLE:
- return getICmp(predicate, C1, C2);
+ case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT:
+ case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLT: case CmpInst::FCMP_OLE:
+ case CmpInst::FCMP_ONE: case CmpInst::FCMP_ORD: case CmpInst::FCMP_UNO:
+ case CmpInst::FCMP_UEQ: case CmpInst::FCMP_UGT: case CmpInst::FCMP_UGE:
+ case CmpInst::FCMP_ULT: case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE:
+ case CmpInst::FCMP_TRUE:
+ return isVectorType ? getVFCmp(predicate, C1, C2)
+ : getFCmp(predicate, C1, C2);
+ case CmpInst::ICMP_EQ: case CmpInst::ICMP_NE: case CmpInst::ICMP_UGT:
+ case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE:
+ case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT:
+ case CmpInst::ICMP_SLE:
+ return isVectorType ? getVICmp(predicate, C1, C2)
+ : getICmp(predicate, C1, C2);
}
}
Constant *
ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
- assert(isa<VectorType>(LHS->getType()) &&
+ assert(isa<VectorType>(LHS->getType()) && LHS->getType() == RHS->getType() &&
"Tried to create vicmp operation on non-vector type!");
- assert(LHS->getType() == RHS->getType());
assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid VICmp Predicate");
const Type *EltTy = VTy->getElementType();
unsigned NumElts = VTy->getNumElements();
- SmallVector<Constant *, 8> Elts;
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
- RHS->getOperand(i));
- if (FC) {
- uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
- if (Val != 0ULL)
- Elts.push_back(ConstantInt::getAllOnesValue(EltTy));
- else
- Elts.push_back(ConstantInt::get(EltTy, 0ULL));
+ // See if we can fold the element-wise comparison of the LHS and RHS.
+ SmallVector<Constant *, 16> LHSElts, RHSElts;
+ LHS->getVectorElements(LHSElts);
+ RHS->getVectorElements(RHSElts);
+
+ if (!LHSElts.empty() && !RHSElts.empty()) {
+ SmallVector<Constant *, 16> Elts;
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *FC = ConstantFoldCompareInstruction(pred, LHSElts[i],
+ RHSElts[i]);
+ if (ConstantInt *FCI = dyn_cast_or_null<ConstantInt>(FC)) {
+ if (FCI->getZExtValue())
+ Elts.push_back(ConstantInt::getAllOnesValue(EltTy));
+ else
+ Elts.push_back(ConstantInt::get(EltTy, 0ULL));
+ } else if (FC && isa<UndefValue>(FC)) {
+ Elts.push_back(UndefValue::get(EltTy));
+ } else {
+ break;
+ }
}
+ if (Elts.size() == NumElts)
+ return ConstantVector::get(&Elts[0], Elts.size());
}
- if (Elts.size() == NumElts)
- return ConstantVector::get(&Elts[0], Elts.size());
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
const Type *REltTy = IntegerType::get(EltTy->getPrimitiveSizeInBits());
const Type *ResultTy = VectorType::get(REltTy, NumElts);
- SmallVector<Constant *, 8> Elts;
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
- RHS->getOperand(i));
- if (FC) {
- uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
- if (Val != 0ULL)
- Elts.push_back(ConstantInt::getAllOnesValue(REltTy));
- else
- Elts.push_back(ConstantInt::get(REltTy, 0ULL));
+ // See if we can fold the element-wise comparison of the LHS and RHS.
+ SmallVector<Constant *, 16> LHSElts, RHSElts;
+ LHS->getVectorElements(LHSElts);
+ RHS->getVectorElements(RHSElts);
+
+ if (!LHSElts.empty() && !RHSElts.empty()) {
+ SmallVector<Constant *, 16> Elts;
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *FC = ConstantFoldCompareInstruction(pred, LHSElts[i],
+ RHSElts[i]);
+ if (ConstantInt *FCI = dyn_cast_or_null<ConstantInt>(FC)) {
+ if (FCI->getZExtValue())
+ Elts.push_back(ConstantInt::getAllOnesValue(REltTy));
+ else
+ Elts.push_back(ConstantInt::get(REltTy, 0ULL));
+ } else if (FC && isa<UndefValue>(FC)) {
+ Elts.push_back(UndefValue::get(REltTy));
+ } else {
+ break;
+ }
}
+ if (Elts.size() == NumElts)
+ return ConstantVector::get(&Elts[0], Elts.size());
}
- if (Elts.size() == NumElts)
- return ConstantVector::get(&Elts[0], Elts.size());
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
"insertvalue type invalid!");
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant InsertValue expression");
- if (Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx))
- 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(Agg);
- ArgVec.push_back(Val);
- SmallVector<unsigned, 4> Indices(Idxs, Idxs + NumIdx);
- const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, Indices);
- return ExprConstants->getOrCreate(ReqTy, Key);
+ Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx);
+ assert(FC && "InsertValue constant expr couldn't be folded!");
+ return FC;
}
Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
"extractvalue indices invalid!");
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant extractvalue expression");
- if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx))
- 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(Agg);
- SmallVector<unsigned, 4> Indices(Idxs, Idxs + NumIdx);
- const ExprMapKeyType Key(Instruction::ExtractValue, ArgVec, 0, Indices);
- return ExprConstants->getOrCreate(ReqTy, Key);
+ Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx);
+ assert(FC && "ExtractValue constant expr couldn't be folded!");
+ return FC;
}
Constant *ConstantExpr::getExtractValue(Constant *Agg,
if (C2 == From) C2 = To;
if (getOpcode() == Instruction::ICmp)
Replacement = ConstantExpr::getICmp(getPredicate(), C1, C2);
- else
+ else if (getOpcode() == Instruction::FCmp)
Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2);
+ else if (getOpcode() == Instruction::VICmp)
+ Replacement = ConstantExpr::getVICmp(getPredicate(), C1, C2);
+ else {
+ assert(getOpcode() == Instruction::VFCmp);
+ Replacement = ConstantExpr::getVFCmp(getPredicate(), C1, C2);
+ }
} else if (getNumOperands() == 2) {
Constant *C1 = getOperand(0);
Constant *C2 = getOperand(1);