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:
parent
592c5055dd
commit
ab1dbddc83
@ -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 <size>, i8* nocapture <ptr>)
|
||||
</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 <size>, i8* nocapture <ptr>)
|
||||
</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 <size>, i8* nocapture <ptr>) 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({}* <start>, i64 <size>, i8* nocapture <ptr>)
|
||||
</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>
|
||||
|
@ -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]>,
|
||||
|
36
test/Feature/memorymarkers.ll
Normal file
36
test/Feature/memorymarkers.ll
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user