Commit Graph

18 Commits

Author SHA1 Message Date
Brian Gesiak 986062219f [Coroutines] Use allocator overload when available
Summary:
Depends on https://reviews.llvm.org/D42605.

An implementation of the behavior described in `[dcl.fct.def.coroutine]/7`:
when a promise type overloads `operator new` using a "placement new"
that takes the same argument types as the coroutine function, that
overload is used when allocating the coroutine frame.

Simply passing references to the coroutine function parameters directly
to `operator new` results in invariant violations in LLVM's coroutine
splitting pass, so this implementation modifies Clang codegen to
produce allocator-specific alloc/store/loads for each parameter being
forwarded to the allocator.

Test Plan: `check-clang`

Reviewers: rsmith, GorNishanov, eric_niebler

Reviewed By: GorNishanov

Subscribers: lewissbaker, EricWF, cfe-commits

Differential Revision: https://reviews.llvm.org/D42606

llvm-svn: 325291
2018-02-15 20:37:22 +00:00
Eric Fiselier 8ed97272ab [coroutines] Fix application of NRVO to Coroutine "Gro" or return object.
Summary:
Fix NRVO for Gro variable.

Previously, we only marked the GRO declaration as an NRVO variable
when its QualType and the function return's QualType matched exactly
(using operator==). However, this was incorrect for two reasons:

1. We were marking non-class types, such as ints, as being NRVO variables.

