1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

Add new "memory use marker" intrinsics. These indicate lifetimes and invariant

sections of memory objects.

llvm-svn: 83953
This commit is contained in:
Nick Lewycky 2009-10-13 07:03:23 +00:00
parent 592c5055dd
commit ab1dbddc83
3 changed files with 183 additions and 0 deletions

View File

@ -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>

View 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]>,

View File

@ -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
}