summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-08-11 17:57:01 +0000
committerDan Gohman <gohman@apple.com>2009-08-11 17:57:01 +0000
commite2574d3215c412a15763d26aee9aa5d856764c2c (patch)
treec5d94d9987841e646bbffadceb943480cd203296
parent7cd0118c367314308cf94765ac12f81020a56271 (diff)
downloadllvm-e2574d3215c412a15763d26aee9aa5d856764c2c.tar.gz
llvm-e2574d3215c412a15763d26aee9aa5d856764c2c.tar.bz2
llvm-e2574d3215c412a15763d26aee9aa5d856764c2c.tar.xz
Add convenience functions for creating inbounds GEPs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78695 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Constants.h11
-rw-r--r--include/llvm/Instructions.h38
-rw-r--r--include/llvm/Support/ConstantFolder.h9
-rw-r--r--include/llvm/Support/IRBuilder.h74
-rw-r--r--include/llvm/Support/NoFolder.h9
-rw-r--r--include/llvm/Support/TargetFolder.h9
-rw-r--r--lib/VMCore/Constants.cpp20
7 files changed, 164 insertions, 6 deletions
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 3b674cda57..78b3ca83ea 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -723,7 +723,16 @@ public:
Constant* const *IdxList, unsigned NumIdx);
static Constant *getGetElementPtr(Constant *C,
Value* const *IdxList, unsigned NumIdx);
-
+
+ /// Create an "inbounds" getelementptr. See the documentation for the
+ /// "inbounds" flag in LangRef.html for details.
+ static Constant *getInBoundsGetElementPtr(Constant *C,
+ Constant* const *IdxList,
+ unsigned NumIdx);
+ static Constant *getInBoundsGetElementPtr(Constant *C,
+ Value* const *IdxList,
+ unsigned NumIdx);
+
static Constant *getExtractElement(Constant *Vec, Constant *Idx);
static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index ecfddf2cf9..9bee045878 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -493,6 +493,44 @@ public:
return new(2) GetElementPtrInst(Ptr, Idx, NameStr, InsertAtEnd);
}
+ /// Create an "inbounds" getelementptr. See the documentation for the
+ /// "inbounds" flag in LangRef.html for details.
+ template<typename InputIterator>
+ static GetElementPtrInst *CreateInBounds(Value *Ptr, InputIterator IdxBegin,
+ InputIterator IdxEnd,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
+ NameStr, InsertBefore);
+ cast<GEPOperator>(GEP)->setIsInBounds(true);
+ return GEP;
+ }
+ template<typename InputIterator>
+ static GetElementPtrInst *CreateInBounds(Value *Ptr,
+ InputIterator IdxBegin,
+ InputIterator IdxEnd,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
+ NameStr, InsertAtEnd);
+ cast<GEPOperator>(GEP)->setIsInBounds(true);
+ return GEP;
+ }
+ static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore);
+ cast<GEPOperator>(GEP)->setIsInBounds(true);
+ return GEP;
+ }
+ static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd);
+ cast<GEPOperator>(GEP)->setIsInBounds(true);
+ return GEP;
+ }
+
virtual GetElementPtrInst *clone(LLVMContext &Context) const;
/// Transparently provide more efficient getOperand methods.
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h
index 422d1ad00d..1b5b2b7745 100644
--- a/include/llvm/Support/ConstantFolder.h
+++ b/include/llvm/Support/ConstantFolder.h
@@ -122,6 +122,15 @@ public:
return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx);
}
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
+ }
+
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index 33ceb69feb..89dd2953da 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -362,21 +362,43 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr)) {
// Every index must be constant.
InputIterator i;
- for (i = IdxBegin; i < IdxEnd; ++i) {
+ for (i = IdxBegin; i < IdxEnd; ++i)
if (!isa<Constant>(*i))
break;
- }
if (i == IdxEnd)
return Folder.CreateGetElementPtr(PC, &IdxBegin[0], IdxEnd - IdxBegin);
}
return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name);
}
+ template<typename InputIterator>
+ Value *CreateInBoundsGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+ const char *Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+ // Every index must be constant.
+ InputIterator i;
+ for (i = IdxBegin; i < IdxEnd; ++i)
+ if (!isa<Constant>(*i))
+ break;
+ if (i == IdxEnd)
+ return Folder.CreateInBoundsGetElementPtr(PC,
+ &IdxBegin[0],
+ IdxEnd - IdxBegin);
+ }
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxBegin, IdxEnd),
+ Name);
+ }
Value *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
return Folder.CreateGetElementPtr(PC, &IC, 1);
return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
}
+ Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const char *Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Folder.CreateInBoundsGetElementPtr(PC, &IC, 1);
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ }
Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const char *Name = "") {
Value *Idx = ConstantInt::get(Type::Int32Ty, Idx0);
@@ -385,6 +407,15 @@ public:
return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
}
+ Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
+ const char *Name = "") {
+ Value *Idx = ConstantInt::get(Type::Int32Ty, Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
+ }
Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
const char *Name = "") {
Value *Idxs[] = {
@@ -397,6 +428,18 @@ public:
return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
}
+ Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+ const char *Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::Int32Ty, Idx0),
+ ConstantInt::get(Type::Int32Ty, Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
+ }
Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const char *Name = "") {
Value *Idx = ConstantInt::get(Type::Int64Ty, Idx0);
@@ -405,7 +448,16 @@ public:
return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);
}
- Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+ Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
+ const char *Name = "") {
+ Value *Idx = ConstantInt::get(Type::Int64Ty, Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
+ }
+ Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
const char *Name = "") {
Value *Idxs[] = {
ConstantInt::get(Type::Int64Ty, Idx0),
@@ -417,8 +469,20 @@ public:
return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
}
+ Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+ const char *Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::Int64Ty, Idx0),
+ ConstantInt::get(Type::Int64Ty, Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
+ }
Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") {
- return CreateConstGEP2_32(Ptr, 0, Idx, Name);
+ return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
}
Value *CreateGlobalString(const char *Str = "", const char *Name = "") {
Constant *StrConstant = ConstantArray::get(Str, true);
@@ -438,7 +502,7 @@ public:
Value *gv = CreateGlobalString(Str, Name);
Value *zero = ConstantInt::get(Type::Int32Ty, 0);
Value *Args[] = { zero, zero };
- return CreateGEP(gv, Args, Args+2, Name);
+ return CreateInBoundsGEP(gv, Args, Args+2, Name);
}
//===--------------------------------------------------------------------===//
// Instruction creation methods: Cast/Conversion Operators
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h
index b89c084b58..5333b87efd 100644
--- a/include/llvm/Support/NoFolder.h
+++ b/include/llvm/Support/NoFolder.h
@@ -126,6 +126,15 @@ public:
return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx);
}
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx);
+ }
+ Value *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return GetElementPtrInst::CreateInBounds(C, IdxList, IdxList+NumIdx);
+ }
+
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index 473b0ab03c..2569cb9019 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -138,6 +138,15 @@ public:
return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx));
}
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList,
+ unsigned NumIdx) const {
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx));
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList,
+ unsigned NumIdx) const {
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx));
+ }
+
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 2670965f73..89578fb897 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -1363,6 +1363,7 @@ Constant* ConstantExpr::getSizeOf(const Type* Ty) {
Constant* ConstantExpr::getAlignOf(const Type* Ty) {
// alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1
+ // Note that a non-inbounds gep is used, as null isn't within any object.
const Type *AligningTy = StructType::get(Ty->getContext(),
Type::Int8Ty, Ty, NULL);
Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo());
@@ -1438,11 +1439,30 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
}
+Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
+ Value* const *Idxs,
+ unsigned NumIdx) {
+ // Get the result type of the getelementptr!
+ const Type *Ty =
+ GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
+ assert(Ty && "GEP indices invalid!");
+ unsigned As = cast<PointerType>(C->getType())->getAddressSpace();
+ Constant *Result = getGetElementPtrTy(PointerType::get(Ty, As), C,
+ Idxs, NumIdx);
+ cast<GEPOperator>(Result)->setIsInBounds(true);
+ return Result;
+}
+
Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
unsigned NumIdx) {
return getGetElementPtr(C, (Value* const *)Idxs, NumIdx);
}
+Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
+ Constant* const *Idxs,
+ unsigned NumIdx) {
+ return getInBoundsGetElementPtr(C, (Value* const *)Idxs, NumIdx);
+}
Constant *
ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {