Use *OL = OperandList;
for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
I != E; ++I, ++OL) {
- Constant *E = *I;
- assert((E->getType() == T->getElementType() ||
+ Constant *C = *I;
+ assert((C->getType() == T->getElementType() ||
(T->isAbstract() &&
- E->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
+ C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
"Initializer for array element doesn't match array element type!");
- OL->init(E, this);
+ OL->init(C, this);
}
}
Use *OL = OperandList;
for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
I != E; ++I, ++OL) {
- Constant *E = *I;
- assert((E->getType() == T->getElementType(I-V.begin()) ||
+ Constant *C = *I;
+ assert((C->getType() == T->getElementType(I-V.begin()) ||
((T->getElementType(I-V.begin())->isAbstract() ||
- E->getType()->isAbstract()) &&
+ C->getType()->isAbstract()) &&
T->getElementType(I-V.begin())->getTypeID() ==
- E->getType()->getTypeID())) &&
+ C->getType()->getTypeID())) &&
"Initializer for struct element doesn't match struct element type!");
- OL->init(E, this);
+ OL->init(C, this);
}
}
Use *OL = OperandList;
for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
I != E; ++I, ++OL) {
- Constant *E = *I;
- assert((E->getType() == T->getElementType() ||
+ Constant *C = *I;
+ assert((C->getType() == T->getElementType() ||
(T->isAbstract() &&
- E->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
+ C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
"Initializer for packed element doesn't match packed element type!");
- OL->init(E, this);
+ OL->init(C, this);
}
}
}
};
+/// ExtractElementConstantExpr - This class is private to
+/// Constants.cpp, and is used behind the scenes to implement
+/// extractelement constant exprs.
+class ExtractElementConstantExpr : public ConstantExpr {
+ Use Ops[2];
+public:
+ ExtractElementConstantExpr(Constant *C1, Constant *C2)
+ : ConstantExpr(cast<PackedType>(C1->getType())->getElementType(),
+ Instruction::ExtractElement, Ops, 2) {
+ Ops[0].init(C1, this);
+ Ops[1].init(C2, this);
+ }
+};
+
+/// InsertElementConstantExpr - This class is private to
+/// Constants.cpp, and is used behind the scenes to implement
+/// insertelement constant exprs.
+class InsertElementConstantExpr : public ConstantExpr {
+ Use Ops[3];
+public:
+ InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
+ : ConstantExpr(C1->getType(), Instruction::InsertElement,
+ Ops, 3) {
+ Ops[0].init(C1, this);
+ Ops[1].init(C2, this);
+ Ops[2].init(C3, this);
+ }
+};
+
/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
/// used behind the scenes to implement getelementpr constant exprs.
struct GetElementPtrConstantExpr : public ConstantExpr {
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]);
assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!");
case Instruction::Mul: case Instruction::Div:
case Instruction::Rem:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint()) &&
+ assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint() ||
+ isa<PackedType>(C1->getType())) &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntegral() &&
+ assert((C1->getType()->isIntegral() || isa<PackedType>(C1->getType())) &&
"Tried to create a logical operation on a non-integral type!");
break;
case Instruction::SetLT: case Instruction::SetGT: case Instruction::SetLE:
case Instruction::Shl:
case Instruction::Shr:
assert(C2->getType() == Type::UByteTy && "Shift should be by ubyte!");
- assert(C1->getType()->isInteger() &&
+ assert((C1->getType()->isInteger() || isa<PackedType>(C1->getType())) &&
"Tried to create a shift operation on a non-integer type!");
break;
default:
return getGetElementPtrTy(PointerType::get(Ty), C, IdxList);
}
+Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
+ Constant *Idx) {
+ if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
+ return FC; // Fold a few common cases...
+ // 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);
+ return ExprConstants.getOrCreate(ReqTy, Key);
+}
+
+Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
+ assert(isa<PackedType>(Val->getType()) &&
+ "Tried to create extractelement operation on non-packed type!");
+ assert(Idx->getType() == Type::UIntTy &&
+ "Extractelement index must be uint type!");
+ return getExtractElementTy(cast<PackedType>(Val->getType())->getElementType(),
+ Val, Idx);
+}
+
+Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
+ Constant *Elt, Constant *Idx) {
+ if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
+ return FC; // Fold a few common cases...
+ // Look up the constant in the table first to ensure uniqueness
+ std::vector<Constant*> ArgVec(1, Val);
+ ArgVec.push_back(Elt);
+ ArgVec.push_back(Idx);
+ const ExprMapKeyType &Key = std::make_pair(Instruction::InsertElement,ArgVec);
+ return ExprConstants.getOrCreate(ReqTy, Key);
+}
+
+Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
+ Constant *Idx) {
+ assert(isa<PackedType>(Val->getType()) &&
+ "Tried to create insertelement operation on non-packed type!");
+ assert(Elt->getType() == cast<PackedType>(Val->getType())->getElementType()
+ && "Insertelement types must match!");
+ assert(Idx->getType() == Type::UIntTy &&
+ "Insertelement index must be uint type!");
+ return getInsertElementTy(cast<PackedType>(Val->getType())->getElementType(),
+ Val, Elt, Idx);
+}
// destroyConstant - Remove the constant from the constant table...
//
if (C2 == From) C2 = To;
if (C3 == From) C3 = To;
Replacement = ConstantExpr::getSelect(C1, C2, C3);
+ } else if (getOpcode() == Instruction::ExtractElement) {
+ Constant *C1 = getOperand(0);
+ Constant *C2 = getOperand(1);
+ if (C1 == From) C1 = To;
+ if (C2 == From) C2 = To;
+ Replacement = ConstantExpr::getExtractElement(C1, C2);
} else if (getNumOperands() == 2) {
Constant *C1 = getOperand(0);
Constant *C2 = getOperand(1);
(*I)->destroyConstantImpl();
Constants.clear();
}
+
+/// getStringValue - Turn an LLVM constant pointer that eventually points to a
+/// global into a string value. Return an empty string if we can't do it.
+/// Parameter Chop determines if the result is chopped at the first null
+/// terminator.
+///
+std::string Constant::getStringValue(bool Chop, unsigned Offset) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) {
+ if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
+ ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
+ if (Init->isString()) {
+ std::string Result = Init->getAsString();
+ if (Offset < Result.size()) {
+ // If we are pointing INTO The string, erase the beginning...
+ Result.erase(Result.begin(), Result.begin()+Offset);
+
+ // Take off the null terminator, and any string fragments after it.
+ if (Chop) {
+ std::string::size_type NullPos = Result.find_first_of((char)0);
+ if (NullPos != std::string::npos)
+ Result.erase(Result.begin()+NullPos, Result.end());
+ }
+ return Result;
+ }
+ }
+ }
+ } else if (Constant *C = dyn_cast<Constant>(this)) {
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
+ return GV->getStringValue(Chop, Offset);
+ else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ // Turn a gep into the specified offset.
+ if (CE->getNumOperands() == 3 &&
+ cast<Constant>(CE->getOperand(1))->isNullValue() &&
+ isa<ConstantInt>(CE->getOperand(2))) {
+ Offset += cast<ConstantInt>(CE->getOperand(2))->getRawValue();
+ return CE->getOperand(0)->getStringValue(Chop, Offset);
+ }
+ }
+ }
+ }
+ return "";
+}
+