@@ -1563,6 +1563,42 @@ static void createDevirtTriggerFunc(CallGraph &CG, CallGraphSCC &SCC) {
1563
1563
SCC.initialize (Nodes);
1564
1564
}
1565
1565
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
+ }
1566
1602
// / Replace a call to llvm.coro.prepare.retcon.
1567
1603
static void replacePrepare (CallInst *Prepare, CallGraph &CG) {
1568
1604
auto CastFn = Prepare->getArgOperand (0 ); // as an i8*
@@ -1618,6 +1654,19 @@ static void replacePrepare(CallInst *Prepare, CallGraph &CG) {
1618
1654
}
1619
1655
}
1620
1656
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
+
1621
1670
// / Remove calls to llvm.coro.prepare.retcon, a barrier meant to prevent
1622
1671
// / IPO from operating on calls to a retcon coroutine before it's been
1623
1672
// / split. This is only safe to do after we've split all retcon
@@ -1656,7 +1705,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
1656
1705
return PreservedAnalyses::all ();
1657
1706
1658
1707
// 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" );
1660
1709
if (PrepareFn && PrepareFn->use_empty ())
1661
1710
PrepareFn = nullptr ;
1662
1711
@@ -1670,8 +1719,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
1670
1719
return PreservedAnalyses::all ();
1671
1720
1672
1721
if (Coroutines.empty ())
1673
- llvm_unreachable (" new pass manager cannot yet handle "
1674
- " 'llvm.coro.prepare.retcon'" );
1722
+ replaceAllPrepares (PrepareFn, CG, C);
1675
1723
1676
1724
// Split all the coroutines.
1677
1725
for (LazyCallGraph::Node *N : Coroutines) {
@@ -1704,8 +1752,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
1704
1752
}
1705
1753
1706
1754
if (PrepareFn)
1707
- llvm_unreachable (" new pass manager cannot yet handle "
1708
- " 'llvm.coro.prepare.retcon'" );
1755
+ replaceAllPrepares (PrepareFn, CG, C);
1709
1756
1710
1757
return PreservedAnalyses::none ();
1711
1758
}
0 commit comments