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

remove misleading documentation: LLVM has no atomic support yet.

llvm-svn: 42580
This commit is contained in:
Chris Lattner 2007-10-03 17:33:51 +00:00
parent a31fa80185
commit fc0f3994a0

View File

@ -191,15 +191,6 @@
</li>
<li><a href="#int_debugger">Debugger intrinsics</a></li>
<li><a href="#int_eh">Exception Handling intrinsics</a></li>
<li><a href="#int_atomics">Atomic Operations and Synchronization Intrinsics</a>
<ol>
<li><a href="#int_lcs">'<tt>llvm.atomic.lcs.*</tt>' Intrinsic</a></li>
<li><a href="#int_ls">'<tt>llvm.atomic.ls.*</tt>' Intrinsic</a></li>
<li><a href="#int_las">'<tt>llvm.atomic.las.*</tt>' Intrinsic</a></li>
<li><a href="#int_lss">'<tt>llvm.atomic.lss.*</tt>' Intrinsic</a></li>
<li><a href="#int_memory_barrier">'<tt>llvm.memory.barrier</tt>' Intrinsic</a></li>
</ol>
</li>
<li><a href="#int_trampoline">Trampoline Intrinsic</a>
<ol>
<li><a href="#int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a></li>
@ -291,7 +282,7 @@ by the verifier pass indicate bugs in transformation passes or input to
the parser.</p>
</div>
<!-- Describe the typesetting conventions here. -->
<!-- Describe the typesetting conventions here. --> </div>
<!-- *********************************************************************** -->
<div class="doc_section"> <a name="identifiers">Identifiers</a> </div>
@ -4859,298 +4850,6 @@ href="ExceptionHandling.html#format_common_intrinsics">LLVM Exception
Handling</a> document. </p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="int_atomics">Atomic Operations and Synchronization Intrinsics</a>
</div>
<div class="doc_text">
<p>
These intrinsic functions expand the "universal IR" of LLVM to represent
hardware constructs for atomic operations and memory synchronization. This
provides an interface to the hardware, not an interface to the programmer. It
is aimed at a low enough level to allow any programming models or APIs which
need atomic behaviors to map cleanly onto it. It is also modeled primarily on
hardware behavior. Just as hardware provides a "universal IR" for source
languages, it also provides a starting point for developing a "universal"
atomic operation and synchronization IR.
</p>
<p>
These do <em>not</em> form an API such as high-level threading libraries,
software transaction memory systems, atomic primitives, and intrinsic
functions as found in BSD, GNU libc, atomic_ops, APR, and other system and
application libraries. The hardware interface provided by LLVM should allow
a clean implementation of all of these APIs and parallel programming models.
No one model or paradigm should be selected above others unless the hardware
itself ubiquitously does so.
</p>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="int_lcs">'<tt>llvm.atomic.lcs.*</tt>' Intrinsic</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<p>
This is an overloaded intrinsic. You can use <tt>llvm.atomic.lcs</tt> on any
integer bit width. Not all targets support all bit widths however.</p>
<pre>
declare i8 @llvm.atomic.lcs.i8.i8p.i8.i8( i8* &lt;ptr&gt;, i8 &lt;cmp&gt;, i8 &lt;val&gt; )
declare i16 @llvm.atomic.lcs.i16.i16p.i16.i16( i16* &lt;ptr&gt;, i16 &lt;cmp&gt;, i16 &lt;val&gt; )
declare i32 @llvm.atomic.lcs.i32.i32p.i32.i32( i32* &lt;ptr&gt;, i32 &lt;cmp&gt;, i32 &lt;val&gt; )
declare i64 @llvm.atomic.lcs.i64.i64p.i64.i64( i64* &lt;ptr&gt;, i64 &lt;cmp&gt;, i64 &lt;val&gt; )
</pre>
<h5>Overview:</h5>
<p>
This loads a value in memory and compares it to a given value. If they are
equal, it stores a new value into the memory.
</p>
<h5>Arguments:</h5>
<p>
The <tt>llvm.atomic.lcs</tt> intrinsic takes three arguments. The result as
well as both <tt>cmp</tt> and <tt>val</tt> must be integer values with the
same bit width. The <tt>ptr</tt> argument must be a pointer to a value of
this integer type. While any bit width integer may be used, targets may only
lower representations they support in hardware.
</p>
<h5>Semantics:</h5>
<p>
This entire intrinsic must be executed atomically. It first loads the value
in memory pointed to by <tt>ptr</tt> and compares it with the value
<tt>cmp</tt>. If they are equal, <tt>val</tt> is stored into the memory. The
loaded value is yielded in all cases. This provides the equivalent of an
atomic compare-and-swap operation within the SSA framework.
</p>
<h5>Examples:</h5>
<pre>
%ptr = malloc i32
store i32 4, %ptr
%val1 = add i32 4, 4
%result1 = call i32 @llvm.atomic.lcs( i32* %ptr, i32 4, %val1 )
<i>; yields {i32}:result1 = 4</i>
%stored1 = icmp eq i32 %result1, 4 <i>; yields {i1}:stored1 = true</i>
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 8</i>
%val2 = add i32 1, 1
%result2 = call i32 @llvm.atomic.lcs( i32* %ptr, i32 5, %val2 )
<i>; yields {i32}:result2 = 8</i>
%stored2 = icmp eq i32 %result2, 5 <i>; yields {i1}:stored2 = false</i>
%memval2 = load i32* %ptr <i>; yields {i32}:memval2 = 8</i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="int_ls">'<tt>llvm.atomic.ls.*</tt>' Intrinsic</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<p>
This is an overloaded intrinsic. You can use <tt>llvm.atomic.ls</tt> on any
integer bit width. Not all targets support all bit widths however.</p>
<pre>
declare i8 @llvm.atomic.ls.i8.i8p.i8( i8* &lt;ptr&gt;, i8 &lt;val&gt; )
declare i16 @llvm.atomic.ls.i16.i16p.i16( i16* &lt;ptr&gt;, i16 &lt;val&gt; )
declare i32 @llvm.atomic.ls.i32.i32p.i32( i32* &lt;ptr&gt;, i32 &lt;val&gt; )
declare i64 @llvm.atomic.ls.i64.i64p.i64( i64* &lt;ptr&gt;, i64 &lt;val&gt; )
</pre>
<h5>Overview:</h5>
<p>
This intrinsic loads the value stored in memory at <tt>ptr</tt> and yields
the value from memory. It then stores the value in <tt>val</tt> in the memory
at <tt>ptr</tt>.
</p>
<h5>Arguments:</h5>
<p>
The <tt>llvm.atomic.ls</tt> intrinsic takes two arguments. Both the
<tt>val</tt> argument and the result must be integers of the same bit width.
The first argument, <tt>ptr</tt>, must be a pointer to a value of this
integer type. The targets may only lower integer representations they
support.
</p>
<h5>Semantics:</h5>
<p>
This intrinsic loads the value pointed to by <tt>ptr</tt>, yields it, and
stores <tt>val</tt> back into <tt>ptr</tt> atomically. This provides the
equivalent of an atomic swap operation within the SSA framework.
</p>
<h5>Examples:</h5>
<pre>
%ptr = malloc i32
store i32 4, %ptr
%val1 = add i32 4, 4
%result1 = call i32 @llvm.atomic.ls( i32* %ptr, i32 %val1 )
<i>; yields {i32}:result1 = 4</i>
%stored1 = icmp eq i32 %result1, 4 <i>; yields {i1}:stored1 = true</i>
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 8</i>
%val2 = add i32 1, 1
%result2 = call i32 @llvm.atomic.ls( i32* %ptr, i32 %val2 )
<i>; yields {i32}:result2 = 8</i>
%stored2 = icmp eq i32 %result2, 8 <i>; yields {i1}:stored2 = true</i>
%memval2 = load i32* %ptr <i>; yields {i32}:memval2 = 2</i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="int_las">'<tt>llvm.atomic.las.*</tt>' Intrinsic</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<p>
This is an overloaded intrinsic. You can use <tt>llvm.atomic.las</tt> on any
integer bit width. Not all targets support all bit widths however.</p>
<pre>
declare i8 @llvm.atomic.las.i8.i8p.i8( i8* &lt;ptr&gt;, i8 &lt;delta&gt; )
declare i16 @llvm.atomic.las.i16.i16p.i16( i16* &lt;ptr&gt;, i16 &lt;delta&gt; )
declare i32 @llvm.atomic.las.i32.i32p.i32( i32* &lt;ptr&gt;, i32 &lt;delta&gt; )
declare i64 @llvm.atomic.las.i64.i64p.i64( i64* &lt;ptr&gt;, i64 &lt;delta&gt; )
</pre>
<h5>Overview:</h5>
<p>
This intrinsic adds <tt>delta</tt> to the value stored in memory at
<tt>ptr</tt>. It yields the original value at <tt>ptr</tt>.
</p>
<h5>Arguments:</h5>
<p>
The intrinsic takes two arguments, the first a pointer to an integer value
and the second an integer value. The result is also an integer value. These
integer types can have any bit width, but they must all have the same bit
width. The targets may only lower integer representations they support.
</p>
<h5>Semantics:</h5>
<p>
This intrinsic does a series of operations atomically. It first loads the
value stored at <tt>ptr</tt>. It then adds <tt>delta</tt>, stores the result
to <tt>ptr</tt>. It yields the original value stored at <tt>ptr</tt>.
</p>
<h5>Examples:</h5>
<pre>
%ptr = malloc i32
store i32 4, %ptr
%result1 = call i32 @llvm.atomic.las( i32* %ptr, i32 4 )
<i>; yields {i32}:result1 = 4</i>
%result2 = call i32 @llvm.atomic.las( i32* %ptr, i32 2 )
<i>; yields {i32}:result2 = 8</i>
%result3 = call i32 @llvm.atomic.las( i32* %ptr, i32 5 )
<i>; yields {i32}:result3 = 10</i>
%memval = load i32* %ptr <i>; yields {i32}:memval1 = 15</i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="int_lss">'<tt>llvm.atomic.lss.*</tt>' Intrinsic</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<p>
This is an overloaded intrinsic. You can use <tt>llvm.atomic.lss</tt> on any
integer bit width. Not all targets support all bit widths however.</p>
<pre>
declare i8 @llvm.atomic.lss.i8.i8.i8( i8* &lt;ptr&gt;, i8 &lt;delta&gt; )
declare i16 @llvm.atomic.lss.i16.i16.i16( i16* &lt;ptr&gt;, i16 &lt;delta&gt; )
declare i32 @llvm.atomic.lss.i32.i32.i32( i32* &lt;ptr&gt;, i32 &lt;delta&gt; )
declare i64 @llvm.atomic.lss.i64.i64.i64( i64* &lt;ptr&gt;, i64 &lt;delta&gt; )
</pre>
<h5>Overview:</h5>
<p>
This intrinsic subtracts <tt>delta</tt> from the value stored in memory at
<tt>ptr</tt>. It yields the original value at <tt>ptr</tt>.
</p>
<h5>Arguments:</h5>
<p>
The intrinsic takes two arguments, the first a pointer to an integer value
and the second an integer value. The result is also an integer value. These
integer types can have any bit width, but they must all have the same bit
width. The targets may only lower integer representations they support.
</p>
<h5>Semantics:</h5>
<p>
This intrinsic does a series of operations atomically. It first loads the
value stored at <tt>ptr</tt>. It then subtracts <tt>delta</tt>,
stores the result to <tt>ptr</tt>. It yields the original value stored
at <tt>ptr</tt>.
</p>
<h5>Examples:</h5>
<pre>
%ptr = malloc i32
store i32 32, %ptr
%result1 = call i32 @llvm.atomic.lss( i32* %ptr, i32 4 )
<i>; yields {i32}:result1 = 32</i>
%result2 = call i32 @llvm.atomic.lss( i32* %ptr, i32 2 )
<i>; yields {i32}:result2 = 28</i>
%result3 = call i32 @llvm.atomic.lss( i32* %ptr, i32 5 )
<i>; yields {i32}:result3 = 26</i>
%memval = load i32* %ptr <i>; yields {i32}:memval1 = 21</i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="int_memory_barrier">'<tt>llvm.memory.barrier</tt>' Intrinsic</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<pre>
declare void @llvm.memory.barrier( i1 &lt;ll&gt;, i1 &lt;ls&gt;, i1 &lt;sl&gt;, i1 &lt;ss&gt; )
</pre>
<h5>Overview:</h5>
<p>
The <tt>llvm.memory.barrier</tt> intrinsic guarantees ordering between
specific pairs of memory access types.
</p>
<h5>Arguments:</h5>
<p>
The <tt>llvm.memory.barrier</tt> intrinsic requires four boolean arguments.
Each argument enables a specific barrier as listed below.
</p>
<ul>
<li><tt>ll</tt>: load-load barrier</li>
<li><tt>ls</tt>: load-store barrier</li>
<li><tt>sl</tt>: store-load barrier</li>
<li><tt>ss</tt>: store-store barrier</li>
</ul>
<h5>Semantics:</h5>
<p>
This intrinsic causes the system to enforce some ordering constraints upon
the loads and stores of the program. This barrier does not indicate
<em>when</em> any events will occur, it only enforces an <em>order</em> in
which they occur. For any of the specified pairs of load and store operations
(f.ex. load-load, or store-load), all of the first operations preceding the
barrier will complete before any of the second operations succeeding the
barrier begin. Specifically the semantics for each pairing is as follows:
</p>
<ul>
<li><tt>ll</tt>: All loads before the barrier must complete before any load
after the barrier begins.</li>
<li><tt>ls</tt>: All loads before the barrier must complete before any
store after the barrier begins.</li>
<li><tt>ss</tt>: All stores before the barrier must complete before any
store after the barrier begins.</li>
<li><tt>sl</tt>: All stores before the barrier must complete before any
load after the barrier begins.</li>
</ul>
<p>
These semantics are applied with a logical "and" behavior when more than one
is enabled in a single memory barrier intrinsic.
</p>
<h5>Example:</h5>
<pre>
%ptr = malloc i32
store i32 4, %ptr
%result1 = load i32* %ptr <i>; yields {i32}:result1 = 4</i>
call void @llvm.memory.barrier( i1 false, i1 true, i1 false, i1 false )
<i>; guarantee the above finishes</i>
store i32 8, %ptr <i>; before this begins</i>
</pre>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="int_trampoline">Trampoline Intrinsic</a>