Commit Graph

347 Commits

Author SHA1 Message Date
Chuanqi Xu 66e15d4c01 [NFC] [Coroutines] Update the comments for lowering coro.save
The original comment is not right. We don't store 0 all the time.
2022-07-07 14:57:41 +08:00
Chuanqi Xu e3b4452e07 [Debug] [Coroutines] Get rid of DW_ATE_address
Closing https://github.com/llvm/llvm-project/issues/55916

This patch tries to get rid of DW_ATE_address and enhance the test
coverage.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D127625
2022-07-07 10:47:09 +08:00
Chuanqi Xu 7137ebc4ce [Debug] [Coroutine] Adjust the scope and name for coroutine frame
Previously the scope of debug type of __coro_frame is limited in the
current function. It looked good at the first sight. But it prevent us
to print the type in splitted functions and other functions. Also the
debug type is different for different coroutine functions. So it makes
sense to rename the debug type to make it related to the function name.

After this patch, we could access the coroutine frame type in a function
by `function_name.coro_frame_ty`.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D127623
2022-07-07 10:35:32 +08:00
Chuanqi Xu 0b5ead6590 [WebAssembly] Don't set musttail for coroutines when tail-call is not
enabled

The C++20 Coroutines couldn't be compiled to WebAssembly due to an
optimization named symmetric transfer requires the support for musttail
calls but WebAssembly doesn't support it yet.

This patch tries to fix the problem by adding a supportsTailCalls
method to TargetTransformImpl to skip the symmetric transfer when
tail-call feature is not supported.

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D128794
2022-06-30 11:15:40 +08:00
Nikita Popov 5548e807b5 [IR] Remove support for extractvalue constant expression
This removes the extractvalue constant expression, as part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
extractvalue is already not supported in bitcode, so we do not need
to worry about bitcode auto-upgrade.

Uses of ConstantExpr::getExtractValue() should be replaced with
IRBuilder::CreateExtractValue() (if the fact that the result is
constant is not important) or ConstantFoldExtractValueInstruction()
(if it is). Though for this particular case, it is also possible
and usually preferable to use getAggregateElement() instead.

The C API function LLVMConstExtractValue() is removed, as the
underlying constant expression no longer exists. Instead,
LLVMBuildExtractValue() should be used (which will constant fold
or create an instruction). Depending on the use-case,
LLVMGetAggregateElement() may also be used instead.

Differential Revision: https://reviews.llvm.org/D125795
2022-06-28 10:40:17 +02:00
Yuanfang Chen e2e9e708e5 [Coroutine] Remove the '!func_sanitize' metadata for split functions
There is no proper RTTI for these split functions. So just delete the
metadata.

Fixes https://github.com/llvm/llvm-project/issues/49689.

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D116130
2022-06-27 12:09:13 -07:00
Chuanqi Xu 24e53b01d5 Revert "[Coroutines] Only do symmetric transfer if optimization is on"
This reverts commit 7782e080e8. According
to the discussion of WG21, symmetric transfer is a desired feature.
2022-06-27 10:54:56 +08:00
Kazu Hirata 7a47ee51a1 [llvm] Don't use Optional::getValue (NFC) 2022-06-20 22:45:45 -07:00
Kazu Hirata e0e687a615 [llvm] Don't use Optional::hasValue (NFC) 2022-06-20 10:38:12 -07:00
Guillaume Chatelet 7296811910 [NFC] Simplify alignment code in CoroFrame 2022-06-20 15:15:52 +00:00
Chuanqi Xu 7782e080e8 [Coroutines] Only do symmetric transfer if optimization is on
Symmetric transfer is not a part of C++ standards. So the vendors is not
forced to implement it any way. Given the symmetric transfer nowadays is
an optimization. It makes more sense to enable it only if the
optimization is enabled. It is also helpful for the compilation speed in
O0.
2022-06-20 16:20:36 +08:00
Guillaume Chatelet 77bba68de6 [NFC][Alignment] Use Align in CoroFrame 2022-06-14 10:56:36 +00:00
Chuanqi Xu 735e6c40b5 [Coroutines] Convert coroutine.presplit to enum attr
This is required by @nikic in https://reviews.llvm.org/D127383 to
decrease the cost to check whether a function is a coroutine and this
fixes a FIXME too.

