@@ -543,10 +543,37 @@ class PrunedLiveness {
543543 RangeIterationHelpers::MapFunctor ());
544544 }
545545
546+ void visitUsers (llvm::function_ref<void (SILInstruction *, LifetimeEnding)>
547+ visitor) const {
548+ for (auto &pair : users) {
549+ visitor (pair.first , pair.second );
550+ }
551+ }
552+
546553 void print (llvm::raw_ostream &OS) const ;
547554 void dump () const ;
548555};
549556
557+ // / Recording liveness boundary at some level of detail; see concrete subclasses
558+ // / PrunedLivenessBoundary and PrunedLivenessBlockBoundary.
559+ struct AnyPrunedLivenessBoundary {
560+ virtual ~AnyPrunedLivenessBoundary () {}
561+ // / Targets whose single predecessor has at least one non-boundary successor.
562+ SmallVector<SILBasicBlock *, 8 > boundaryEdges;
563+
564+ friend class SSAPrunedLiveness ;
565+ friend class MultiDefPrunedLiveness ;
566+
567+ private:
568+ virtual void findBoundaryInSSADefBlock (SILNode *ssaDef,
569+ const PrunedLiveness &liveness) = 0;
570+ virtual void
571+ findBoundaryInMultiDefBlock (SILBasicBlock *block, bool isLiveOut,
572+ const MultiDefPrunedLiveness &liveness) = 0 ;
573+ virtual void findBoundaryInNonDefBlock (SILBasicBlock *block,
574+ const PrunedLiveness &liveness) = 0;
575+ };
576+
550577// / Record the last use points and CFG edges that form the boundary of
551578// / PrunedLiveness.
552579// /
@@ -558,9 +585,8 @@ class PrunedLiveness {
558585// / Each boundary edge is identified by its target block. The source of the edge
559586// / is the target block's single predecessor which must have at least one other
560587// / non-boundary successor.
561- struct PrunedLivenessBoundary {
588+ struct PrunedLivenessBoundary : AnyPrunedLivenessBoundary {
562589 SmallVector<SILInstruction *, 8 > lastUsers;
563- SmallVector<SILBasicBlock *, 8 > boundaryEdges;
564590 SmallVector<SILNode *, 1 > deadDefs;
565591
566592 void clear () {
@@ -579,6 +605,39 @@ struct PrunedLivenessBoundary {
579605
580606 void print (llvm::raw_ostream &OS) const ;
581607 void dump () const ;
608+
609+ private:
610+ void findBoundaryInSSADefBlock (SILNode *ssaDef,
611+ const PrunedLiveness &liveness) override ;
612+ void
613+ findBoundaryInMultiDefBlock (SILBasicBlock *block, bool isLiveOut,
614+ const MultiDefPrunedLiveness &liveness) override ;
615+ void findBoundaryInNonDefBlock (SILBasicBlock *block,
616+ const PrunedLiveness &liveness) override ;
617+ };
618+
619+ // / Record the blocks which either contain last use points or are boundary edge
620+ // / targets.
621+ // /
622+ // / Enables clients only interested in block-level details to avoid expensive
623+ // / and for-them wasteful instruction list iteration.
624+ struct PrunedLivenessBlockBoundary : AnyPrunedLivenessBoundary {
625+ // / Blocks containing last users or dead defs.
626+ SmallVector<SILBasicBlock *, 8 > endBlocks;
627+
628+ void clear () {
629+ endBlocks.clear ();
630+ boundaryEdges.clear ();
631+ }
632+
633+ private:
634+ void findBoundaryInSSADefBlock (SILNode *ssaDef,
635+ const PrunedLiveness &liveness) override ;
636+ void
637+ findBoundaryInMultiDefBlock (SILBasicBlock *block, bool isLiveOut,
638+ const MultiDefPrunedLiveness &liveness) override ;
639+ void findBoundaryInNonDefBlock (SILBasicBlock *block,
640+ const PrunedLiveness &liveness) override ;
582641};
583642
584643// / PrunedLiveness with information about defs for computing the live range
@@ -689,7 +748,7 @@ class PrunedLiveRange : public PrunedLiveness {
689748 // / The computed boundary will completely post-dominate, including dead end
690749 // / paths. The client should query DeadEndBlocks to ignore those dead end
691750 // / paths.
692- void computeBoundary (PrunedLivenessBoundary &boundary) const ;
751+ void computeBoundary (AnyPrunedLivenessBoundary &boundary) const ;
693752
694753 // / Compute the boundary from a backward CFG traversal from a known set of
695754 // / jointly post-dominating blocks. Avoids the need to record an ordered list
@@ -765,7 +824,7 @@ class SSAPrunedLiveness : public PrunedLiveRange<SSAPrunedLiveness> {
765824
766825 // / SSA implementation of computeBoundary.
767826 void findBoundariesInBlock (SILBasicBlock *block, bool isLiveOut,
768- PrunedLivenessBoundary &boundary) const ;
827+ AnyPrunedLivenessBoundary &boundary) const ;
769828
770829 // / Compute liveness for a single SSA definition. The lifetime-ending uses are
771830 // / also recorded--destroy_value or end_borrow.
@@ -853,9 +912,9 @@ class MultiDefPrunedLiveness : public PrunedLiveRange<MultiDefPrunedLiveness> {
853912
854913 // / Multi-Def implementation of computeBoundary.
855914 void findBoundariesInBlock (SILBasicBlock *block, bool isLiveOut,
856- PrunedLivenessBoundary &boundary) const ;
915+ AnyPrunedLivenessBoundary &boundary) const ;
857916
858- // / Compute liveness for a all currently initialized definitions. The
917+ // / Compute liveness for all currently initialized definitions. The
859918 // / lifetime-ending uses are also recorded--destroy_value or
860919 // / end_borrow. However destroy_values might not jointly-post dominate if
861920 // / dead-end blocks are present.
@@ -872,6 +931,9 @@ class MultiDefPrunedLiveness : public PrunedLiveRange<MultiDefPrunedLiveness> {
872931 // / also lack scope-ending instructions, so the liveness of their nested uses
873932 // / may be ignored.
874933 LiveRangeSummary computeSimple ();
934+
935+ friend struct PrunedLivenessBoundary ;
936+ friend struct PrunedLivenessBlockBoundary ;
875937};
876938
877939// ===----------------------------------------------------------------------===//
0 commit comments