aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/LangRef.html131
-rw-r--r--include/llvm/Intrinsics.td16
-rw-r--r--test/Feature/memorymarkers.ll36
3 files changed, 183 insertions, 0 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 1b1655e..7adb896 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -273,6 +273,14 @@
<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>
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 9b0c876..bfa924c 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -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
index 0000000..06b8376
--- /dev/null
+++ b/test/Feature/memorymarkers.ll
@@ -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
+}