19
19
#include " swift/SIL/BasicBlockDatastructures.h"
20
20
#include " swift/SIL/BasicBlockUtils.h"
21
21
#include " swift/SIL/OwnershipUtils.h"
22
- #include " swift/SIL/PrunedLiveness.h"
23
22
#include " swift/SIL/SILBuilder.h"
24
23
#include " swift/SIL/SILInstruction.h"
25
24
#include " swift/SIL/ScopedAddressUtils.h"
@@ -445,14 +444,111 @@ void TypeTreeLeafTypeRange::constructProjectionsForNeededElements(
445
444
}
446
445
}
447
446
447
+ // ===----------------------------------------------------------------------===//
448
+ // MARK: FieldSensitivePrunedLiveBlocks
449
+ // ===----------------------------------------------------------------------===//
450
+
451
+ void FieldSensitivePrunedLiveBlocks::computeScalarUseBlockLiveness (
452
+ SILBasicBlock *userBB, unsigned bitNo) {
453
+ // If, we are visiting this block, then it is not already LiveOut. Mark it
454
+ // LiveWithin to indicate a liveness boundary within the block.
455
+ markBlockLive (userBB, bitNo, LiveWithin);
456
+
457
+ BasicBlockWorklist worklist (userBB->getFunction ());
458
+ worklist.push (userBB);
459
+
460
+ while (auto *block = worklist.pop ()) {
461
+ // The popped `bb` is live; now mark all its predecessors LiveOut.
462
+ //
463
+ // Traversal terminates at any previously visited block, including the
464
+ // blocks initialized as definition blocks.
465
+ for (auto *predBlock : block->getPredecessorBlocks ()) {
466
+ switch (getBlockLiveness (predBlock, bitNo)) {
467
+ case Dead:
468
+ worklist.pushIfNotVisited (predBlock);
469
+ LLVM_FALLTHROUGH;
470
+ case LiveWithin:
471
+ markBlockLive (predBlock, bitNo, LiveOut);
472
+ break ;
473
+ case LiveOut:
474
+ break ;
475
+ }
476
+ }
477
+ }
478
+ }
479
+
480
+ // / Update the current def's liveness based on one specific use instruction.
481
+ // /
482
+ // / Return the updated liveness of the \p use block (LiveOut or LiveWithin).
483
+ // /
484
+ // / Terminators are not live out of the block.
485
+ void FieldSensitivePrunedLiveBlocks::updateForUse (
486
+ SILInstruction *user, unsigned startBitNo, unsigned endBitNo,
487
+ SmallVectorImpl<IsLive> &resultingLivenessInfo) {
488
+ assert (isInitialized ());
489
+ resultingLivenessInfo.clear ();
490
+
491
+ SWIFT_ASSERT_ONLY (seenUse = true );
492
+
493
+ auto *bb = user->getParent ();
494
+ getBlockLiveness (bb, startBitNo, endBitNo, resultingLivenessInfo);
495
+
496
+ for (auto pair : llvm::enumerate (resultingLivenessInfo)) {
497
+ unsigned index = pair.index ();
498
+ unsigned specificBitNo = startBitNo + index ;
499
+ switch (pair.value ()) {
500
+ case LiveOut:
501
+ case LiveWithin:
502
+ continue ;
503
+ case Dead: {
504
+ // This use block has not yet been marked live. Mark it and its
505
+ // predecessor blocks live.
506
+ computeScalarUseBlockLiveness (bb, specificBitNo);
507
+ resultingLivenessInfo.push_back (getBlockLiveness (bb, specificBitNo));
508
+ continue ;
509
+ }
510
+ }
511
+ llvm_unreachable (" covered switch" );
512
+ }
513
+ }
514
+
515
+ llvm::StringRef
516
+ FieldSensitivePrunedLiveBlocks::getStringRef (IsLive isLive) const {
517
+ switch (isLive) {
518
+ case Dead:
519
+ return " Dead" ;
520
+ case LiveWithin:
521
+ return " LiveWithin" ;
522
+ case LiveOut:
523
+ return " LiveOut" ;
524
+ }
525
+ }
526
+
527
+ void FieldSensitivePrunedLiveBlocks::print (llvm::raw_ostream &OS) const {
528
+ if (!discoveredBlocks) {
529
+ OS << " No deterministic live block list\n " ;
530
+ return ;
531
+ }
532
+ SmallVector<IsLive, 8 > isLive;
533
+ for (auto *block : *discoveredBlocks) {
534
+ block->printAsOperand (OS);
535
+ OS << " : " ;
536
+ for (unsigned i : range (getNumBitsToTrack ()))
537
+ OS << getStringRef (this ->getBlockLiveness (block, i)) << " , " ;
538
+ OS << " \n " ;
539
+ }
540
+ }
541
+
542
+ void FieldSensitivePrunedLiveBlocks::dump () const { print (llvm::dbgs ()); }
543
+
448
544
// ===----------------------------------------------------------------------===//
449
545
// MARK: FieldSensitiveLiveness
450
546
// ===----------------------------------------------------------------------===//
451
547
452
548
void FieldSensitivePrunedLiveness::updateForUse (SILInstruction *user,
453
549
TypeTreeLeafTypeRange range,
454
550
bool lifetimeEnding) {
455
- SmallVector<PrunedLiveBlocks ::IsLive, 8 > resultingLiveness;
551
+ SmallVector<FieldSensitivePrunedLiveBlocks ::IsLive, 8 > resultingLiveness;
456
552
liveBlocks.updateForUse (user, range.startEltOffset , range.endEltOffset ,
457
553
resultingLiveness);
458
554
@@ -479,7 +575,7 @@ bool FieldSensitivePrunedLiveRange<LivenessWithDefs>::isWithinBoundary(
479
575
return true ;
480
576
}
481
577
482
- using IsLive = PrunedLiveBlocks ::IsLive;
578
+ using IsLive = FieldSensitivePrunedLiveBlocks ::IsLive;
483
579
484
580
auto *block = inst->getParent ();
485
581
@@ -491,12 +587,12 @@ bool FieldSensitivePrunedLiveRange<LivenessWithDefs>::isWithinBoundary(
491
587
LLVM_DEBUG (llvm::dbgs () << " Visiting bit: " << bit << ' \n ' );
492
588
bool isLive = false ;
493
589
switch (pair.value ()) {
494
- case PrunedLiveBlocks ::Dead:
590
+ case FieldSensitivePrunedLiveBlocks ::Dead:
495
591
LLVM_DEBUG (llvm::dbgs () << " Dead... continuing!\n " );
496
592
// We are only not within the boundary if all of our bits are dead. We
497
593
// track this via allDeadBits. So, just continue.
498
594
continue ;
499
- case PrunedLiveBlocks ::LiveOut:
595
+ case FieldSensitivePrunedLiveBlocks ::LiveOut:
500
596
// If we are LiveOut and are not a def block, then we know that we are
501
597
// within the boundary for this bit. We consider ourselves to be within
502
598
// the boundary if /any/ of our bits are within the boundary. So return
@@ -513,7 +609,7 @@ bool FieldSensitivePrunedLiveRange<LivenessWithDefs>::isWithinBoundary(
513
609
LLVM_DEBUG (llvm::dbgs ()
514
610
<< " LiveOut, but a def block... searching block!\n " );
515
611
[[clang::fallthrough]];
516
- case PrunedLiveBlocks ::LiveWithin:
612
+ case FieldSensitivePrunedLiveBlocks ::LiveWithin:
517
613
bool shouldContinue = false ;
518
614
if (!isLive)
519
615
LLVM_DEBUG (llvm::dbgs () << " LiveWithin... searching block!\n " );
@@ -576,13 +672,13 @@ bool FieldSensitivePrunedLiveRange<LivenessWithDefs>::isWithinBoundary(
576
672
return false ;
577
673
}
578
674
579
- static StringRef getStringRef (PrunedLiveBlocks ::IsLive isLive) {
675
+ static StringRef getStringRef (FieldSensitivePrunedLiveBlocks ::IsLive isLive) {
580
676
switch (isLive) {
581
- case PrunedLiveBlocks ::Dead:
677
+ case FieldSensitivePrunedLiveBlocks ::Dead:
582
678
return " Dead" ;
583
- case PrunedLiveBlocks ::LiveWithin:
679
+ case FieldSensitivePrunedLiveBlocks ::LiveWithin:
584
680
return " LiveWithin" ;
585
- case PrunedLiveBlocks ::LiveOut:
681
+ case FieldSensitivePrunedLiveBlocks ::LiveOut:
586
682
return " LiveOut" ;
587
683
}
588
684
}
@@ -594,7 +690,7 @@ void FieldSensitivePrunedLiveRange<LivenessWithDefs>::computeBoundary(
594
690
595
691
LLVM_DEBUG (llvm::dbgs () << " Liveness Boundary Compuation!\n " );
596
692
597
- using IsLive = PrunedLiveBlocks ::IsLive;
693
+ using IsLive = FieldSensitivePrunedLiveBlocks ::IsLive;
598
694
SmallVector<IsLive, 8 > isLiveTmp;
599
695
for (SILBasicBlock *block : getDiscoveredBlocks ()) {
600
696
SWIFT_DEFER { isLiveTmp.clear (); };
@@ -610,9 +706,10 @@ void FieldSensitivePrunedLiveRange<LivenessWithDefs>::computeBoundary(
610
706
LLVM_DEBUG (llvm::dbgs () << " Bit: " << index << " . Liveness: "
611
707
<< getStringRef (pair.value ()) << ' \n ' );
612
708
switch (pair.value ()) {
613
- case PrunedLiveBlocks ::LiveOut:
709
+ case FieldSensitivePrunedLiveBlocks ::LiveOut:
614
710
for (SILBasicBlock *succBB : block->getSuccessors ()) {
615
- if (getBlockLiveness (succBB, index ) == PrunedLiveBlocks::Dead) {
711
+ if (getBlockLiveness (succBB, index ) ==
712
+ FieldSensitivePrunedLiveBlocks::Dead) {
616
713
LLVM_DEBUG (llvm::dbgs () << " Marking succBB as boundary edge: bb"
617
714
<< succBB->getDebugID () << ' \n ' );
618
715
boundary.getBoundaryEdgeBits (succBB).set (index );
@@ -622,13 +719,13 @@ void FieldSensitivePrunedLiveRange<LivenessWithDefs>::computeBoundary(
622
719
boundary);
623
720
foundAnyNonDead = true ;
624
721
break ;
625
- case PrunedLiveBlocks ::LiveWithin: {
722
+ case FieldSensitivePrunedLiveBlocks ::LiveWithin: {
626
723
asImpl ().findBoundariesInBlock (block, index , /* isLiveOut*/ false ,
627
724
boundary);
628
725
foundAnyNonDead = true ;
629
726
break ;
630
727
}
631
- case PrunedLiveBlocks ::Dead:
728
+ case FieldSensitivePrunedLiveBlocks ::Dead:
632
729
// We do not assert here like in the normal pruned liveness
633
730
// implementation since we can have dead on some bits and liveness along
634
731
// others.
@@ -682,7 +779,7 @@ void findBoundaryInNonDefBlock(SILBasicBlock *block, unsigned bitNo,
682
779
FieldSensitivePrunedLivenessBoundary &boundary,
683
780
const FieldSensitivePrunedLiveness &liveness) {
684
781
assert (liveness.getBlockLiveness (block, bitNo) ==
685
- PrunedLiveBlocks ::LiveWithin);
782
+ FieldSensitivePrunedLiveBlocks ::LiveWithin);
686
783
687
784
LLVM_DEBUG (llvm::dbgs () << " Looking for boundary in non-def block\n " );
688
785
for (SILInstruction &inst : llvm::reverse (*block)) {
@@ -895,7 +992,7 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock(
895
992
if (llvm::all_of (block->getPredecessorBlocks (),
896
993
[&](SILBasicBlock *predBlock) -> bool {
897
994
return getBlockLiveness (predBlock, bitNo) ==
898
- PrunedLiveBlocks ::IsLive::LiveOut;
995
+ FieldSensitivePrunedLiveBlocks ::IsLive::LiveOut;
899
996
})) {
900
997
boundary.getBoundaryEdgeBits (block).set (bitNo);
901
998
}
0 commit comments