[llvm-commits] [llvm] r158660 - in /llvm/trunk: docs/LangRef.html include/llvm/LLVMContext.h lib/VMCore/LLVMContext.cpp lib/VMCore/Verifier.cpp test/Verifier/alloc-1.ll test/Verifier/alloc-2.ll

Nuno Lopes nunoplopes at sapo.pt
Mon Jun 18 09:04:05 PDT 2012


Author: nlopes
Date: Mon Jun 18 11:04:04 2012
New Revision: 158660

URL: http://llvm.org/viewvc/llvm-project?rev=158660&view=rev
Log:
add the 'alloc' metadata node to represent the size of offset of buffers pointed to by pointers.
This metadata can be attached to any instruction returning a pointer

Added:
    llvm/trunk/test/Verifier/alloc-1.ll
    llvm/trunk/test/Verifier/alloc-2.ll
Modified:
    llvm/trunk/docs/LangRef.html
    llvm/trunk/include/llvm/LLVMContext.h
    llvm/trunk/lib/VMCore/LLVMContext.cpp
    llvm/trunk/lib/VMCore/Verifier.cpp

Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=158660&r1=158659&r2=158660&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Mon Jun 18 11:04:04 2012
@@ -105,6 +105,7 @@
           <li><a href="#tbaa">'<tt>tbaa</tt>' Metadata</a></li>
           <li><a href="#fpmath">'<tt>fpmath</tt>' Metadata</a></li>
           <li><a href="#range">'<tt>range</tt>' Metadata</a></li>
+          <li><a href="#alloc">'<tt>alloc</tt>' Metadata</a></li>
         </ol>
       </li>
     </ol>
@@ -3077,6 +3078,49 @@
 </pre>
 </div>
 </div>
+
+<!-- _______________________________________________________________________ -->
+<h4>
+  <a name="alloc">'<tt>alloc</tt>' Metadata</a>
+</h4>
+ 
+<div>
+
+<p><tt>alloc</tt> metadata may be attached to any instruction returning a
+   pointer. It can be used to express the size and offset relative to the
+   beginning of the buffer pointed by.</p>
+
+<blockquote>
+
+<p>The first parameter is a function that returns the size of the buffer, and
+   the second (optional) parameter is a function that returns the offset from
+   the beginning of the buffer. If the second parameter is not present or null,
+   the offset is assumed to be null. Both functions must be either readonly or
+   readnone.</p>
+<p><tt>alloc</tt> metadata can have additional parameters, which are passed to
+   the size and offset functions when they are evaluated. Therefore the size and
+   offset functions must have the same signature.</p>
+
+</blockquote>
+
+
+<p>Examples:</p>
+<div class="doc_code">
+<pre>
+  ; size of buffer allocated by this call is my_malloc_size(%s), and offset=0
+  %a = call my_malloc(%s), !alloc !{i32 (i32)* @my_malloc_size, null, i32 %s}
+
+  ; size of the buffer pointed by *ptr is size(%x), and offset=offset(%x)
+  %b = load i8** %foo, !alloc !{i32 (i32)* @size, i32 (i32)* @offset, i32 %x}
+
+  ; size of buffer allocated by this call is foo_size(), and offset=0
+  %a = call alloc_foo(%s), !alloc !0
+...
+!0 = metadata {i32 ()* @foo_size}
+</pre>
+</div>
+</div>
+
 </div>
 
 </div>

Modified: llvm/trunk/include/llvm/LLVMContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LLVMContext.h?rev=158660&r1=158659&r2=158660&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LLVMContext.h (original)
+++ llvm/trunk/include/llvm/LLVMContext.h Mon Jun 18 11:04:04 2012
@@ -43,7 +43,8 @@
     MD_tbaa = 1, // "tbaa"
     MD_prof = 2,  // "prof"
     MD_fpmath = 3,  // "fpmath"
-    MD_range = 4 // "range"
+    MD_range = 4, // "range"
+    MD_alloc = 5 // "alloc"
   };
   
   /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.

Modified: llvm/trunk/lib/VMCore/LLVMContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContext.cpp?rev=158660&r1=158659&r2=158660&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/LLVMContext.cpp (original)
+++ llvm/trunk/lib/VMCore/LLVMContext.cpp Mon Jun 18 11:04:04 2012
@@ -53,6 +53,11 @@
   unsigned RangeID = getMDKindID("range");
   assert(RangeID == MD_range && "range kind id drifted");
   (void)RangeID;
+
+  // Create the 'alloc' metadata kind.
+  unsigned AllocID = getMDKindID("alloc");
+  assert(AllocID == MD_alloc && "alloc kind id drifted");
+  (void)AllocID;
 }
 LLVMContext::~LLVMContext() { delete pImpl; }
 

Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=158660&r1=158659&r2=158660&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Jun 18 11:04:04 2012
@@ -1672,6 +1672,39 @@
     }
   }
 
