[llvm-commits] [llvm] r78695 - in /llvm/trunk: include/llvm/Constants.h include/llvm/Instructions.h include/llvm/Support/ConstantFolder.h include/llvm/Support/IRBuilder.h include/llvm/Support/NoFolder.h include/llvm/Support/TargetFolder.h lib/VMCore/Constants.cpp

Dan Gohman gohman at apple.com
Tue Aug 11 10:57:01 PDT 2009


Author: djg
Date: Tue Aug 11 12:57:01 2009
New Revision: 78695

URL: http://llvm.org/viewvc/llvm-project?rev=78695&view=rev
Log:
Add convenience functions for creating inbounds GEPs.

Modified:
    llvm/trunk/include/llvm/Constants.h
    llvm/trunk/include/llvm/Instructions.h
    llvm/trunk/include/llvm/Support/ConstantFolder.h
    llvm/trunk/include/llvm/Support/IRBuilder.h
    llvm/trunk/include/llvm/Support/NoFolder.h
    llvm/trunk/include/llvm/Support/TargetFolder.h
    llvm/trunk/lib/VMCore/Constants.cpp

Modified: llvm/trunk/include/llvm/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=78695&r1=78694&r2=78695&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Constants.h (original)
+++ llvm/trunk/include/llvm/Constants.h Tue Aug 11 12:57:01 2009
@@ -723,7 +723,16 @@
                                     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);

Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=78695&r1=78694&r2=78695&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Tue Aug 11 12:57:01 2009
@@ -493,6 +493,44 @@
     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.

Modified: llvm/trunk/include/llvm/Support/ConstantFolder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ConstantFolder.h?rev=78695&r1=78694&r2=78695&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/ConstantFolder.h (original)
+++ llvm/trunk/include/llvm/Support/ConstantFolder.h Tue Aug 11 12:57:01 2009
@@ -122,6 +122,15 @@
     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
   //===--------------------------------------------------------------------===//

Modified: llvm/trunk/include/llvm/Support/IRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=78695&r1=78694&r2=78695&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/IRBuilder.h (original)
+++ llvm/trunk/include/llvm/Support/IRBuilder.h Tue Aug 11 12:57:01 2009
@@ -362,21 +362,43 @@
     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 @@
 
     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 @@
 
     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 @@
 
     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 @@
 
     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 @@
     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

Modified: llvm/trunk/include/llvm/Support/NoFolder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/NoFolder.h?rev=78695&r1=78694&r2=78695&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/NoFolder.h (original)
+++ llvm/trunk/include/llvm/Support/NoFolder.h Tue Aug 11 12:57:01 2009
@@ -126,6 +126,15 @@
     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
   //===--------------------------------------------------------------------===//

Modified: llvm/trunk/include/llvm/Support/TargetFolder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TargetFolder.h?rev=78695&r1=78694&r2=78695&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/TargetFolder.h (original)
+++ llvm/trunk/include/llvm/Support/TargetFolder.h Tue Aug 11 12:57:01 2009
@@ -138,6 +138,15 @@
     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
   //===--------------------------------------------------------------------===//

Modified: llvm/trunk/lib/VMCore/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=78695&r1=78694&r2=78695&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Constants.cpp (original)
+++ llvm/trunk/lib/VMCore/Constants.cpp Tue Aug 11 12:57:01 2009
@@ -1363,6 +1363,7 @@
 
 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 @@
   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) {





More information about the llvm-commits mailing list