summaryrefslogtreecommitdiffstats
path: root/llvm/docs/Coroutines.rst
Commit message (Collapse)AuthorAgeFilesLines
* fix another doc typo to cycle botsNico Weber2019-12-201-1/+1
|
* Extend coroutines to support a "returned continuation" lowering.John McCall2019-08-141-31/+272
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A quick contrast of this ABI with the currently-implemented ABI: - Allocation is implicitly managed by the lowering passes, which is fine for frontends that are fine with assuming that allocation cannot fail. This assumption is necessary to implement dynamic allocas anyway. - The lowering attempts to fit the coroutine frame into an opaque, statically-sized buffer before falling back on allocation; the same buffer must be provided to every resume point. A buffer must be at least pointer-sized. - The resume and destroy functions have been combined; the continuation function takes a parameter indicating whether it has succeeded. - Conversely, every suspend point begins its own continuation function. - The continuation function pointer is directly returned to the caller instead of being stored in the frame. The continuation can therefore directly destroy the frame when exiting the coroutine instead of having to leave it in a defunct state. - Other values can be returned directly to the caller instead of going through a promise allocation. The frontend provides a "prototype" function declaration from which the type, calling convention, and attributes of the continuation functions are taken. - On the caller side, the frontend can generate natural IR that directly uses the continuation functions as long as it prevents IPO with the coroutine until lowering has happened. In combination with the point above, the frontend is almost totally in charge of the ABI of the coroutine. - Unique-yield coroutines are given some special treatment. llvm-svn: 368788
* [coroutines] Add support for llvm.coro.noop intrinsicsGor Nishanov2018-04-021-0/+26
| | | | | | | | | | | | | | | | Summary: A recent addition to Coroutines TS (https://wg21.link/p0913) adds a pre-defined coroutine noop_coroutine that does nothing. To implement this feature, we implemented an llvm.coro.noop intrinsic that returns a coroutine handle to a coroutine that does nothing when resumed or destroyed. Reviewers: EricWF, modocache, rnk, lewissbaker Reviewed By: modocache Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D45114 llvm-svn: 328986
* fix trivial typos in documents; NFCHiroshi Inoue2017-07-021-1/+1
| | | | llvm-svn: 306975
* [coroutines] Add syntax coloring to examples in Coroutines.rstGor Nishanov2017-04-051-19/+19
| | | | | | | | Subscribers: EricWF Differential Revision: https://reviews.llvm.org/D31699 llvm-svn: 299517
* [coroutines] Add handling for unwind coro.endsGor Nishanov2017-03-071-18/+67
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: The purpose of coro.end intrinsic is to allow frontends to mark the cleanup and other code that is only relevant during the initial invocation of the coroutine and should not be present in resume and destroy parts. In landing pads coro.end is replaced with an appropriate instruction to unwind to caller. The handling of coro.end differs depending on whether the target is using landingpad or WinEH exception model. For landingpad based exception model, it is expected that frontend uses the `coro.end`_ intrinsic as follows: ``` ehcleanup: %InResumePart = call i1 @llvm.coro.end(i8* null, i1 true) br i1 %InResumePart, label %eh.resume, label %cleanup.cont cleanup.cont: ; rest of the cleanup eh.resume: %exn = load i8*, i8** %exn.slot, align 8 %sel = load i32, i32* %ehselector.slot, align 4 %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn, 0 %lpad.val29 = insertvalue { i8*, i32 } %lpad.val, i32 %sel, 1 resume { i8*, i32 } %lpad.val29 ``` The `CoroSpit` pass replaces `coro.end` with ``True`` in the resume functions, thus leading to immediate unwind to the caller, whereas in start function it is replaced with ``False``, thus allowing to proceed to the rest of the cleanup code that is only needed during initial invocation of the coroutine. For Windows Exception handling model, a frontend should attach a funclet bundle referring to an enclosing cleanuppad as follows: ``` ehcleanup: %tok = cleanuppad within none [] %unused = call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %tok) ] cleanupret from %tok unwind label %RestOfTheCleanup ``` The `CoroSplit` pass, if the funclet bundle is present, will insert ``cleanupret from %tok unwind to caller`` before the `coro.end`_ intrinsic and will remove the rest of the block. Reviewers: majnemer Reviewed By: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D25543 llvm-svn: 297223
* Changing a code block to text because Sphinx does not like it on the builder ↵Aaron Ballman2016-08-311-2/+2
| | | | | | (http://lab.llvm.org:8011/builders/llvm-sphinx-docs/builds/12517/steps/docs-llvm-html/logs/stdio) llvm-svn: 280247
* Changing a code block to text because Sphinx does not like it on the builder ↵Aaron Ballman2016-08-311-1/+1
| | | | | | (http://lab.llvm.org:8011/builders/llvm-sphinx-docs/builds/12516/steps/docs-llvm-html/logs/stdio) llvm-svn: 280238
* [Coroutines] Part 9: Add cleanup subfunction.Gor Nishanov2016-08-291-29/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: [Coroutines] Part 9: Add cleanup subfunction. This patch completes coroutine heap allocation elision. Now, the heap elision example from docs\Coroutines.rst compiles and produces expected result (see test/Transform/Coroutines/ex3.ll) Intrinsic Changes: * coro.free gets a token parameter tying it to coro.id to allow reliably discovering all coro.frees associated with a particular coroutine. * coro.id gets an extra parameter that points back to a coroutine function. This allows to check whether a coro.id describes the enclosing function or it belongs to a different function that was later inlined. CoroSplit now creates three subfunctions: # f$resume - resume logic # f$destroy - cleanup logic, followed by a deallocation code # f$cleanup - just the cleanup code CoroElide pass during devirtualization replaces coro.destroy with either f$destroy or f$cleanup depending whether heap elision is performed or not. Other fixes, improvements: * Fixed buglet in Shape::buildFrame that was not creating coro.save properly if coroutine has more than one suspend point. * Switched to using variable width suspend index field (no longer limited to 32 bit index field can be as little as i1 or as large as i<whatever-size_t-is>) Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D23844 llvm-svn: 279971
* [Coroutines]: Part6b: Add coro.id intrinsic.Gor Nishanov2016-08-121-73/+98
| | | | | | | | | | | | | | | Summary: 1. Make coroutine representation more robust against optimization that may duplicate instruction by introducing coro.id intrinsics that returns a token that will get fed into coro.alloc and coro.begin. Due to coro.id returning a token, it won't get duplicated and can be used as reliable indicator of coroutine identify when a particular coroutine call gets inlined. 2. Move last three arguments of coro.begin into coro.id as they will be shared if coro.begin will get duplicated. 3. doc + test + code updated to support the new intrinsic. Reviewers: mehdi_amini, majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D23412 llvm-svn: 278481
* [Coroutines] Part 6: Elide dynamic allocation of a coroutine frame when possibleGor Nishanov2016-08-101-31/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: A particular coroutine usage pattern, where a coroutine is created, manipulated and destroyed by the same calling function, is common for coroutines implementing 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. coro.free and coro.alloc intrinsics are used to indicate which code needs to be suppressed when dynamic allocation elision happens: ``` entry: %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: %alloc = call i8* @CustomAlloc(i32 4) br label %coro.begin coro.begin: %phi = phi i8* [ %elide, %entry ], [ %alloc, %dyn.alloc ] %hdl = call i8* @llvm.coro.begin(i8* %phi, i32 0, i8* null, i8* bitcast ([2 x void (%f.frame*)*]* @f.resumers to i8*)) ``` and ``` %mem = call i8* @llvm.coro.free(i8* %hdl) %need.dyn.free = icmp ne i8* %mem, null br i1 %need.dyn.free, label %dyn.free, label %if.end dyn.free: call void @CustomFree(i8* %mem) br label %if.end if.end: ... ``` If heap allocation elision is performed, we replace coro.alloc with a static alloca on the caller frame and coro.free with null constant. Also, we need to make sure that if there are any tail calls referencing the coroutine frame, we need to remote tail call attribute, since now coroutine frame lives on the stack. Documentation and overview is here: http://llvm.org/docs/Coroutines.html. Upstreaming sequence (rough plan) 1.Add documentation. (https://reviews.llvm.org/D22603) 2.Add coroutine intrinsics. (https://reviews.llvm.org/D22659) 3.Add empty coroutine passes. (https://reviews.llvm.org/D22847) 4.Add coroutine devirtualization + tests. ab) Lower coro.resume and coro.destroy (https://reviews.llvm.org/D22998) c) Do devirtualization (https://reviews.llvm.org/D23229) 5.Add CGSCC restart trigger + tests. (https://reviews.llvm.org/D23234) 6.Add coroutine heap elision + tests. <= we are here 7.Add the rest of the logic (split into more patches) Reviewers: mehdi_amini, majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D23245 llvm-svn: 278242
* testing commit accessGor Nishanov2016-08-051-1/+1
| | | | llvm-svn: 277816
* [coroutines] Part 3 of N: Adding Boilerplate for Coroutine PassesDavid Majnemer2016-07-281-2/+2
| | | | | | | | | | | | | This adds boilerplate code for all coroutine passes, the passes are no-ops for now. Also, a small test has been added to verify that passes execute in the expected order or not at all if coroutine support is disabled. Patch by Gor Nishanov! Differential Revision: https://reviews.llvm.org/D22847 llvm-svn: 277033
* Fix Coroutines doc exampleMehdi Amini2016-07-271-1/+1
| | | | | | SSA was broken. llvm-svn: 276843
* [coroutines] Part 2 of N: Adding Coroutine IntrinsicsDavid Majnemer2016-07-271-26/+22
| | | | | | | | | | | 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
* Fix docs/Coroutines.rst syntax highlighting on LinuxSanjoy Das2016-07-261-5/+5
| | | | | | | | | | | | | Summary: s/code-block:: C++/code-block:: c++ in docs/Coroutines.rst . Patch by Gor Nishanov! Edited by Sanjoy to fix a missing s/C/c/. Reviewers: sanjoy, rengolin Differential Revision: https://reviews.llvm.org/D22832 llvm-svn: 276806
* Change some more llvm highlighting instances to be text instead. It seems ↵Aaron Ballman2016-07-231-9/+9
| | | | | | | | that Pygment does not handle "token" or "none" yet, and this caused the documentation bot to go red. Patch by Gor Nishanov. llvm-svn: 276532
* Switching the highlighting from llvm to none in an attempt to appease the ↵Aaron Ballman2016-07-231-1/+1
| | | | | | build bot (http://lab.llvm.org:8011/builders/llvm-sphinx-docs/builds/11984/steps/docs-llvm-html/logs/stdio). llvm-svn: 276531
* [coroutines] Part 1 of N: DocumentationDavid Majnemer2016-07-231-0/+1218
This is the first patch in the coroutine series. It contains the documentation for the coroutine intrinsics and their usage. Patch by Gor Nishanov! Differential Revision: https://reviews.llvm.org/D22603 llvm-svn: 276513
OpenPOWER on IntegriCloud