Reviewed By: rjmccall, ezhulenev

Differential Revision: https://reviews.llvm.org/D127471
2022-06-14 14:23:46 +08:00
Chuanqi Xu 733d7cf964 [Debug] [Coroutines] Add deref operator for non complex expression
Background:

When we construct coroutine frame, we would insert a dbg.declare
intrinsic for it:
```
%hdl = call void @llvm.coro.begin() ; would return coroutine handle
call void @llvm.dbg.declare(metadata ptr %hdl, metadata
![[DEBUG_VARIABLE: __coro_frame]], metadata !DIExpression())
```

And in the splitted coroutine, it looks like:
```
define void @coro_func.resume(ptr *hdl) {
entry.resume:
    call void @llvm.dbg.declare(metadata ptr %hdl, metadata
![[DEBUG_VARIABLE: __coro_frame]], metadata !DIExpression())
}
```

And we would salvage the debug info by inserting a new alloca here:
```
define void @coro_func.resume(ptr %hdl) {
entry.resume:
    %frame.debug = alloca ptr
    call void @llvm.dbg.declare(metadata ptr %frame.debug, metadata
![[DEBUG_VARIABLE: __coro_frame]], metadata !DIExpression())
    store ptr %hdl, %frame.debug
}
```

But now, the problem comes since the `dbg.declare` refers to the address
of that alloca instead of actual coroutine handle. I saw there are codes
to solve the problem but it only applies to complex expression only. I
feel if it is OK to relax the condition to make it work for
`__coro_frame`.

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D126277
2022-06-08 10:53:51 +08:00
Kazu Hirata 3b9707dbc0 [llvm] Convert for_each to range-based for loops (NFC) 2022-06-05 12:07:14 -07:00
Arnold Schwaighofer 5c902af572 [coro async] Add code to support dynamic aligment of over-aligned types in async frames
Async context frames are allocated with a maximum alignment. If a type
requests an alignment bigger than that dynamically align the address
in the frame.

Differential Revision: https://reviews.llvm.org/D126715
2022-06-03 07:06:14 -07:00
serge-sans-paille fb67d683db [iwyu] Handle regressions in libLLVM header include
Running iwyu-diff on LLVM codebase since 7030654296 detected a few
regressions, fixing them.

Differential Revision: https://reviews.llvm.org/D126417
2022-05-26 08:12:34 +02:00
Chuanqi Xu 02d6845234 [NFC] [Coroutines] Remove EnableReuseStorageInFrame option
The EnableReuseStorageInFrame option is designed for testing only.
But it is better to use *_PASS_WITH_PARAMS macro to keep consistent with
other passes.
2022-05-10 17:28:43 +08:00
Chuanqi Xu beeed0994e [Coroutines] Use PassManager instead of Legacy PassManager internally
This is a following cleanup for the previous work D123918. I missed
serveral places which still use legacy pass managers. This patch tries
to remove them.
2022-05-10 13:15:11 +08:00
Chuanqi Xu 2d037873a3 [Coroutines] Don't re-materialize for debug instructions
Re-materialize for debug instructions would cause a different code
generated if we enabled `-g`. This is bad. So we disable to
re-materialize for debug instructions.
2022-05-06 13:52:19 +08:00
Chuanqi Xu 405bf90235 [NFC] [Pipelines] Hoist CoroCleanup as Module Pass
This is similar to previous patch https://reviews.llvm.org/D123925. It
could also reduce the time we call declaresCoroCleanupIntrinsics. And it
is helpful for further changes.

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D124362
2022-05-05 15:15:09 +08:00
serge-sans-paille 7030654296 [iwyu] Handle regressions in libLLVM header include
Running iwyu-diff on LLVM codebase since fa5a4e1b95 detected a few
regressions, fixing them.

