//
//===----------------------------------------------------------------------===//
-#define __STDC_LIMIT_MACROS // Get defs for INT64_MAX and friends...
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/iMemory.h"
}
ConstantSInt::ConstantSInt(const Type *Ty, int64_t V) : ConstantInt(Ty, V) {
+ assert(Ty->isInteger() && Ty->isSigned() &&
+ "Illegal type for unsigned integer constant!");
assert(isValueValidForType(Ty, V) && "Value too large for type!");
}
ConstantUInt::ConstantUInt(const Type *Ty, uint64_t V) : ConstantInt(Ty, V) {
+ assert(Ty->isInteger() && Ty->isUnsigned() &&
+ "Illegal type for unsigned integer constant!");
assert(isValueValidForType(Ty, V) && "Value too large for type!");
}
ConstantArray::ConstantArray(const ArrayType *T,
const std::vector<Constant*> &V) : Constant(T) {
- for (unsigned i = 0; i < V.size(); i++) {
+ Operands.reserve(V.size());
+ for (unsigned i = 0, e = V.size(); i != e; ++i) {
assert(V[i]->getType() == T->getElementType());
Operands.push_back(Use(V[i], this));
}
const StructType::ElementTypes &ETypes = T->getElementTypes();
assert(V.size() == ETypes.size() &&
"Invalid initializer vector for constant structure");
- for (unsigned i = 0; i < V.size(); i++) {
+ Operands.reserve(V.size());
+ for (unsigned i = 0, e = V.size(); i != e; ++i) {
assert(V[i]->getType() == ETypes[i]);
Operands.push_back(Use(V[i], this));
}
// classof implementations
bool ConstantIntegral::classof(const Constant *CPV) {
- return (CPV->getType()->isIntegral() || CPV->getType() == Type::BoolTy) &&
- !isa<ConstantExpr>(CPV);
+ return CPV->getType()->isIntegral() && !isa<ConstantExpr>(CPV);
}
bool ConstantInt::classof(const Constant *CPV) {
- return CPV->getType()->isIntegral() && !isa<ConstantExpr>(CPV);
+ return CPV->getType()->isInteger() && !isa<ConstantExpr>(CPV);
}
bool ConstantSInt::classof(const Constant *CPV) {
return CPV->getType()->isSigned() && !isa<ConstantExpr>(CPV);
}
};
+//===----------------------------------------------------------------------===//
+// replaceUsesOfWithOnConstant implementations
+
+void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+ std::vector<Constant*> Values;
+ Values.reserve(getValues().size()); // Build replacement array...
+ for (unsigned i = 0, e = getValues().size(); i != e; ++i) {
+ Constant *Val = cast<Constant>(getValues()[i]);
+ if (Val == From) Val = cast<Constant>(To);
+ Values.push_back(Val);
+ }
+
+ ConstantArray *Replacement = ConstantArray::get(getType(), Values);
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement...
+ replaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}
+
+void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+ std::vector<Constant*> Values;
+ Values.reserve(getValues().size());
+ for (unsigned i = 0, e = getValues().size(); i != e; ++i) {
+ Constant *Val = cast<Constant>(getValues()[i]);
+ if (Val == From) Val = cast<Constant>(To);
+ Values.push_back(Val);
+ }
+
+ ConstantStruct *Replacement = ConstantStruct::get(getType(), Values);
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement...
+ replaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}
+
+void ConstantPointerRef::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+ if (isa<GlobalValue>(To)) {
+ assert(From == getOperand(0) && "Doesn't contain from!");
+ ConstantPointerRef *Replacement =
+ ConstantPointerRef::get(cast<GlobalValue>(To));
+
+ // Everyone using this now uses the replacement...
+ replaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+ } else {
+ // Just replace ourselves with the To value specified.
+ replaceAllUsesWith(To);
+
+ // Delete the old constant!
+ destroyConstant();
+ }
+}
+
+void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+ ConstantExpr *Replacement = 0;
+ if (getOpcode() == Instruction::GetElementPtr) {
+ std::vector<Constant*> Indices;
+ Constant *Pointer = cast<Constant>(getOperand(0));
+ Indices.reserve(getNumOperands()-1);
+ if (Pointer == From) Pointer = cast<Constant>(To);
+
+ for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
+ Constant *Val = cast<Constant>(getOperand(i));
+ if (Val == From) Val = cast<Constant>(To);
+ Indices.push_back(Val);
+ }
+ Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices);
+ } else if (getOpcode() == Instruction::Cast) {
+ assert(getOperand(0) == From && "Cast only has one use!");
+ Replacement = ConstantExpr::getCast(cast<Constant>(To), getType());
+ } else if (getNumOperands() == 2) {
+ Constant *C1 = cast<Constant>(getOperand(0));
+ Constant *C2 = cast<Constant>(getOperand(1));
+ if (C1 == From) C1 = cast<Constant>(To);
+ if (C2 == From) C2 = cast<Constant>(To);
+ Replacement = ConstantExpr::get(getOpcode(), C1, C2);
+ } else {
+ assert(0 && "Unknown ConstantExpr type!");
+ return;
+ }
+
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement...
+ replaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}
+
+
+
//===----------------------------------------------------------------------===//
// Factory Function Implementation
destroyConstantImpl();
}
+// getAsString - If the sub-element type of this array is either sbyte or ubyte,
+// then this method converts the array to an std::string and returns it.
+// Otherwise, it asserts out.
+//
+std::string ConstantArray::getAsString() const {
+ std::string Result;
+ if (getType()->getElementType() == Type::SByteTy)
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ Result += (char)cast<ConstantSInt>(getOperand(i))->getValue();
+ else {
+ assert(getType()->getElementType() == Type::UByteTy && "Not a string!");
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ Result += (char)cast<ConstantUInt>(getOperand(i))->getValue();
+ }
+ return Result;
+}
+
+
//---- ConstantStruct::get() implementation...
//
static ValueMap<std::vector<Constant*>, ConstantStruct> StructConstants;
// Its not in the table so create a new one and put it in the table.
// Check the operands for consistency first
- assert((Opcode >= Instruction::FirstBinaryOp &&
- Opcode < Instruction::NumBinaryOps) &&
+ assert((Opcode >= Instruction::BinaryOpsBegin &&
+ Opcode < Instruction::BinaryOpsEnd) &&
"Invalid opcode in binary constant expression");
assert(C1->getType() == C2->getType() &&
return Instruction::getOpcodeName(getOpcode());
}
-
-//---- ConstantPointerRef::mutateReferences() implementation...
-//
-unsigned ConstantPointerRef::mutateReferences(Value *OldV, Value *NewV) {
- assert(getValue() == OldV && "Cannot mutate old value if I'm not using it!");
- GlobalValue *NewGV = cast<GlobalValue>(NewV);
- getValue()->getParent()->mutateConstantPointerRef(getValue(), NewGV);
- Operands[0] = NewGV;
- return 1;
-}
-
-
-//---- ConstantPointerExpr::mutateReferences() implementation...
-//
-unsigned ConstantExpr::mutateReferences(Value* OldV, Value *NewV) {
- unsigned NumReplaced = 0;
- Constant *NewC = cast<Constant>(NewV);
- for (unsigned i = 0, N = getNumOperands(); i != N; ++i)
- if (Operands[i] == OldV) {
- ++NumReplaced;
- Operands[i] = NewC;
- }
- return NumReplaced;
+unsigned Constant::mutateReferences(Value *OldV, Value *NewV) {
+ // Uses of constant pointer refs are global values, not constants!
+ if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(this)) {
+ GlobalValue *NewGV = cast<GlobalValue>(NewV);
+ GlobalValue *OldGV = CPR->getValue();
+
+ assert(OldGV == OldV && "Cannot mutate old value if I'm not using it!");
+
+ OldGV->getParent()->mutateConstantPointerRef(OldGV, NewGV);
+ Operands[0] = NewGV;
+ return 1;
+ } else {
+ Constant *NewC = cast<Constant>(NewV);
+ unsigned NumReplaced = 0;
+ for (unsigned i = 0, N = getNumOperands(); i != N; ++i)
+ if (Operands[i] == OldV) {
+ ++NumReplaced;
+ Operands[i] = NewC;
+ }
+ return NumReplaced;
+ }
}