add getUnderlyingObjectSize()
authorNuno Lopes <nunoplopes@sapo.pt>
Sat, 2 Mar 2013 11:23:34 +0000 (11:23 +0000)
committerNuno Lopes <nunoplopes@sapo.pt>
Sat, 2 Mar 2013 11:23:34 +0000 (11:23 +0000)
this is similar to getObjectSize(), but doesnt subtract the offset
tweak the BasicAA code accordingly (per PR14988)

llvm-svn: 176407

llvm/include/llvm/Analysis/MemoryBuiltins.h
llvm/lib/Analysis/BasicAliasAnalysis.cpp
llvm/lib/Analysis/MemoryBuiltins.cpp

index f07658f..dd2fce4 100644 (file)
@@ -144,6 +144,14 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
 bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
                    const TargetLibraryInfo *TLI, bool RoundToAlign = false);
 
+/// \brief Compute the size of the underlying object pointed by Ptr. Returns
+/// true and the object size in Size if successful, and false otherwise.
+/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
+/// byval arguments, and global variables.
+bool getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size,
+                             const DataLayout *TD, const TargetLibraryInfo *TLI,
+                             bool RoundToAlign = false);
+
 
 
 typedef std::pair<APInt, APInt> SizeOffsetType;
index ad36cbb..4139336 100644 (file)
@@ -88,7 +88,7 @@ static uint64_t getObjectSize(const Value *V, const DataLayout &TD,
                               const TargetLibraryInfo &TLI,
                               bool RoundToAlign = false) {
   uint64_t Size;
-  if (getObjectSize(V, Size, &TD, &TLI, RoundToAlign))
+  if (getUnderlyingObjectSize(V, Size, &TD, &TLI, RoundToAlign))
     return Size;
   return AliasAnalysis::UnknownSize;
 }
@@ -98,35 +98,6 @@ static uint64_t getObjectSize(const Value *V, const DataLayout &TD,
 static bool isObjectSmallerThan(const Value *V, uint64_t Size,
                                 const DataLayout &TD,
                                 const TargetLibraryInfo &TLI) {
-  // Note that the meanings of the "object" are slightly different in the
-  // following contexts:
-  //    c1: llvm::getObjectSize()
-  //    c2: llvm.objectsize() intrinsic
-  //    c3: isObjectSmallerThan()
-  // c1 and c2 share the same meaning; however, the meaning of "object" in c3
-  // refers to the "entire object".
-  //
-  //  Consider this example:
-  //     char *p = (char*)malloc(100)
-  //     char *q = p+80;
-  //
-  //  In the context of c1 and c2, the "object" pointed by q refers to the
-  // stretch of memory of q[0:19]. So, getObjectSize(q) should return 20.
-  //
-  //  However, in the context of c3, the "object" refers to the chunk of memory
-  // being allocated. So, the "object" has 100 bytes, and q points to the middle
-  // the "object". In case q is passed to isObjectSmallerThan() as the 1st
-  // parameter, before the llvm::getObjectSize() is called to get the size of
-  // entire object, we should:
-  //    - either rewind the pointer q to the base-address of the object in
-  //      question (in this case rewind to p), or
-  //    - just give up. It is up to caller to make sure the pointer is pointing
-  //      to the base address the object.
-  // 
-  // We go for 2nd option for simplicity.
-  if (!isIdentifiedObject(V))
-    return false;
-
   // This function needs to use the aligned object size because we allow
   // reads a bit past the end given sufficient alignment.
   uint64_t ObjectSize = getObjectSize(V, TD, TLI, /*RoundToAlign*/true);
index 0fc0550..90f5811 100644 (file)
@@ -360,6 +360,26 @@ bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
   return true;
 }
 
+/// \brief Compute the size of the underlying object pointed by Ptr. Returns
+/// true and the object size in Size if successful, and false otherwise.
+/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
+/// byval arguments, and global variables.
+bool llvm::getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size,
+                                   const DataLayout *TD,
+                                   const TargetLibraryInfo *TLI,
+                                   bool RoundToAlign) {
+  if (!TD)
+    return false;
+
+  ObjectSizeOffsetVisitor Visitor(TD, TLI, Ptr->getContext(), RoundToAlign);
+  SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
+  if (!Visitor.knownSize(Data))
+    return false;
+
+  Size = Data.first.getZExtValue();
+  return true;
+}
+
 
 STATISTIC(ObjectVisitorArgument,
           "Number of arguments with unsolved size and offset");