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

Chandler Carruth chandlerc at gmail.com
Fri Jul 20 12:34:38 PDT 2007


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.

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>
 





More information about the llvm-commits mailing list