summaryrefslogtreecommitdiff
path: root/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/DataLayout.cpp23
-rw-r--r--lib/VMCore/Instructions.cpp11
-rw-r--r--lib/VMCore/Type.cpp7
3 files changed, 38 insertions, 3 deletions
diff --git a/lib/VMCore/DataLayout.cpp b/lib/VMCore/DataLayout.cpp
index e6994be257..8d7a8e267c 100644
--- a/lib/VMCore/DataLayout.cpp
+++ b/lib/VMCore/DataLayout.cpp
@@ -660,13 +660,32 @@ unsigned DataLayout::getPreferredTypeAlignmentShift(Type *Ty) const {
return Log2_32(Align);
}
-/// getIntPtrType - Return an unsigned integer type that is the same size or
-/// greater to the host pointer size.
+/// getIntPtrType - Return an integer type that is the same size or
+/// greater to the pointer size for the address space.
IntegerType *DataLayout::getIntPtrType(LLVMContext &C,
unsigned AddressSpace) const {
return IntegerType::get(C, getPointerSizeInBits(AddressSpace));
}
+/// getIntPtrType - Return an integer type that is the same size or
+/// greater to the pointer size of the specific PointerType.
+IntegerType *DataLayout::getIntPtrType(Type *Ty) const {
+ LLVMContext &C = Ty->getContext();
+ // For pointers, we return the size for the specific address space.
+ if (Ty->isPointerTy()) return IntegerType::get(C, getTypeSizeInBits(Ty));
+ // For vector of pointers, we return the size of the address space
+ // of the pointer type.
+ if (Ty->isVectorTy() && cast<VectorType>(Ty)->getElementType()->isPointerTy())
+ return IntegerType::get(C,
+ getTypeSizeInBits(cast<VectorType>(Ty)->getElementType()));
+ // Otherwise return the address space for the default address space.
+ // An example of this occuring is that you want to get the IntPtr
+ // for all of the arguments in a function. However, the IntPtr
+ // for a non-pointer type cannot be determined by the type, so
+ // the default value is used.
+ return getIntPtrType(C, 0);
+}
+
uint64_t DataLayout::getIndexedOffset(Type *ptrTy,
ArrayRef<Value *> Indices) const {
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 13c4a5d257..e9b96d6cd2 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -2120,6 +2120,17 @@ bool CastInst::isNoopCast(Type *IntPtrTy) const {
return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy);
}
+/// @brief Determine if a cast is a no-op
+bool CastInst::isNoopCast(const DataLayout &DL) const {
+ unsigned AS = 0;
+ if (getOpcode() == Instruction::PtrToInt)
+ AS = getOperand(0)->getType()->getPointerAddressSpace();
+ else if (getOpcode() == Instruction::IntToPtr)
+ AS = getType()->getPointerAddressSpace();
+ Type *IntPtrTy = DL.getIntPtrType(getContext(), AS);
+ return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy);
+}
+
/// This function determines if a pair of casts can be eliminated and what
/// opcode should be used in the elimination. This assumes that there are two
/// instructions like this:
diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp
index 1a7a650989..54146e118c 100644
--- a/lib/VMCore/Type.cpp
+++ b/lib/VMCore/Type.cpp
@@ -233,7 +233,12 @@ unsigned Type::getVectorNumElements() const {
}
unsigned Type::getPointerAddressSpace() const {
- return cast<PointerType>(this)->getAddressSpace();
+ if (isPointerTy())
+ return cast<PointerType>(this)->getAddressSpace();
+ if (isVectorTy())
+ return getSequentialElementType()->getPointerAddressSpace();
+ llvm_unreachable("Should never reach here!");
+ return 0;
}