@@ -367,44 +367,6 @@ bool PrunedLiveRange<LivenessWithDefs>::areUsesOutsideBoundary(
367
367
return true ;
368
368
}
369
369
370
- template <typename LivenessWithDefs>
371
- void PrunedLiveRange<LivenessWithDefs>::findBoundariesInBlock(
372
- SILBasicBlock *block, bool isLiveOut,
373
- PrunedLivenessBoundary &boundary) const {
374
- assert (asImpl ().isInitialized ());
375
-
376
- bool isLive = isLiveOut;
377
- bool isDefBlock = asImpl ().isDefBlock (block);
378
- SILInstruction *nextDef = nullptr ;
379
- SILInstruction *searchPos = block->getTerminator ();
380
- while (searchPos) {
381
- if (isLive) {
382
- nextDef = asImpl ().findPreviousDef (searchPos, nextDef);
383
- if (!nextDef)
384
- return ;
385
-
386
- searchPos = nextDef;
387
- isLive = false ;
388
- } else if (isDefBlock) {
389
- // Check if the previous instruction is a def before checking whether it
390
- // is a use. The same instruction can be both a dead def and boundary use.
391
- if (asImpl ().isDef (searchPos)) {
392
- boundary.deadDefs .push_back (cast<SILNode>(searchPos));
393
- }
394
- }
395
- if (isInterestingUser (searchPos)) {
396
- boundary.lastUsers .push_back (searchPos);
397
- isLive = true ;
398
- }
399
- searchPos = searchPos->getPreviousInstruction ();
400
- }
401
- if (!isLive && isDefBlock) {
402
- if (SILArgument *deadArg = asImpl ().getArgDef (block)) {
403
- boundary.deadDefs .push_back (deadArg);
404
- }
405
- }
406
- }
407
-
408
370
template <typename LivenessWithDefs>
409
371
void PrunedLiveRange<LivenessWithDefs>::computeBoundary(
410
372
PrunedLivenessBoundary &boundary) const {
@@ -419,10 +381,10 @@ void PrunedLiveRange<LivenessWithDefs>::computeBoundary(
419
381
boundary.boundaryEdges .push_back (succBB);
420
382
}
421
383
}
422
- findBoundariesInBlock (block, /* isLiveOut*/ true , boundary);
384
+ asImpl (). findBoundariesInBlock (block, /* isLiveOut*/ true , boundary);
423
385
break ;
424
386
case PrunedLiveBlocks::LiveWithin: {
425
- findBoundariesInBlock (block, /* isLiveOut*/ false , boundary);
387
+ asImpl (). findBoundariesInBlock (block, /* isLiveOut*/ false , boundary);
426
388
break ;
427
389
}
428
390
case PrunedLiveBlocks::Dead:
@@ -451,10 +413,10 @@ void PrunedLiveRange<LivenessWithDefs>::computeBoundary(
451
413
// Process each block that has not been visited and is not LiveOut.
452
414
switch (getBlockLiveness (block)) {
453
415
case PrunedLiveBlocks::LiveOut:
454
- findBoundariesInBlock (block, /* isLiveOut*/ true , boundary);
416
+ asImpl (). findBoundariesInBlock (block, /* isLiveOut*/ true , boundary);
455
417
break ;
456
418
case PrunedLiveBlocks::LiveWithin: {
457
- findBoundariesInBlock (block, /* isLiveOut*/ false , boundary);
419
+ asImpl (). findBoundariesInBlock (block, /* isLiveOut*/ false , boundary);
458
420
break ;
459
421
}
460
422
case PrunedLiveBlocks::Dead:
@@ -476,26 +438,71 @@ template class PrunedLiveRange<SSAPrunedLiveness>;
476
438
template class PrunedLiveRange <MultiDefPrunedLiveness>;
477
439
} // namespace swift
478
440
441
+ // ===----------------------------------------------------------------------===//
442
+ // SSAPrunedLiveness
443
+ // ===----------------------------------------------------------------------===//
444
+
445
+ void SSAPrunedLiveness::findBoundariesInBlock (
446
+ SILBasicBlock *block, bool isLiveOut,
447
+ PrunedLivenessBoundary &boundary) const {
448
+ assert (isInitialized ());
449
+
450
+ // For SSA, a live-out block cannot have a boundary.
451
+ if (isLiveOut)
452
+ return ;
453
+
454
+ bool isDefBlockState = isDefBlock (block);
455
+ for (SILInstruction &inst : llvm::reverse (*block)) {
456
+ if (isDefBlockState && isDef (&inst)) {
457
+ boundary.deadDefs .push_back (cast<SILNode>(&inst));
458
+ return ;
459
+ }
460
+ if (isInterestingUser (&inst)) {
461
+ boundary.lastUsers .push_back (&inst);
462
+ return ;
463
+ }
464
+ }
465
+ auto *deadArg = dyn_cast<SILArgument>(def);
466
+ assert (deadArg && deadArg->getParent () == block
467
+ && " findBoundariesInBlock must be called on a live block" );
468
+ boundary.deadDefs .push_back (deadArg);
469
+ }
470
+
479
471
// ===----------------------------------------------------------------------===//
480
472
// MultiDefPrunedLiveness
481
473
// ===----------------------------------------------------------------------===//
482
474
483
- SILInstruction *
484
- MultiDefPrunedLiveness::findPreviousDef (SILInstruction *searchPos,
485
- SILInstruction *nextDef) const {
486
- auto *block = searchPos->getParent ();
487
- if (!defBlocks.contains (block))
488
- return nullptr ;
475
+ void MultiDefPrunedLiveness::findBoundariesInBlock (
476
+ SILBasicBlock *block, bool isLiveOut,
477
+ PrunedLivenessBoundary &boundary) const {
478
+ assert (isInitialized ());
479
+ unsigned prevCount = boundary.deadDefs .size () + boundary.lastUsers .size ();
489
480
490
- auto it = searchPos->getReverseIterator ();
491
- if (searchPos == nextDef) {
492
- ++it;
481
+ bool isLive = isLiveOut;
482
+ bool isDefBlockState = isDefBlock (block);
483
+ for (auto &inst : llvm::reverse (*block)) {
484
+ // Check if the instruction is a def before checking whether it is a
485
+ // use. The same instruction can be both a dead def and boundary use.
486
+ if (isDefBlockState && isDef (&inst)) {
487
+ if (!isLive) {
488
+ boundary.deadDefs .push_back (cast<SILNode>(&inst));
489
+ }
490
+ isLive = false ;
491
+ }
492
+ if (!isLive && isInterestingUser (&inst)) {
493
+ boundary.lastUsers .push_back (&inst);
494
+ isLive = true ;
495
+ }
493
496
}
494
- for (auto end = block->rend (); it != end; ++it) {
495
- if (isDef (&*it))
496
- return &*it;
497
+ if (!isLive && isDefBlockState) {
498
+ for (SILArgument *deadArg : block->getArguments ()) {
499
+ if (defs.contains (deadArg)) {
500
+ boundary.deadDefs .push_back (deadArg);
501
+ }
502
+ }
497
503
}
498
- return nullptr ;
504
+ assert (prevCount < boundary.deadDefs .size () + boundary.lastUsers .size ()
505
+ && " findBoundariesInBlock must be called on a live block" );
499
506
}
500
507
501
508
SimpleLiveRangeSummary MultiDefPrunedLiveness::computeSimple () {
0 commit comments