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.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Transforms/Coroutines/CoroFrame.cpp | ||
---|---|---|
1588 | Surely just doing AI->getAlignment() - 1 is simpler. Can we trust AI->getAlignment() to be the same value as the alignment we used when computing the frame layout? |
llvm/lib/Transforms/Coroutines/CoroFrame.cpp | ||
---|---|---|
1588 |
LLVM's constant folder saved my bacon there, but yes. I will fix.
Yes. For Allocas we pass AI->getAlign() to addField as the FieldAlignment which is then used to compute the layout. FieldAlignment is only set in the addField function if it has not been set (it is a MaybeAlign optional). Fields.push_back({FieldSize, Offset, Ty, 0, *FieldAlignment, TyAlignment, DynamicAlignBuffer}); |
This is rather memory-inefficient, and it's quite a shame that the ABI was defined such as not to pass-down a "context_alignment" field next to "context_size" in the async_function_pointer struct, so that the allocator can DTRT. Oh well...
Increasing the size of async function pointers and complicating the allocation logic are not free. The max alignment used by the ABI is 16 bytes, and the Swift frontend does not normally request alignments larger than that, and I wouldn't expect the places that *do* request it to typically need to persist values across an async suspension (vectorization, for example, generally loses a lot of its punch if you've got calls in the middle of your vectorized kernel), so we're talking about pretty rarified circumstances here; I think the trade-off made by the ABI is appropriate.
I would guess that whatever code pattern triggered this bug does not in fact need the value to persist a value across the suspension, and someone we're just failing to put it on the stack.
Add asserts that the dynamic alignment frame information when constructing the
frame matches the alloca.
llvm/lib/Transforms/Coroutines/CoroFrame.cpp | ||
---|---|---|
1797 | These three sites all need to be A.NeedsDynamicAlignment in case the original alloca is over-aligned, right? Should we just make GetFramePointer take a const Field & so that this falls out? |
llvm/lib/Transforms/Coroutines/CoroFrame.cpp | ||
---|---|---|
1797 | I relied on the fact that for async ABI we won't get here. (line 1751) I will rewrite it as you said so that this is not a ticking time bomb (though the asserts I added would catch that) |
Surely just doing AI->getAlignment() - 1 is simpler.
Can we trust AI->getAlignment() to be the same value as the alignment we used when computing the frame layout?