+  if (MDNode *MD = I.getMetadata(LLVMContext::MD_alloc)) {
+    Assert1(I.getType()->isPointerTy(), "alloc requires a pointer result", &I);
+    Assert1(MD->getNumOperands() >= 1, "alloc takes at least one operand", &I);
+    Function *SizeFn = dyn_cast<Function>(MD->getOperand(0));
+    Function *OffsetFn = MD->getNumOperands() >= 2 ?
+                         dyn_cast_or_null<Function>(MD->getOperand(1)) : 0;
+    Assert1(SizeFn, "first parameter of alloc must be a function", &I);
+    Assert1(MD->getNumOperands() == 1 || !MD->getOperand(1) || OffsetFn,
+            "second parameter of alloc must be either a function or null", &I);
+    Assert1(SizeFn->onlyReadsMemory(),
+            "size function must be readonly/readnone", &I);
+    Assert1(!OffsetFn || OffsetFn->onlyReadsMemory(),
+            "offset function must be readonly/readnone", &I);
+    Assert1(SizeFn->getReturnType()->isIntegerTy(),
+            "size function must return an integer", &I);
+    Assert1(!OffsetFn || OffsetFn->getReturnType()->isIntegerTy(),
+            "offset function must return an integer", &I);
+
+    FunctionType *SizeFnTy = SizeFn->getFunctionType();
+    FunctionType *OffsetFnTy = OffsetFn ? OffsetFn->getFunctionType() : 0;
+    Assert1(SizeFnTy->getNumParams() == MD->getNumOperands()-2,
+            "size function number of parameters mismatch", &I);
+    Assert1(!OffsetFnTy || OffsetFnTy->getNumParams() == MD->getNumOperands()-2,
+            "offset function number of parameters mismatch", &I);
+    for (unsigned i = 0, e = SizeFnTy->getNumParams(); i != e; ++i) {
+      Assert1(SizeFnTy->getParamType(i) == MD->getOperand(i+2)->getType(),
+              "size function parameter type mismatch", &I);
+      if (OffsetFnTy)
+        Assert1(OffsetFnTy->getParamType(i) == MD->getOperand(i+2)->getType(),
+                "offset function parameter type mismatch", &I);
+    }
+  }
+
   MDNode *MD = I.getMetadata(LLVMContext::MD_range);
   Assert1(!MD || isa<LoadInst>(I), "Ranges are only for loads!", &I);
 

Added: llvm/trunk/test/Verifier/alloc-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/alloc-1.ll?rev=158660&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/alloc-1.ll (added)
+++ llvm/trunk/test/Verifier/alloc-1.ll Mon Jun 18 11:04:04 2012
@@ -0,0 +1,48 @@
+; RUN: not llvm-as < %s -o /dev/null |& FileCheck %s
+
+declare i32 @size() readonly
+declare i32 @sizeR()
+declare i32 @size1(i32) readnone
+declare i32 @size1i8(i8) readnone
+declare i32* @sizeptr() readnone
+
+define void @f1(i8** %x, i32* %y) {
+entry:
+  %0 = load i8** %x, !alloc !0
+  %1 = load i8** %x, !alloc !1
+  %2 = load i8** %x, !alloc !2
+  %3 = load i8** %x, !alloc !3
+  %4 = load i8** %x, !alloc !4
+  %5 = load i8** %x, !alloc !5
+  %6 = load i8** %x, !alloc !6
+  %7 = load i8** %x, !alloc !7
+  %8 = load i8** %x, !alloc !8
+  %9 = load i32* %y, !alloc !9
+  %10 = load i8** %x, !alloc !10
+  %11 = load i8** %x, !alloc !11
+  ret void
+}
+; CHECK: alloc takes at least one operand
+!0 = metadata !{}
+; CHECK: first parameter of alloc must be a function
+!1 = metadata !{i32 0}
+; CHECK: second parameter of alloc must be either a function or null
+!2 = metadata !{i32 ()* @size, i32 0}
+; CHECK: size function number of parameters mismatch
+!3 = metadata !{i32 ()* @size, null, i32 0}
+; CHECK: offset function number of parameters mismatch
+!4 = metadata !{i32 (i32)* @size1, i32 ()* @size, i32 1}
+; CHECK: size function must be readonly/readnone
+!5 = metadata !{i32 ()* @sizeR, i32 ()* @size}
+; CHECK: offset function must be readonly/readnone
+!6 = metadata !{i32 ()* @size, i32 ()* @sizeR}
+; CHECK: size function parameter type mismatch
+!7 = metadata !{i32 (i32)* @size1, i32 (i8)* @size1i8, i8 5}
+; CHECK: offset function parameter type mismatch
+!8 = metadata !{i32 (i8)* @size1i8, i32 (i32)* @size1, i8 5}
+; CHECK: alloc requires a pointer result
+!9 = metadata !{i32 ()* @size, null}
+; CHECK: size function must return an integer
+!10 = metadata !{i32* ()* @sizeptr, null}
+; CHECK: offset function must return an integer
+!11 = metadata !{i32 ()* @size, i32* ()* @sizeptr}

Added: llvm/trunk/test/Verifier/alloc-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/alloc-2.ll?rev=158660&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/alloc-2.ll (added)
+++ llvm/trunk/test/Verifier/alloc-2.ll Mon Jun 18 11:04:04 2012
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s -o /dev/null
+
+declare i32 @size() readonly
+declare i32 @size1(i32) readnone
+declare i32 @size1i8(i8) readnone
+
+define void @ok(i8** %x, i32 %y) {
+entry:
+  %0 = load i8** %x, !alloc !0
+  %1 = load i8** %x, !alloc !1
+  %2 = load i8** %x, !alloc !2
+  %3 = load i8** %x, !alloc !3
+  %4 = load i8** %x, !alloc !{i32 (i32)* @size1, i32 (i32)* @size1, i32 %y}
+  ret void
+}
+!0 = metadata !{i32 ()* @size, i32 ()* @size}
+!1 = metadata !{i32 ()* @size, null}
+!2 = metadata !{i32 (i32)* @size1, i32 (i32)* @size1, i32 0}
+!3 = metadata !{i32 (i8)* @size1i8, i32 (i8)* @size1i8, i8 0}





More information about the llvm-commits mailing list