2. We failed to  handle cases where the canonical types were the same, but the actual `QualType` objects were different. For example, if  one was represented by a typedef. (Example: https://godbolt.org/g/3UFgsL)

This patch fixes these bugs by marking the Gro variable as supporting NRVO only
when `BuildReturnStmt` marks the Gro variable as a coroutine candidate.






Reviewers: rsmith, GorNishanov, nicholas

Reviewed By: GorNishanov

Subscribers: majnemer, cfe-commits

Differential Revision: https://reviews.llvm.org/D42343

llvm-svn: 324037
2018-02-01 23:47:54 +00:00
Eric Fiselier 96f8c5c420 Revert "[coroutines] Fix application of NRVO to Coroutine "Gro" or return object."
This reverts commit r323712. It's causing some test failures on certain machines.
Not sure why, will investigate.

llvm-svn: 323717
2018-01-30 00:32:25 +00:00
Eric Fiselier a8fc370d51 [coroutines] Fix application of NRVO to Coroutine "Gro" or return object.
Summary:
Fix NRVO for Gro variable.

Previously, we only marked the GRO declaration as an NRVO variable
when its QualType and the function return's QualType matched exactly
(using operator==). However, this was incorrect for two reasons:

1. We were marking non-class types, such as ints, as being NRVO variables.

2. We failed to  handle cases where the canonical types were the same, but the actual `QualType` objects were different. For example, if  one was represented by a typedef. (Example: https://godbolt.org/g/3UFgsL)

This patch fixes these bugs by marking the Gro variable as supporting NRVO only
when `BuildReturnStmt` marks the Gro variable as a coroutine candidate.






Reviewers: rsmith, GorNishanov, nicholas

Reviewed By: GorNishanov

Subscribers: majnemer, cfe-commits

Differential Revision: https://reviews.llvm.org/D42343

llvm-svn: 323712
2018-01-29 23:52:57 +00:00
Gor Nishanov 6c4530c6b5 [coroutines] Add support for deallocation elision
Wrap deallocation code with:

  if (auto *mem = coro.free()) Deallocate

When backend decides to elide allocations it will replace coro.free with nullptr to suppress deallocation code.

llvm-svn: 303599
2017-05-23 04:21:27 +00:00
Gor Nishanov 68fe6ee768 [coroutines] Replace all coro.frame builtins with an SSA value of coro.begin
SemaCoroutine forms expressions referring to the coroutine frame of the enclosing coroutine using coro.frame builtin.
During codegen, we emit llvm.coro.begin intrinsic that returns the address of the coroutine frame.
When coro.frame is emitted, we replace it with SSA value of coro.begin.

llvm-svn: 303598
2017-05-23 03:46:59 +00:00
Gor Nishanov aa6e9a99b4 [coroutines] Add support for allocation elision
Summary:
We wrap allocation code so that backend can elide it if necessary.
llvm.coro.alloc intrinsic returns true, when allocation is needed and false otherwise.

```
  %NeedAlloc = call i1 @llvm.coro.alloc(token %2)
  br i1 %NeedAlloc, label %AllocBB, label %InitBB

AllocBB:
  %5 = call i64 @llvm.coro.size.i64()
  %call = call i8* @_Znwm(i64 %5) ; operator new
  br label %InitBB

InitBB:
  %Phi = phi i8* [ null, %0 ], [ %call, %4 ]
  call i8* @llvm.coro.begin(token %2, i8* %Phi)
```

Reviewers: majnemer, EricWF

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31584

llvm-svn: 303596
2017-05-23 01:13:17 +00:00
Gor Nishanov 6a470689eb [coroutines] Build GRO declaration and return GRO statement
Summary:
1. build declaration of the gro local variable that keeps the result of get_return_object.
2. build return statement returning the gro variable
3. emit them during CodeGen
4. sema and CodeGen tests updated

Reviewers: EricWF, rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31646

llvm-svn: 303573
2017-05-22 20:22:23 +00:00
Eric Fiselier f692e7db51 [coroutines] Fix building of new/delete expressions when get_return_object_on_allocation_failure() is present.
Summary:
This patch implements [dcl.fct.def.coroutine]p8:
> The unqualified-id get_return_object_on_allocation_failure is looked up in the scope of
> class P by class member access lookup (3.4.5). If a declaration is found, ..., and if a 
> global allocation function is selected, the ::operator new(size_t, nothrow_t) form shall be used.
> [...]
> The allocation function used in this case must have a non-throwing noexcept-specification.

Reviewers: GorNishanov, rsmith, majnemer, aaron.ballman

Reviewed By: GorNishanov

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31562

llvm-svn: 300524
2017-04-18 03:12:48 +00:00
Eric Fiselier a9b3d0975a Rename coroutine warning when unhandled_exception() is missing
llvm-svn: 300513
2017-04-17 23:28:02 +00:00
Eric Fiselier 47ee0f4d31 Revert r300504 - [coroutines] Fix rebuilding of implicit and dependent coroutine statements.
I have no idea what's happening here. The tests that fail on all of the bots
pass on my machine. Further investigation needed.

llvm-svn: 300511
2017-04-17 22:40:44 +00:00
Eric Fiselier fb289ecde0 [coroutines] Fix rebuilding of implicit and dependent coroutine statements.
Summary:
Certain implicitly generated coroutine statements, such as the calls to 'return_value()' or `return_void()` or `get_return_object_on_allocation_failure()`, cannot be built until the promise type is no longer dependent. This means they are not built until after the coroutine body statement has been transformed.

This patch fixes an issue where these statements would never be built for coroutine templates.

It also fixes a small issue where diagnostics about `get_return_object_on_allocation_failure()` were incorrectly suppressed. 

Reviewers: rsmith, majnemer, GorNishanov, aaron.ballman

Reviewed By: GorNishanov

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31487

llvm-svn: 300504
2017-04-17 22:06:13 +00:00
Eric Fiselier 1bcc937b56 Revert r300420 - [coroutines] Fix building of new/delete expressions when get_return_object_on_allocation_failure() is present
llvm-svn: 300421
2017-04-16 09:34:28 +00:00
Eric Fiselier 627a63cf50 [coroutines] Fix building of new/delete expressions when get_return_object_on_allocation_failure() is present.
Summary:
This patch implements [dcl.fct.def.coroutine]p8:
> The unqualified-id get_return_object_on_allocation_failure is looked up in the scope of
> class P by class member access lookup (3.4.5). If a declaration is found, ..., and if a 
> global allocation function is selected, the ::operator new(size_t, nothrow_t) form shall be used.
> [...]
> The allocation function used in this case must have a non-throwing noexcept-specification.

Reviewers: GorNishanov, rsmith, majnemer, aaron.ballman

Reviewed By: GorNishanov

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D31562

llvm-svn: 300420
2017-04-16 09:19:59 +00:00
Gor Nishanov 3aa9eb38a0 [coroutines] Handle get_return_object_on_allocation_failure
Summary:
If promise_type has get_return_object_on_allocation_failure defined,
check if an allocation function returns nullptr, and if so,
return the result of get_return_object_on_allocation_failure().

Reviewers: rsmith, EricWF

Reviewed By: EricWF

Subscribers: mehdi_amini, cfe-commits

Differential Revision: https://reviews.llvm.org/D31399

llvm-svn: 298891
2017-03-27 23:36:59 +00:00
Gor Nishanov 6dcb0eb301 [coroutines] Build and pass coroutine_handle to await_suspend
Summary:
This patch adds passing a coroutine_handle object to await_suspend calls.
It builds the coroutine_handle using coroutine_handle<PromiseType>::from_address(__builtin_coro_frame()).

(a revision of https://reviews.llvm.org/D26316 that for some reason refuses to apply via arc patch)

Reviewers: GorNishanov

Subscribers: mehdi_amini, cfe-commits, EricWF

Differential Revision: https://reviews.llvm.org/D30769

llvm-svn: 297356
2017-03-09 03:09:43 +00:00
Gor Nishanov 90be1213d2 [coroutines] Add co_return statement emission
Summary:
Added co_return statement emission.

Tweaked coro-alloc.cpp test to use co_return to trigger coroutine processing instead of co_await, since this change starts emitting the body of the coroutine and await expression handling has not been upstreamed yet.

Reviewers: rsmith, majnemer, EricWF, aaron.ballman

Reviewed By: rsmith

Subscribers: majnemer, llvm-commits, mehdi_amini

Differential Revision: https://reviews.llvm.org/D29979

llvm-svn: 297076
2017-03-06 21:12:54 +00:00
Gor Nishanov 8df64e940d [coroutines] Add allocation and deallocation substatements.
Summary:
SemaCoroutine: Add allocation / deallocation substatements.
CGCoroutine/Test: Emit allocation and deallocation + test.

Reviewers: rsmith

Subscribers: ABataev, EricWF, llvm-commits, mehdi_amini

Differential Revision: https://reviews.llvm.org/D25879

llvm-svn: 285306
2016-10-27 16:28:31 +00:00