Add new "memory use marker" intrinsics. These indicate lifetimes and invariant
authorNick Lewycky <nicholas@mxc.ca>
Tue, 13 Oct 2009 07:03:23 +0000 (07:03 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Tue, 13 Oct 2009 07:03:23 +0000 (07:03 +0000)
sections of memory objects.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83953 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LangRef.html
include/llvm/Intrinsics.td
test/Feature/memorymarkers.ll [new file with mode: 0644]

index 1b1655e42fddb2e7423c041bfe41ab04557518af..7adb89621f4134c47371103a923c5fc8e41fc26a 100644 (file)
           <li><a href="#int_atomic_load_umin"><tt>llvm.atomic.load.umin</tt></a></li>
         </ol>
       </li>
+      <li><a href="#int_memorymarkers">Memory Use Markers</a>
+        <ol>
+          <li><a href="#int_lifetime_start"><tt>llvm.lifetime.start</tt></a></li>
+          <li><a href="#int_lifetime_end"><tt>llvm.lifetime.end</tt></a></li>
+          <li><a href="#int_invariant_start"><tt>llvm.invariant.start</tt></a></li>
+          <li><a href="#int_invariant_end"><tt>llvm.invariant.end</tt></a></li>
+        </ol>
+      </li>
       <li><a href="#int_general">General intrinsics</a>
         <ol>
           <li><a href="#int_var_annotation">
@@ -6980,6 +6988,129 @@ LLVM</a>.</p>
 
 </div>
 
+
+<!-- ======================================================================= -->
+<div class="doc_subsection">
+  <a name="int_memorymarkers">Memory Use Markers</a>
+</div>
+
+<div class="doc_text">
+
+<p>This class of intrinsics exists to information about the lifetime of memory
+   objects and ranges where variables are immutable.</p>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="int_lifetime_start">'<tt>llvm.lifetime.start</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<pre>
+  declare void @llvm.lifetime.start(i64 &lt;size&gt;, i8* nocapture &lt;ptr&gt;)
+</pre>
+
+<h5>Overview:</h5>
+<p>The '<tt>llvm.lifetime.start</tt>' intrinsic specifies the start of a memory
+   object's lifetime.</p>
+
+<h5>Arguments:</h5>
+<p>The first argument is a the size of the object, or -1 if it is variable
+   sized.  The second argument is a pointer to the object.</p>
+
+<h5>Semantics:</h5>
+<p>This intrinsic indicates that before this point in the code, the value of the
+   memory pointed to by <tt>ptr</tt> is dead.  This means that it is known to
+   never be used and has an undefined value.  A load from the pointer that is
+   preceded by this intrinsic can be replaced with
+   <tt>'<a href="#undefvalues">undef</a>'</tt>.</p>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="int_lifetime_end">'<tt>llvm.lifetime.end</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<pre>
+  declare void @llvm.lifetime.end(i64 &lt;size&gt;, i8* nocapture &lt;ptr&gt;)
+</pre>
+
+<h5>Overview:</h5>
+<p>The '<tt>llvm.lifetime.end</tt>' intrinsic specifies the end of a memory
+   object's lifetime.</p>
+
+<h5>Arguments:</h5>
+<p>The first argument is a the size of the object, or -1 if it is variable
+   sized.  The second argument is a pointer to the object.</p>
+
+<h5>Semantics:</h5>
+<p>This intrinsic indicates that after this point in the code, the value of the
+   memory pointed to by <tt>ptr</tt> is dead.  This means that it is known to
+   never be used and has an undefined value.  Any stores into the memory object
+   following this intrinsic may be removed as dead.
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="int_invariant_start">'<tt>llvm.invariant.start</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<pre>
+  declare {}* @llvm.invariant.start(i64 &lt;size&gt;, i8* nocapture &lt;ptr&gt;) readonly
+</pre>
+
+<h5>Overview:</h5>
+<p>The '<tt>llvm.invariant.start</tt>' intrinsic specifies that the contents of
+   a memory object will not change.</p>
+
+<h5>Arguments:</h5>
+<p>The first argument is a the size of the object, or -1 if it is variable
+   sized.  The second argument is a pointer to the object.</p>
+
+<h5>Semantics:</h5>
+<p>This intrinsic indicates that until an <tt>llvm.invariant.end</tt> that uses
+   the return value, the referenced memory location is constant and
+   unchanging.</p>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+  <a name="int_invariant_end">'<tt>llvm.invariant.end</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<pre>
+  declare void @llvm.invariant.end({}* &lt;start&gt;, i64 &lt;size&gt;, i8* nocapture &lt;ptr&gt;)
+</pre>
+
+<h5>Overview:</h5>
+<p>The '<tt>llvm.invariant.end</tt>' intrinsic specifies that the contents of
+   a memory object are mutable.</p>
+
+<h5>Arguments:</h5>
+<p>The first argument is the matching <tt>llvm.invariant.start</tt> intrinsic.
+   The second argument is a the size of the object, or -1 if it is variable
+   sized and the third argument is a pointer to the object.</p>
+
+<h5>Semantics:</h5>
+<p>This intrinsic indicates that the memory is mutable again.</p>
+
+</div>
+
 <!-- ======================================================================= -->
 <div class="doc_subsection">
   <a name="int_general">General Intrinsics</a>
index 9b0c876d72f5d29253c4418e628827b6f1e0be8c..bfa924cd866bf8449cebaea09e00eca721d9b355 100644 (file)
@@ -421,6 +421,22 @@ def int_atomic_load_umax : Intrinsic<[llvm_anyint_ty],
                                      [IntrWriteArgMem, NoCapture<0>]>,
                            GCCBuiltin<"__sync_fetch_and_umax">;
 
+//===------------------------- Memory Use Markers -------------------------===//
+//
+def int_lifetime_start  : Intrinsic<[llvm_void_ty],
+                                    [llvm_i64_ty, llvm_ptr_ty],
+                                    [IntrWriteArgMem, NoCapture<1>]>;
+def int_lifetime_end    : Intrinsic<[llvm_void_ty],
+                                    [llvm_i64_ty, llvm_ptr_ty],
+                                    [IntrWriteArgMem, NoCapture<1>]>;
+def int_invariant_start : Intrinsic<[llvm_descriptor_ty],
+                                    [llvm_i64_ty, llvm_ptr_ty],
+                                    [IntrReadArgMem, NoCapture<1>]>;
+def int_invariant_end   : Intrinsic<[llvm_void_ty],
+                                    [llvm_descriptor_ty, llvm_i64_ty,
+                                     llvm_ptr_ty],
+                                    [IntrWriteArgMem, NoCapture<2>]>;
+
 //===-------------------------- Other Intrinsics --------------------------===//
 //
 def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
diff --git a/test/Feature/memorymarkers.ll b/test/Feature/memorymarkers.ll
new file mode 100644 (file)
index 0000000..06b8376
--- /dev/null
@@ -0,0 +1,36 @@
+; RUN: llvm-as -disable-output < %s
+
+%"struct.std::pair<int,int>" = type { i32, i32 }
+
+declare void @_Z3barRKi(i32*)
+
+declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
+declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
+declare {}* @llvm.invariant.start(i64, i8* nocapture) readonly nounwind
+declare void @llvm.invariant.end({}*, i64, i8* nocapture) nounwind
+
+define i32 @_Z4foo2v() nounwind {
+entry:
+  %x = alloca %"struct.std::pair<int,int>"
+  %y = bitcast %"struct.std::pair<int,int>"* %x to i8*
+
+  ;; Constructor starts here (this isn't needed since it is immediately
+  ;; preceded by an alloca, but shown for completeness).
+  call void @llvm.lifetime.start(i64 8, i8* %y)
+
+  %0 = getelementptr %"struct.std::pair<int,int>"* %x, i32 0, i32 0
+  store i32 4, i32* %0, align 8
+  %1 = getelementptr %"struct.std::pair<int,int>"* %x, i32 0, i32 1
+  store i32 5, i32* %1, align 4
+
+  ;; Constructor has finished here.
+  %inv = call {}* @llvm.invariant.start(i64 8, i8* %y)
+  call void @_Z3barRKi(i32* %0) nounwind
+  %2 = load i32* %0, align 8
+
+  ;; Destructor is run here.
+  call void @llvm.invariant.end({}* %inv, i64 8, i8* %y)
+  ;; Destructor is done here.
+  call void @llvm.lifetime.end(i64 8, i8* %y)
+  ret i32 %2
+}