Differential Revision: https://reviews.llvm.org/D124847
2022-05-04 08:32:38 +02:00
Nathan Lanza 950c95cfdd [coroutines] Get an IntegerType from the value instead of defaulting to 64 bit
This AliasPtr is being created always from an Int64 even for targets
where 32 bit is the proper type. e.g. “thumbv7-none-linux-android16”.
This causes the assert in the `get` func to fail as we're getting a 32
bit from the APInt.

Fix this by simply always just getting the type from the value instead.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D123272
2022-04-25 11:10:46 -07:00
Chuanqi Xu 7eaa84eac3 [NFC] Code cleanups for coroutine after we remvoed legacy passes 2022-04-21 15:32:46 +08:00
Chuanqi Xu 483efc9ad0 [Pipelines] Remove Legacy Passes in Coroutines
The legacy passes are deprecated now and would be removed in near
future. This patch tries to remove legacy passes in coroutines.

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D123918
2022-04-21 10:59:11 +08:00
Chuanqi Xu 5b6742a6bd [NFC] Return correct PreservedAnalysis for CoroEarly
This is a fix for previous typo. It makes no sense to return
PreservedAnalyses::all() if anything is change. This change simplify
codes further.
2022-04-20 16:47:10 +08:00
Chuanqi Xu f9bee35689 [Pipelines] Hoist CoroEarly as a module pass
This change could reduce the time we call `declaresCoroEarlyIntrinsics`.
And it is helpful for future changes.

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D123925
2022-04-19 11:04:24 +08:00
Nikita Popov 792f80e166 [CoroSplit] Use freeze instead of bitcast for dummy instructions
Not all types that can appear in arguments can be bitcasts -- in
particular, bitcasts do not support struct types.
2022-04-01 13:07:25 +02:00
Nikita Popov 68d27587e4 [CoroSplit] Handle argument being the frame pointer (PR54523)
If the frame pointer is an argument of the original pointer (which
happens with opaque pointers), then we currently first replace the
argument with undef, which will prevent later replacement of the
old frame pointer with the new one.

Fix this by replacing arguments with some dummy instructions first,
and then replacing those with undef later. This gives us a chance
to replace the frame pointer before it becomes undef.

Fixes https://github.com/llvm/llvm-project/issues/54523.

Differential Revision: https://reviews.llvm.org/D122375
2022-04-01 12:37:29 +02:00
Arthur Eubanks 9bd66b312c [PassManager][Coroutine] Run passes under -O0 conditionally and run GlobalDCE
CoroSplit lowers various coroutine intrinsics. It's a CGSCC pass and
CGSCC passes don't run on unreachable functions. Normally GlobalDCE will
come along and delete unreachable functions, but we don't run GlobalDCE
under -O0, so an unreachable function with coroutine intrinsics may
never have CoroSplit run on it.

This patch adds GlobalDCE when coroutines intrinsics are present. It
also now runs all coroutine passes conditional when coroutine intrinsics
are present. This should also solve the -O0 regression reported in
D105877 due to LazyCallGraph construction.

Fixes https://github.com/llvm/llvm-project/issues/54117

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D122275
2022-03-23 11:03:26 -07:00
Chuanqi Xu 902f4708fe [NFC] [Coroutines] Remove unnecessary check and constraints on SmallVector
The CoroSplit pass would check the existence of coroutine intrinsic
before starting work. It is not necessary and wasteful since it would
iterate over the Module.

This patch also removes the constraint on the corresponding of the
SmallVector for the possible coroutines in the Modules. The original
value is 4. Given coroutines is used actually in practice. 4 is really
relatively a low threshold.
2022-03-22 14:24:46 +08:00
Fraser Cormack fe74183564 [Coroutines][NFC] Format line to 80 cols 2022-03-17 15:34:24 +00:00
Nikita Popov ce6ca00a92 [CoroSplit] Avoid self-replacement
With opaque pointers, the bitcast might be a no-op, and this can
end up trying to replace a value with itself, which is illegal.
2022-03-14 13:53:31 +01:00
Nikita Popov 479d684ba5 [Coroutines] Support opaque pointers in solveTypeName()
As far as I can tell, these names are only intended to be
informative, so just use a generic "PointerType" for opaque pointers.

The code in solveDIType() also treats pointers as basic types (and
does not try to encode the pointed-to type further), so I believe
this should be fine.

