19
19
#include " llvm/ADT/PostOrderIterator.h"
20
20
#include " llvm/ADT/ScopeExit.h"
21
21
#include " llvm/ADT/SmallString.h"
22
- #include " llvm/Analysis/CFG.h"
23
22
#include " llvm/Analysis/PtrUseVisitor.h"
24
23
#include " llvm/Analysis/StackLifetime.h"
25
24
#include " llvm/Config/llvm-config.h"
@@ -1441,22 +1440,17 @@ namespace {
1441
1440
struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> {
1442
1441
using Base = PtrUseVisitor<AllocaUseVisitor>;
1443
1442
AllocaUseVisitor (const DataLayout &DL, const DominatorTree &DT,
1444
- const coro::Shape &CoroShape,
1445
- const SuspendCrossingInfo &Checker,
1443
+ const CoroBeginInst &CB, const SuspendCrossingInfo &Checker,
1446
1444
bool ShouldUseLifetimeStartInfo)
1447
- : PtrUseVisitor(DL), DT(DT), CoroShape(CoroShape), Checker(Checker),
1448
- ShouldUseLifetimeStartInfo (ShouldUseLifetimeStartInfo) {
1449
- for (AnyCoroSuspendInst *SuspendInst : CoroShape.CoroSuspends )
1450
- CoroSuspendBBs.insert (SuspendInst->getParent ());
1451
- }
1445
+ : PtrUseVisitor(DL), DT(DT), CoroBegin(CB), Checker(Checker),
1446
+ ShouldUseLifetimeStartInfo (ShouldUseLifetimeStartInfo) {}
1452
1447
1453
1448
void visit (Instruction &I) {
1454
1449
Users.insert (&I);
1455
1450
Base::visit (I);
1456
1451
// If the pointer is escaped prior to CoroBegin, we have to assume it would
1457
1452
// be written into before CoroBegin as well.
1458
- if (PI.isEscaped () &&
1459
- !DT.dominates (CoroShape.CoroBegin , PI.getEscapingInst ())) {
1453
+ if (PI.isEscaped () && !DT.dominates (&CoroBegin, PI.getEscapingInst ())) {
1460
1454
MayWriteBeforeCoroBegin = true ;
1461
1455
}
1462
1456
}
@@ -1559,19 +1553,10 @@ struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> {
1559
1553
// When we found the lifetime markers refers to a
1560
1554
// subrange of the original alloca, ignore the lifetime
1561
1555
// markers to avoid misleading the analysis.
1562
- if (!IsOffsetKnown || !Offset.isZero ())
1563
- return Base::visitIntrinsicInst (II);
1564
- switch (II.getIntrinsicID ()) {
1565
- default :
1556
+ if (II.getIntrinsicID () != Intrinsic::lifetime_start || !IsOffsetKnown ||
1557
+ !Offset.isZero ())
1566
1558
return Base::visitIntrinsicInst (II);
1567
- case Intrinsic::lifetime_start:
1568
- LifetimeStarts.insert (&II);
1569
- LifetimeStartBBs.push_back (II.getParent ());
1570
- break ;
1571
- case Intrinsic::lifetime_end:
1572
- LifetimeEndBBs.insert (II.getParent ());
1573
- break ;
1574
- }
1559
+ LifetimeStarts.insert (&II);
1575
1560
}
1576
1561
1577
1562
void visitCallBase (CallBase &CB) {
@@ -1601,17 +1586,14 @@ struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> {
1601
1586
1602
1587
private:
1603
1588
const DominatorTree &DT;
1604
- const coro::Shape &CoroShape ;
1589
+ const CoroBeginInst &CoroBegin ;
1605
1590
const SuspendCrossingInfo &Checker;
1606
1591
// All alias to the original AllocaInst, created before CoroBegin and used
1607
1592
// after CoroBegin. Each entry contains the instruction and the offset in the
1608
1593
// original Alloca. They need to be recreated after CoroBegin off the frame.
1609
1594
DenseMap<Instruction *, std::optional<APInt>> AliasOffetMap{};
1610
1595
SmallPtrSet<Instruction *, 4 > Users{};
1611
1596
SmallPtrSet<IntrinsicInst *, 2 > LifetimeStarts{};
1612
- SmallVector<BasicBlock *> LifetimeStartBBs{};
1613
- SmallPtrSet<BasicBlock *, 2 > LifetimeEndBBs{};
1614
- SmallPtrSet<const BasicBlock *, 2 > CoroSuspendBBs{};
1615
1597
bool MayWriteBeforeCoroBegin{false };
1616
1598
bool ShouldUseLifetimeStartInfo{true };
1617
1599
@@ -1623,19 +1605,10 @@ struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> {
1623
1605
// every basic block that uses the pointer to see if they cross suspension
1624
1606
// points. The uses cover both direct uses as well as indirect uses.
1625
1607
if (ShouldUseLifetimeStartInfo && !LifetimeStarts.empty ()) {
1626
- // If there is no explicit lifetime.end, then assume the address can
1627
- // cross suspension points.
1628
- if (LifetimeEndBBs.empty ())
1629
- return true ;
1630
-
1631
- // If there is a path from a lifetime.start to a suspend without a
1632
- // corresponding lifetime.end, then the alloca's lifetime persists
1633
- // beyond that suspension point and the alloca must go on the frame.
1634
- llvm::SmallVector<BasicBlock *> Worklist (LifetimeStartBBs);
1635
- if (isManyPotentiallyReachableFromMany (Worklist, CoroSuspendBBs,
1636
- &LifetimeEndBBs, &DT))
1637
- return true ;
1638
-
1608
+ for (auto *I : Users)
1609
+ for (auto *S : LifetimeStarts)
1610
+ if (Checker.isDefinitionAcrossSuspend (*S, I))
1611
+ return true ;
1639
1612
// Addresses are guaranteed to be identical after every lifetime.start so
1640
1613
// we cannot use the local stack if the address escaped and there is a
1641
1614
// suspend point between lifetime markers. This should also cover the
@@ -1673,13 +1646,13 @@ struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> {
1673
1646
}
1674
1647
1675
1648
void handleMayWrite (const Instruction &I) {
1676
- if (!DT.dominates (CoroShape. CoroBegin , &I))
1649
+ if (!DT.dominates (& CoroBegin, &I))
1677
1650
MayWriteBeforeCoroBegin = true ;
1678
1651
}
1679
1652
1680
1653
bool usedAfterCoroBegin (Instruction &I) {
1681
1654
for (auto &U : I.uses ())
1682
- if (DT.dominates (CoroShape. CoroBegin , U))
1655
+ if (DT.dominates (& CoroBegin, U))
1683
1656
return true ;
1684
1657
return false ;
1685
1658
}
@@ -1688,7 +1661,7 @@ struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> {
1688
1661
// We track all aliases created prior to CoroBegin but used after.
1689
1662
// These aliases may need to be recreated after CoroBegin if the alloca
1690
1663
// need to live on the frame.
1691
- if (DT.dominates (CoroShape. CoroBegin , &I) || !usedAfterCoroBegin (I))
1664
+ if (DT.dominates (& CoroBegin, &I) || !usedAfterCoroBegin (I))
1692
1665
return ;
1693
1666
1694
1667
if (!IsOffsetKnown) {
@@ -2857,7 +2830,8 @@ static void collectFrameAlloca(AllocaInst *AI, coro::Shape &Shape,
2857
2830
bool ShouldUseLifetimeStartInfo =
2858
2831
(Shape.ABI != coro::ABI::Async && Shape.ABI != coro::ABI::Retcon &&
2859
2832
Shape.ABI != coro::ABI::RetconOnce);
2860
- AllocaUseVisitor Visitor{AI->getModule ()->getDataLayout (), DT, Shape, Checker,
2833
+ AllocaUseVisitor Visitor{AI->getModule ()->getDataLayout (), DT,
2834
+ *Shape.CoroBegin , Checker,
2861
2835
ShouldUseLifetimeStartInfo};
2862
2836
Visitor.visitPtr (*AI);
2863
2837
if (!Visitor.getShouldLiveOnFrame ())
0 commit comments