@@ -493,17 +493,21 @@ class FieldSensitivePrunedLiveBlocks {
493
493
// / LiveWithin blocks have at least one use and/or def within the block, but
494
494
// / are not (yet) LiveOut.
495
495
// /
496
+ // / DeadToLiveEdge blocks are not live within the block itself, but the value
497
+ // / becomes live on one or more of the edges out.
498
+ // /
496
499
// / LiveOut blocks are live on at least one successor path. LiveOut blocks may
497
500
// / or may not contain defs or uses.
498
- // /
499
- // / NOTE: The values below for Dead, LiveWithin, LiveOut were picked to ensure
500
- // / that given a 2 bit representation of the value, a value is Dead if the
501
- // / first bit is 0 and is LiveOut if the second bit is set.
502
501
enum IsLive {
503
502
Dead = 0 ,
504
503
LiveWithin = 1 ,
504
+ DeadToLiveEdge = 2 ,
505
505
LiveOut = 3 ,
506
506
};
507
+
508
+ static bool isDead (IsLive liveness) {
509
+ return liveness == Dead || liveness == DeadToLiveEdge;
510
+ }
507
511
508
512
// / A bit vector that stores information about liveness. This is composed
509
513
// / with SmallBitVector since it contains two bits per liveness so that it
@@ -524,37 +528,27 @@ class FieldSensitivePrunedLiveBlocks {
524
528
unsigned size () const { return bits.size () / 2 ; }
525
529
526
530
IsLive getLiveness (unsigned bitNo) const {
527
- if (!bits[bitNo * 2 ])
528
- return IsLive::Dead;
529
- return bits[bitNo * 2 + 1 ] ? LiveOut : LiveWithin;
531
+ return IsLive ((bits[bitNo * 2 + 1 ] << 1 ) | bits[bitNo * 2 ]);
530
532
}
531
533
532
534
// / Returns the liveness in \p resultingFoundLiveness. We only return the
533
535
// / bits for endBitNo - startBitNo.
534
536
void getLiveness (unsigned startBitNo, unsigned endBitNo,
535
537
SmallVectorImpl<IsLive> &resultingFoundLiveness) const {
536
- unsigned actualStartBitNo = startBitNo * 2 ;
537
- unsigned actualEndBitNo = endBitNo * 2 ;
538
-
539
- for (unsigned i = actualStartBitNo, e = actualEndBitNo; i != e; i += 2 ) {
540
- if (!bits[i]) {
541
- resultingFoundLiveness.push_back (Dead);
542
- continue ;
543
- }
544
-
545
- resultingFoundLiveness.push_back (bits[i + 1 ] ? LiveOut : LiveWithin);
538
+ for (unsigned i = startBitNo, e = endBitNo; i != e; ++i) {
539
+ resultingFoundLiveness.push_back (getLiveness (i));
546
540
}
547
541
}
548
542
549
- void setLiveness (unsigned startBitNo, unsigned endBitNo, IsLive isLive) {
550
- for (unsigned i = startBitNo * 2 , e = endBitNo * 2 ; i != e; i += 2 ) {
551
- bits[i] = isLive & 1 ;
552
- bits[i + 1 ] = isLive & 2 ;
553
- }
543
+ void setLiveness (unsigned bitNo, IsLive isLive) {
544
+ bits[bitNo * 2 ] = isLive & 1 ;
545
+ bits[bitNo * 2 + 1 ] = bool (isLive & 2 );
554
546
}
555
547
556
- void setLiveness (unsigned bitNo, IsLive isLive) {
557
- setLiveness (bitNo, bitNo + 1 , isLive);
548
+ void setLiveness (unsigned startBitNo, unsigned endBitNo, IsLive isLive) {
549
+ for (unsigned i = startBitNo, e = endBitNo; i != e; ++i) {
550
+ setLiveness (i, isLive);
551
+ }
558
552
}
559
553
};
560
554
@@ -620,9 +614,10 @@ class FieldSensitivePrunedLiveBlocks {
620
614
}
621
615
622
616
void initializeDefBlock (SILBasicBlock *defBB, unsigned startBitNo,
623
- unsigned endBitNo) {
617
+ unsigned endBitNo,
618
+ IsLive isLive = LiveWithin) {
624
619
assert (isInitialized ());
625
- markBlockLive (defBB, startBitNo, endBitNo, LiveWithin );
620
+ markBlockLive (defBB, startBitNo, endBitNo, isLive );
626
621
}
627
622
628
623
// / Update this liveness result for a single use.
@@ -632,7 +627,7 @@ class FieldSensitivePrunedLiveBlocks {
632
627
auto *block = user->getParent ();
633
628
if (!isUserBeforeDef) {
634
629
auto liveness = getBlockLiveness (block, bitNo);
635
- if (liveness != Dead )
630
+ if (! isDead (liveness) )
636
631
return liveness;
637
632
}
638
633
computeScalarUseBlockLiveness (block, bitNo);
@@ -696,6 +691,7 @@ class FieldSensitivePrunedLiveBlocks {
696
691
// If we are dead, always update to the new liveness.
697
692
switch (iterAndInserted.first ->getSecond ().getLiveness (bitNo)) {
698
693
case Dead:
694
+ case DeadToLiveEdge:
699
695
iterAndInserted.first ->getSecond ().setLiveness (bitNo, bitNo + 1 ,
700
696
isLive);
701
697
break ;
@@ -935,10 +931,12 @@ class FieldSensitivePrunedLiveness {
935
931
return UserBlockRange (getAllUsers (), op);
936
932
}
937
933
938
- void initializeDefBlock (SILBasicBlock *defBB, TypeTreeLeafTypeRange span) {
934
+ void initializeDefBlock (SILBasicBlock *defBB, TypeTreeLeafTypeRange span,
935
+ FieldSensitivePrunedLiveBlocks::IsLive isLive
936
+ = FieldSensitivePrunedLiveBlocks::LiveWithin) {
939
937
assert (isInitialized ());
940
938
liveBlocks.initializeDefBlock (defBB, span.startEltOffset ,
941
- span.endEltOffset );
939
+ span.endEltOffset , isLive );
942
940
}
943
941
944
942
// / For flexibility, \p lifetimeEnding is provided by the
@@ -1303,6 +1301,14 @@ class FieldSensitiveSSAPrunedLiveRange
1303
1301
FieldSensitivePrunedLivenessBoundary &boundary) const ;
1304
1302
};
1305
1303
1304
+ static inline SILBasicBlock *getDefinedInBlock (SILNode *node) {
1305
+ // try_apply defines the value only on the success edge.
1306
+ if (auto ta = dyn_cast<TryApplyInst>(node)) {
1307
+ return ta->getNormalBB ();
1308
+ }
1309
+ return node->getParentBlock ();
1310
+ }
1311
+
1306
1312
// / MultiDefPrunedLiveness is computed incrementally by calling updateForUse.
1307
1313
// /
1308
1314
// / Defs should be initialized before calling updatingForUse on any def
@@ -1351,9 +1357,17 @@ class FieldSensitiveMultiDefPrunedLiveRange
1351
1357
void initializeDef (SILNode *node, TypeTreeLeafTypeRange span) {
1352
1358
assert (Super::isInitialized ());
1353
1359
defs.insert (node, span);
1354
- auto *block = node->getParentBlock ();
1355
- defBlocks.insert (block, span);
1356
- initializeDefBlock (block, span);
1360
+ auto defBlock = getDefinedInBlock (node);
1361
+ defBlocks.insert (defBlock, span);
1362
+ initializeDefBlock (defBlock, span);
1363
+
1364
+ if (auto ta = dyn_cast<TryApplyInst>(node)) {
1365
+ // The value becomes live on the success edge.
1366
+ // Mark the basic block the try_apply terminates as a dead-to-live
1367
+ // edge.
1368
+ initializeDefBlock (ta->getParent (), span,
1369
+ FieldSensitivePrunedLiveBlocks::DeadToLiveEdge);
1370
+ }
1357
1371
}
1358
1372
1359
1373
void initializeDef (SILInstruction *def, TypeTreeLeafTypeRange span) {
0 commit comments