Differential Revision: https://reviews.llvm.org/D121280
2022-03-10 09:33:55 +01:00
Michael Gottesman 0b647fc529 [debug-info] Debug salvage llvm.dbg.addr in original function that point into the coroutine frame when splitting coros.
We are already doing this in the split functions while we clone. This just
handles the original function.

I also updated the coroutine split test to validate that we are always referring
to the msg in the context object instead of in a shadow copy.

rdar://83957028

Reviewed By: aprantl

Differential Revision: https://reviews.llvm.org/D121324
2022-03-09 14:02:09 -08:00
Nikita Popov e81f566de6 [Coroutines] Avoid pointer element access for resume function type
For switch ABI, the function type is always "void (%frame*)", so
just hardcode that rather than fetching it from a pointer element
type.
2022-03-09 14:47:17 +01:00
Nikita Popov 3d9386a349 [CoroFrame] Avoid pointer element type access for swifterror
These must have pointer-to-pointer type, and with opaque pointers
we don't care about the specific pointer type anymore.
2022-03-09 11:15:10 +01:00
Nikita Popov 1bd33691cb [CoroElide] Remove fallback for frame layout determination
Only determine the frame layout based on dereferenceable and align
attributes, and remove the type-based fallback, which is incompatible
with opaque pointers. The dereferenceable attribute is required,
while the align attribute uses default alignment of 1 (commonly,
align 1 attributes do not get placed, relying on default alignment).

The CoroSplit pass producing the resume function adds the necessary
attributes in 7daed35911/llvm/lib/Transforms/Coroutines/CoroSplit.cpp (L840),
and their presence is checked in coro-debug.ll at least.

Differential Revision: https://reviews.llvm.org/D120988
2022-03-07 11:23:02 +01:00
Nikita Popov 9bca4ea364 [Coroutines] Allow FramePtr to be an Argument
With opaque pointers, after splitRetconCoroutine() the FramePtr
may be an Argument rather than an Instruction. With typed pointers,
this currently doesn't happen because the FramePtr would be a
bitcast instruction.

Fix this by making FramePtr a Value and adding a helper for the
"after FramePtr" insertion point, which would be the start of the
function in the Argument case.

Differential Revision: https://reviews.llvm.org/D120994
2022-03-07 10:58:56 +01:00
Nikita Popov 6467d1d275 [CoroFrame] Remove unused insertSpills() return value (NFC) 2022-03-04 15:11:24 +01:00
serge-sans-paille 71c3a5519d Cleanup includes: LLVMAnalysis
Number of lines output by preprocessor:
before: 1065940348
after:  1065307662

Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup
Differential Revision: https://reviews.llvm.org/D120659
2022-03-01 18:01:54 +01:00
Michael Gottesman 19279ffc77 [debug-info] If one sees a spill with a dbg.addr use, salvageDebugInfo upon it and don't hoist it.
This ensures that if we have a dbg.addr in a coroutine funclet that is on one of
our function arguments, that the dbg.addr is not mapped to undef and also that
later it isn't hoisted to the front of the basic block. Instead it remains at
its original cloned location.

rdar://83957028

Differential Revision: https://reviews.llvm.org/D119576
2022-02-11 15:15:13 -08:00
Arthur Eubanks 22f4f94256 [CoroFrame][OpaquePtr] Remove getPointerElementType() call
Get it from the byval type instead.
2022-02-11 09:53:20 -08:00
serge-sans-paille ffe8720aa0 Reduce dependencies on llvm/BinaryFormat/Dwarf.h
This header is very large (3M Lines once expended) and was included in location
where dwarf-specific information were not needed.

More specifically, this commit suppresses the dependencies on
llvm/BinaryFormat/Dwarf.h in two headers: llvm/IR/IRBuilder.h and
llvm/IR/DebugInfoMetadata.h. As these headers (esp. the former) are widely used,
this has a decent impact on number of preprocessed lines generated during
compilation of LLVM, as showcased below.

This is achieved by moving some definitions back to the .cpp file, no
performance impact implied[0].

As a consequence of that patch, downstream user may need to manually some extra
files:

