@@ -543,10 +543,37 @@ class PrunedLiveness {
543
543
RangeIterationHelpers::MapFunctor ());
544
544
}
545
545
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
+
546
553
void print (llvm::raw_ostream &OS) const ;
547
554
void dump () const ;
548
555
};
549
556
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
+
550
577
// / Record the last use points and CFG edges that form the boundary of
551
578
// / PrunedLiveness.
552
579
// /
@@ -558,9 +585,8 @@ class PrunedLiveness {
558
585
// / Each boundary edge is identified by its target block. The source of the edge
559
586
// / is the target block's single predecessor which must have at least one other
560
587
// / non-boundary successor.
561
- struct PrunedLivenessBoundary {
588
+ struct PrunedLivenessBoundary : AnyPrunedLivenessBoundary {
562
589
SmallVector<SILInstruction *, 8 > lastUsers;
563
- SmallVector<SILBasicBlock *, 8 > boundaryEdges;
564
590
SmallVector<SILNode *, 1 > deadDefs;
565
591
566
592
void clear () {
@@ -579,6 +605,39 @@ struct PrunedLivenessBoundary {
579
605
580
606
void print (llvm::raw_ostream &OS) const ;
581
607
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 ;
582
641
};
583
642
584
643
// / PrunedLiveness with information about defs for computing the live range
@@ -689,7 +748,7 @@ class PrunedLiveRange : public PrunedLiveness {
689
748
// / The computed boundary will completely post-dominate, including dead end
690
749
// / paths. The client should query DeadEndBlocks to ignore those dead end
691
750
// / paths.
692
- void computeBoundary (PrunedLivenessBoundary &boundary) const ;
751
+ void computeBoundary (AnyPrunedLivenessBoundary &boundary) const ;
693
752
694
753
// / Compute the boundary from a backward CFG traversal from a known set of
695
754
// / jointly post-dominating blocks. Avoids the need to record an ordered list
@@ -765,7 +824,7 @@ class SSAPrunedLiveness : public PrunedLiveRange<SSAPrunedLiveness> {
765
824
766
825
// / SSA implementation of computeBoundary.
767
826
void findBoundariesInBlock (SILBasicBlock *block, bool isLiveOut,
768
- PrunedLivenessBoundary &boundary) const ;
827
+ AnyPrunedLivenessBoundary &boundary) const ;
769
828
770
829
// / Compute liveness for a single SSA definition. The lifetime-ending uses are
771
830
// / also recorded--destroy_value or end_borrow.
@@ -853,9 +912,9 @@ class MultiDefPrunedLiveness : public PrunedLiveRange<MultiDefPrunedLiveness> {
853
912
854
913
// / Multi-Def implementation of computeBoundary.
855
914
void findBoundariesInBlock (SILBasicBlock *block, bool isLiveOut,
856
- PrunedLivenessBoundary &boundary) const ;
915
+ AnyPrunedLivenessBoundary &boundary) const ;
857
916
858
- // / Compute liveness for a all currently initialized definitions. The
917
+ // / Compute liveness for all currently initialized definitions. The
859
918
// / lifetime-ending uses are also recorded--destroy_value or
860
919
// / end_borrow. However destroy_values might not jointly-post dominate if
861
920
// / dead-end blocks are present.
@@ -872,6 +931,9 @@ class MultiDefPrunedLiveness : public PrunedLiveRange<MultiDefPrunedLiveness> {
872
931
// / also lack scope-ending instructions, so the liveness of their nested uses
873
932
// / may be ignored.
874
933
LiveRangeSummary computeSimple ();
934
+
935
+ friend struct PrunedLivenessBoundary ;
936
+ friend struct PrunedLivenessBlockBoundary ;
875
937
};
876
938
877
939
// ===----------------------------------------------------------------------===//
0 commit comments