Skip to content

Commit c27b64b

Browse files
committed
[Coro][NewPM] Handle llvm.coro.prepare.retcon in NPM coro-split pass
Reviewed By: rjmccall Differential Revision: https://reviews.llvm.org/D87731
1 parent b5c3efe commit c27b64b

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

llvm/lib/Transforms/Coroutines/CoroSplit.cpp

+52-5
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,42 @@ static void createDevirtTriggerFunc(CallGraph &CG, CallGraphSCC &SCC) {
15631563
SCC.initialize(Nodes);
15641564
}
15651565

1566+
/// Replace a call to llvm.coro.prepare.retcon.
1567+
static void replacePrepare(CallInst *Prepare, LazyCallGraph &CG,
1568+
LazyCallGraph::SCC &C) {
1569+
auto CastFn = Prepare->getArgOperand(0); // as an i8*
1570+
auto Fn = CastFn->stripPointerCasts(); // as its original type
1571+
1572+
// Attempt to peephole this pattern:
1573+
// %0 = bitcast [[TYPE]] @some_function to i8*
1574+
// %1 = call @llvm.coro.prepare.retcon(i8* %0)
1575+
// %2 = bitcast %1 to [[TYPE]]
1576+
// ==>
1577+
// %2 = @some_function
1578+
for (auto UI = Prepare->use_begin(), UE = Prepare->use_end(); UI != UE;) {
1579+
// Look for bitcasts back to the original function type.
1580+
auto *Cast = dyn_cast<BitCastInst>((UI++)->getUser());
1581+
if (!Cast || Cast->getType() != Fn->getType())
1582+
continue;
1583+
1584+
// Replace and remove the cast.
1585+
Cast->replaceAllUsesWith(Fn);
1586+
Cast->eraseFromParent();
1587+
}
1588+
1589+
// Replace any remaining uses with the function as an i8*.
1590+
// This can never directly be a callee, so we don't need to update CG.
1591+
Prepare->replaceAllUsesWith(CastFn);
1592+
Prepare->eraseFromParent();
1593+
1594+
// Kill dead bitcasts.
1595+
while (auto *Cast = dyn_cast<BitCastInst>(CastFn)) {
1596+
if (!Cast->use_empty())
1597+
break;
1598+
CastFn = Cast->getOperand(0);
1599+
Cast->eraseFromParent();
1600+
}
1601+
}
15661602
/// Replace a call to llvm.coro.prepare.retcon.
15671603
static void replacePrepare(CallInst *Prepare, CallGraph &CG) {
15681604
auto CastFn = Prepare->getArgOperand(0); // as an i8*
@@ -1618,6 +1654,19 @@ static void replacePrepare(CallInst *Prepare, CallGraph &CG) {
16181654
}
16191655
}
16201656

1657+
static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG,
1658+
LazyCallGraph::SCC &C) {
1659+
bool Changed = false;
1660+
for (auto PI = PrepareFn->use_begin(), PE = PrepareFn->use_end(); PI != PE;) {
1661+
// Intrinsics can only be used in calls.
1662+
auto *Prepare = cast<CallInst>((PI++)->getUser());
1663+
replacePrepare(Prepare, CG, C);
1664+
Changed = true;
1665+
}
1666+
1667+
return Changed;
1668+
}
1669+
16211670
/// Remove calls to llvm.coro.prepare.retcon, a barrier meant to prevent
16221671
/// IPO from operating on calls to a retcon coroutine before it's been
16231672
/// split. This is only safe to do after we've split all retcon
@@ -1656,7 +1705,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
16561705
return PreservedAnalyses::all();
16571706

16581707
// Check for uses of llvm.coro.prepare.retcon.
1659-
const auto *PrepareFn = M.getFunction("llvm.coro.prepare.retcon");
1708+
auto *PrepareFn = M.getFunction("llvm.coro.prepare.retcon");
16601709
if (PrepareFn && PrepareFn->use_empty())
16611710
PrepareFn = nullptr;
16621711

@@ -1670,8 +1719,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
16701719
return PreservedAnalyses::all();
16711720

16721721
if (Coroutines.empty())
1673-
llvm_unreachable("new pass manager cannot yet handle "
1674-
"'llvm.coro.prepare.retcon'");
1722+
replaceAllPrepares(PrepareFn, CG, C);
16751723

16761724
// Split all the coroutines.
16771725
for (LazyCallGraph::Node *N : Coroutines) {
@@ -1704,8 +1752,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
17041752
}
17051753

17061754
if (PrepareFn)
1707-
llvm_unreachable("new pass manager cannot yet handle "
1708-
"'llvm.coro.prepare.retcon'");
1755+
replaceAllPrepares(PrepareFn, CG, C);
17091756

17101757
return PreservedAnalyses::none();
17111758
}

llvm/test/Transforms/Coroutines/coro-retcon-frame.ll

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: opt < %s -coro-split -S | FileCheck %s
2+
; RUN: opt < %s -passes=coro-split -S | FileCheck %s
23

34
target datalayout = "p:64:64:64"
45

0 commit comments

Comments
 (0)