case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID:
+ case Type::UnionTyID:
case Type::ArrayTyID:
case Type::VectorTyID:
return ConstantAggregateZero::get(Ty);
/// isConstantUsed - Return true if the constant has users other than constant
/// exprs and other dangling things.
bool Constant::isConstantUsed() const {
- for (use_const_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
+ for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
const Constant *UC = dyn_cast<Constant>(*UI);
if (UC == 0 || isa<GlobalValue>(UC))
return true;
// Factory Function Implementation
ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) {
- assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) &&
+ assert((Ty->isStructTy() || Ty->isUnionTy()
+ || Ty->isArrayTy() || Ty->isVectorTy()) &&
"Cannot create an aggregate zero of non-aggregate type!");
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::ZExt, C, Ty);
+ return getBitCast(C, Ty);
+ return getZExt(C, Ty);
}
Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::SExt, C, Ty);
+ return getBitCast(C, Ty);
+ return getSExt(C, Ty);
}
Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::Trunc, C, Ty);
+ return getBitCast(C, Ty);
+ return getTrunc(C, Ty);
}
Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast");
if (Ty->isIntegerTy())
- return getCast(Instruction::PtrToInt, S, Ty);
- return getCast(Instruction::BitCast, S, Ty);
+ return getPtrToInt(S, Ty);
+ return getBitCast(S, Ty);
}
Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *GEP = getGetElementPtr(
Constant::getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant* ConstantExpr::getAlignOf(const Type* Ty) {
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *Indices[2] = { Zero, One };
Constant *GEP = getGetElementPtr(NullPtr, Indices, 2);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
};
Constant *GEP = getGetElementPtr(
Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx, 2);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant *ConstantExpr::getCompare(unsigned short pred,
return Instruction::getOpcodeName(getOpcode());
}
+
+
+GetElementPtrConstantExpr::
+GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
+ const Type *DestTy)
+ : ConstantExpr(DestTy, Instruction::GetElementPtr,
+ OperandTraits<GetElementPtrConstantExpr>::op_end(this)
+ - (IdxList.size()+1), IdxList.size()+1) {
+ OperandList[0] = C;
+ for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
+ OperandList[i+1] = IdxList[i];
+}
+
+
//===----------------------------------------------------------------------===//
// replaceUsesOfWithOnConstant implementations
void ConstantUnion::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
- assert(false && "Implement replaceUsesOfWithOnConstant for unions");
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+ Constant *ToC = cast<Constant>(To);
+
+ assert(U == OperandList && "Union constants can only have one use!");
+ assert(getNumOperands() == 1 && "Union constants can only have one use!");
+ assert(getOperand(0) == From && "ReplaceAllUsesWith broken!");
+
+ std::pair<LLVMContextImpl::UnionConstantsTy::MapKey, ConstantUnion*> Lookup;
+ Lookup.first.first = getType();
+ Lookup.second = this;
+ Lookup.first.second = ToC;
+
+ LLVMContext &Context = getType()->getContext();
+ LLVMContextImpl *pImpl = Context.pImpl;
+
+ Constant *Replacement = 0;
+ if (ToC->isNullValue()) {
+ Replacement = ConstantAggregateZero::get(getType());
+ } else {
+ // Check to see if we have this union type already.
+ bool Exists;
+ LLVMContextImpl::UnionConstantsTy::MapTy::iterator I =
+ pImpl->UnionConstants.InsertOrGetItem(Lookup, Exists);
+
+ if (Exists) {
+ Replacement = I->second;
+ } else {
+ // Okay, the new shape doesn't exist in the system yet. Instead of
+ // creating a new constant union, inserting it, replaceallusesof'ing the
+ // old with the new, then deleting the old... just update the current one
+ // in place!
+ pImpl->UnionConstants.MoveConstantToNewSlot(this, I);
+
+ // Update to the new value.
+ setOperand(0, ToC);
+ return;
+ }
+ }
+
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement.
+ uncheckedReplaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
}
void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,