llvm/IR/IRBuilder.h no longer includes llvm/BinaryFormat/Dwarf.h
llvm/IR/DebugInfoMetadata.h no longer includes llvm/BinaryFormat/Dwarf.h

In some situations, codes maybe relying on the fact that
llvm/BinaryFormat/Dwarf.h was including llvm/ADT/Triple.h, this hidden
dependency now needs to be explicit.

$ clang++ -E  -Iinclude -I../llvm/include ../llvm/lib/Transforms/Scalar/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l
after:   10978519
before:  11245451

Related Discourse thread: https://llvm.discourse.group/t/include-what-you-use-include-cleanup
[0] https://llvm-compile-time-tracker.com/compare.php?from=fa7145dfbf94cb93b1c3e610582c495cb806569b&to=995d3e326ee1d9489145e20762c65465a9caeab4&stat=instructions

Differential Revision: https://reviews.llvm.org/D118781
2022-02-04 11:44:03 +01:00
serge-sans-paille e188aae406 Cleanup header dependencies in LLVMCore
Based on the output of include-what-you-use.

This is a big chunk of changes. It is very likely to break downstream code
unless they took a lot of care in avoiding hidden ehader dependencies, something
the LLVM codebase doesn't do that well :-/

I've tried to summarize the biggest change below:

- llvm/include/llvm-c/Core.h: no longer includes llvm-c/ErrorHandling.h
- llvm/IR/DIBuilder.h no longer includes llvm/IR/DebugInfo.h
- llvm/IR/IRBuilder.h no longer includes llvm/IR/IntrinsicInst.h
- llvm/IR/LLVMRemarkStreamer.h no longer includes llvm/Support/ToolOutputFile.h
- llvm/IR/LegacyPassManager.h no longer include llvm/Pass.h
- llvm/IR/Type.h no longer includes llvm/ADT/SmallPtrSet.h
- llvm/IR/PassManager.h no longer includes llvm/Pass.h nor llvm/Support/Debug.h

And the usual count of preprocessed lines:
$ clang++ -E  -Iinclude -I../llvm/include ../llvm/lib/IR/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l
before: 6400831
after:  6189948

200k lines less to process is no that bad ;-)

Discourse thread on the topic: https://llvm.discourse.group/t/include-what-you-use-include-cleanup

Differential Revision: https://reviews.llvm.org/D118652
2022-02-02 06:54:20 +01:00
Nikita Popov aa97bc116d [NFC] Remove uses of PointerType::getElementType()
Instead use either Type::getPointerElementType() or
Type::getNonOpaquePointerElementType().

This is part of D117885, in preparation for deprecating the API.
2022-01-25 09:44:52 +01:00
Nikita Popov d29e319263 [OpaquePtrs] Add getNonOpaquePointerElementType() method (NFC)
This method is intended for use in places that cannot be reached
with opaque pointers, or part of deprecated methods. This makes
it easier to see that some uses of getPointerElementType() don't
need further action.

Differential Revision: https://reviews.llvm.org/D117870
2022-01-24 10:03:49 +01:00
Nikita Popov bfbdb5e43e [Coroutines] Avoid some pointer element type accesses
These are just verifying that pointer types are correct, which is
no longer relevant under opaque pointers.
2022-01-21 12:36:19 +01:00
Nikita Popov 9c5b856dac [CoroSplit] Avoid pointer element type accesses
Use isOpaqueOrPointeeTypeMatches() for the assertions instead.
2022-01-21 12:22:09 +01:00
Chuanqi Xu c8ecf12bc3 [Coroutines] Offering llvm.coro.align intrinsic
It is a known problem that we can't align the switch-based coroutine
frame if the alignment exceeds std::max_align_t (which is 16 usually).

We could solve the problem on the middle-end by dynamically transforming
or in the frontend by emitting aligned allocation function.

If we need to solve it in the frontend, the middle end need to offer an
intrinsic to tell the alignment at least. This patch tries to offer such
an intrinsic called llvm.coro.align.

Reviewed By: https://reviews.llvm.org/D117542

Differential revision: https://reviews.llvm.org/D117542
2022-01-19 09:52:45 +08:00