[llvm-commits] [llvm] r40115 - /llvm/trunk/docs/LangRef.html

Chris Lattner clattner at apple.com
Fri Sep 28 12:16:55 PDT 2007


On Jul 20, 2007, at 12:34 PM, Chandler Carruth wrote:

> Author: chandlerc
> Date: Fri Jul 20 14:34:37 2007
> New Revision: 40115
>
> URL: http://llvm.org/viewvc/llvm-project?rev=40115&view=rev
> Log:
> This introduces the atomic operation intrinsics into the  
> documentation. This is
> a preview for the intrinsics that are going to be implemented over  
> the next few
> weeks.

Chandler, what is the state of this work?  This should be removed  
from LangRef unless it is going to be implemented "real soon now".

-Chris

>
> Modified:
>     llvm/trunk/docs/LangRef.html
>
> Modified: llvm/trunk/docs/LangRef.html
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ 
> LangRef.html?rev=40115&r1=40114&r2=40115&view=diff
>
> ====================================================================== 
> ========
> --- llvm/trunk/docs/LangRef.html (original)
> +++ llvm/trunk/docs/LangRef.html Fri Jul 20 14:34:37 2007
> @@ -191,6 +191,15 @@
>        </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_general">General intrinsics</a></li>
>          <ol>
>            <li><a  
> href="#int_var_annotation">'<tt>llvm.var.annotation</tt>'
> @@ -4822,6 +4831,302 @@
>
>  <!--  
> ====================================================================== 
> = -->
>  <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 "unviresal 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
> +  functionss 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.
> +<pre>
> +declare i8 @llvm.atomic.lcs.i8.i8p.i8.i8( i8* <ptr>, i8  
> <cmp>, i8 <val> )
> +declare i16 @llvm.atomic.lcs.i16.i16p.i16.i16( i16* <ptr>,  
> i16 <cmp>, i16 <val> )
> +declare i32 @llvm.atomic.lcs.i32.i32p.i32.i32( i32* <ptr>,  
> i32 <cmp>, i32 <val> )
> +declare i64 @llvm.atomic.lcs.i64.i64p.i64.i64( i64* <ptr>,  
> i64 <cmp>, i64 <val> )
> +</pre>
> +</p>
> +<h5>Overview:</h5>
> +<p>
> +  This loads a value in shared memory and compares it to a given  
> value. If they
> +  are equal, it stores a new value into the shared 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 shared 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  
> shared
> +  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.
> +<pre>
> +declare i8 @llvm.atomic.ls.i8.i8p.i8( i8* <ptr>, i8  
> <val> )
> +declare i16 @llvm.atomic.ls.i16.i16p.i16( i16* <ptr>, i16  
> <val> )
> +declare i32 @llvm.atomic.ls.i32.i32p.i32( i32* <ptr>, i32  
> <val> )
> +declare i64 @llvm.atomic.ls.i64.i64p.i64( i64* <ptr>, i64  
> <val> )
> +</pre>
> +</p>
> +<h5>Overview:</h5>
> +<p>
> +  This intrinsic loads the value stored in shared memory at  
> <tt>ptr</tt> and
> +  yields the value from memory. It then stores the value in  
> <tt>val</tt> in the
> +  shared 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.
> +<pre>
> +declare i8 @llvm.atomic.las.i8.i8p.i8( i8* <ptr>, i8  
> <delta> )
> +declare i16 @llvm.atomic.las.i16.i16p.i16( i16* <ptr>, i16  
> <delta> )
> +declare i32 @llvm.atomic.las.i32.i32p.i32( i32* <ptr>, i32  
> <delta> )
> +declare i64 @llvm.atomic.las.i64.i64p.i64( i64* <ptr>, i64  
> <delta> )
> +</pre>
> +</p>
> +<h5>Overview:</h5>
> +<p>
> +  This intrinsic adds <tt>delta</tt> to the value stored in shared  
> 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.
> +<pre>
> +declare i8 @llvm.atomic.lss.i8.i8.i8( i8* <ptr>, i8  
> <delta> )
> +declare i16 @llvm.atomic.lss.i16.i16.i16( i16* <ptr>, i16  
> <delta> )
> +declare i32 @llvm.atomic.lss.i32.i32.i32( i32* <ptr>, i32  
> <delta> )
> +declare i64 @llvm.atomic.lss.i64.i64.i64( i64* <ptr>, i64  
> <delta> )
> +</pre>
> +</p>
> +<h5>Overview:</h5>
> +<p>
> +  This intrinsic subtracts <tt>delta</tt> from the value stored in  
> shared
> +  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>
> +<p>
> +<pre>
> +declare void @llvm.memory.barrier( i1 <ll>, i1 <ls>,  
> i1 <sl>, i1 <ss> )
> +</pre>
> +</p>
> +<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.
> +  <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>
> +</p>
> +<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:
> +  <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>
> +  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_general">General Intrinsics</a>
>  </div>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list