diff options
-rw-r--r-- | docs/LangRef.html | 131 | ||||
-rw-r--r-- | include/llvm/Intrinsics.td | 16 | ||||
-rw-r--r-- | test/Feature/memorymarkers.ll | 36 |
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 <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> 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 +} |