[PATCH] D23245: [Coroutines] Part 6: Elide dynamic allocation of a coroutine frame when possible
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 8 20:10:56 PDT 2016
majnemer added inline comments.
================
Comment at: lib/Transforms/Coroutines/CoroElide.cpp:90-94
@@ +89,7 @@
+// See if any operand of the call instruction references the coroutine frame.
+static bool operandReferences(CallInst *CI, AllocaInst *Frame, AAResults &AA) {
+ for (Value *Op : CI->operand_values())
+ if (AA.alias(Op, Frame) != NoAlias)
+ return true;
+ return false;
+}
----------------
This doesn't seem conservative enough because you are only check if the call's operands alias the alloca. I could imagine the call referencing the coroutine frame via other means (load/store via global).
I think `getModRefInfo() != MRI_NoModRef` would capture this better.
================
Comment at: lib/Transforms/Coroutines/CoroElide.cpp:103-105
@@ +102,5 @@
+ for (Instruction &I : instructions(F))
+ if (auto *Call = dyn_cast<CallInst>(&I))
+ if (Call->isTailCall() && operandReferences(Call, Frame, AA))
+ Call->setTailCall(false);
+}
----------------
Should we `report_fatal_error` if the `CallSite` is `must_tail`?
================
Comment at: lib/Transforms/Coroutines/CoroElide.cpp:110
@@ +109,3 @@
+static Type *getFrameType(Function *Resume) {
+ auto ArgType = Resume->getArgumentList().front().getType();
+ return cast<PointerType>(ArgType)->getElementType();
----------------
`auto *`
================
Comment at: lib/Transforms/Coroutines/CoroElide.cpp:129
@@ +128,3 @@
+
+ auto *Frame = new AllocaInst(FrameTy, "", InsertPt);
+ auto *FrameVoidPtr =
----------------
Do we have to worry about the alignment of this alloca?
================
Comment at: lib/Transforms/Coroutines/CoroElide.cpp:194-195
@@ +193,4 @@
+
+ // If llvm.coro.begin refers to llvm.coro.alloc, we can elide the allocation.
+ auto *AllocInst = CoroBegin->getAlloc();
+
----------------
majnemer wrote:
> We would typically sink this assignment into the if.
Is this still safe if there are multiple coro.begin calls and some of them refer to llvm.coro.alloc and others do not?
================
Comment at: lib/Transforms/Coroutines/CoroElide.cpp:194-203
@@ +193,12 @@
+
+ // If llvm.coro.begin refers to llvm.coro.alloc, we can elide the allocation.
+ auto *AllocInst = CoroBegin->getAlloc();
+
+ // FIXME: Do more sophisticated check for when we can do heap elision.
+ // Something like: for every exit from the function where coro.begin is live,
+ // there is a coro.free or coro.destroy that dominates that exit block.
+ // At the moment we simply assume that if we found at least one coro.destroy
+ // referencing the coro.begin, we can elide the heap allocation.
+
+ if (AllocInst) {
+ auto FrameTy = getFrameType(cast<Function>(ResumeAddrConstant));
----------------
We would typically sink this assignment into the if.
================
Comment at: lib/Transforms/Coroutines/CoroElide.cpp:204
@@ +203,3 @@
+ if (AllocInst) {
+ auto FrameTy = getFrameType(cast<Function>(ResumeAddrConstant));
+ elideHeapAllocations(CoroBegin, FrameTy, AllocInst, AA);
----------------
`auto *`
https://reviews.llvm.org/D23245
More information about the llvm-commits
mailing list