summaryrefslogtreecommitdiffstats
path: root/llvm/docs/Coroutines.rst
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-07-27 05:12:35 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-07-27 05:12:35 +0000
commit7855719c102ef1440fb846dec6716e263d64efdc (patch)
treeec4380bf9d50bd6b6a924702894dabe60f3a058a /llvm/docs/Coroutines.rst
parent18c964d7a43a9c3c8fbecb5d4646d5ba3a871ca7 (diff)
downloadbcm5719-llvm-7855719c102ef1440fb846dec6716e263d64efdc.tar.gz
bcm5719-llvm-7855719c102ef1440fb846dec6716e263d64efdc.zip
[coroutines] Part 2 of N: Adding Coroutine Intrinsics
This is the second patch in the coroutine series. It adds coroutine intrinsics and updates intrinsic cost in TargetTransformInfoImpl.h. Patch by Gor Nishanov! Differential Revision: https://reviews.llvm.org/D22659 llvm-svn: 276839
Diffstat (limited to 'llvm/docs/Coroutines.rst')
-rw-r--r--llvm/docs/Coroutines.rst48
1 files changed, 22 insertions, 26 deletions
diff --git a/llvm/docs/Coroutines.rst b/llvm/docs/Coroutines.rst
index 9d89a7e769c..87d5022cc68 100644
--- a/llvm/docs/Coroutines.rst
+++ b/llvm/docs/Coroutines.rst
@@ -215,15 +215,9 @@ RAII idiom and is suitable for allocation elision optimization which avoid
dynamic allocation by storing the coroutine frame as a static `alloca` in its
caller.
-If a coroutine uses allocation and deallocation functions that are known to
-LLVM, unused calls to `malloc` and calls to `free` with `null` argument will be
-removed as dead code. However, if custom allocation functions are used, the
-`coro.alloc` and `coro.free` intrinsics can be used to enable removal of custom
-allocation and deallocation code when coroutine does not require dynamic
-allocation of the coroutine frame.
-
In the entry block, we will call `coro.alloc`_ intrinsic that will return `null`
-when dynamic allocation is required, and non-null otherwise:
+when dynamic allocation is required, and an address of an alloca on the caller's
+frame where coroutine frame can be stored if dynamic allocation is elided.
.. code-block:: llvm
@@ -256,8 +250,7 @@ thus skipping the deallocation code:
...
With allocations and deallocations represented as described as above, after
-coroutine heap allocation elision optimization, the resulting main will end up
-looking just like it was when we used `malloc` and `free`:
+coroutine heap allocation elision optimization, the resulting main will be:
.. code-block:: llvm
@@ -419,12 +412,19 @@ store the current value produced by a coroutine.
entry:
%promise = alloca i32
%pv = bitcast i32* %promise to i8*
+ %elide = call i8* @llvm.coro.alloc()
+ %need.dyn.alloc = icmp ne i8* %elide, null
+ br i1 %need.dyn.alloc, label %coro.begin, label %dyn.alloc
+ dyn.alloc:
%size = call i32 @llvm.coro.size.i32()
%alloc = call i8* @malloc(i32 %size)
- %hdl = call noalias i8* @llvm.coro.begin(i8* %alloc, i32 0, i8* %pv, i8* null)
+ br label %coro.begin
+ coro.begin:
+ %phi = phi i8* [ %elide, %entry ], [ %alloc, %dyn.alloc ]
+ %hdl = call noalias i8* @llvm.coro.begin(i8* %phi, i32 0, i8* %pv, i8* null)
br label %loop
loop:
- %n.val = phi i32 [ %n, %entry ], [ %inc, %loop ]
+ %n.val = phi i32 [ %n, %coro.begin ], [ %inc, %loop ]
%inc = add nsw i32 %n.val, 1
store i32 %n.val, i32* %promise
%0 = call i8 @llvm.coro.suspend(token none, i1 false)
@@ -461,8 +461,7 @@ coroutine promise.
ret i32 0
}
-After example in this section is compiled, result of the compilation will
-exactly like the result of the very first example:
+After example in this section is compiled, result of the compilation will be:
.. code-block:: llvm
@@ -758,14 +757,13 @@ the coroutine frame.
Overview:
"""""""""
-The '``llvm.coro.begin``' intrinsic returns an address of the
-coroutine frame.
+The '``llvm.coro.begin``' intrinsic returns an address of the coroutine frame.
Arguments:
""""""""""
-The first argument is a pointer to a block of memory in which coroutine frame
-may use if memory for the coroutine frame needs to be allocated dynamically.
+The first argument is a pointer to a block of memory where coroutine frame
+will be stored.
The second argument provides information on the alignment of the memory returned
by the allocation function and given to `coro.begin` by the first argument. If
@@ -788,7 +786,7 @@ may be at offset to the `%mem` argument. (This could be beneficial if
instructions that express relative access to data can be more compactly encoded
with small positive and negative offsets).
-Frontend should emit exactly one `coro.begin` intrinsic per coroutine.
+A frontend should emit exactly one `coro.begin` intrinsic per coroutine.
.. _coro.free:
@@ -861,10 +859,8 @@ Semantics:
If the coroutine is eligible for heap elision, this intrinsic is lowered to an
alloca storing the coroutine frame. Otherwise, it is lowered to constant `null`.
-This intrinsic only needs to be used if a custom allocation function is used
-(i.e. a function not recognized by LLVM as a memory allocation function) and the
-language rules allow for custom allocation / deallocation to be elided when not
-needed.
+
+A frontend should emit at most one `coro.alloc` intrinsic per coroutine.
Example:
""""""""
@@ -1076,7 +1072,7 @@ to the coroutine:
Overview:
"""""""""
-The '``llvm.coro.param``' is used by the frontend to mark up the code used to
+The '``llvm.coro.param``' is used by a frontend to mark up the code used to
construct and destruct copies of the parameters. If the optimizer discovers that
a particular parameter copy is not used after any suspends, it can remove the
construction and destruction of the copy by replacing corresponding coro.param
@@ -1180,8 +1176,8 @@ earlier passes.
Upstreaming sequence (rough plan)
=================================
-#. Add documentation. <= we are here
-#. Add coroutine intrinsics.
+#. Add documentation.
+#. Add coroutine intrinsics. <= we are here
#. Add empty coroutine passes.
#. Add coroutine devirtualization + tests.
#. Add CGSCC restart trigger + tests.
OpenPOWER on IntegriCloud