@@ -387,6 +387,12 @@ static bool anyMissing(unsigned StartSubElt, unsigned NumSubElts,
387
387
388
388
namespace {
389
389
390
+ enum class AvailableValueExpectedOwnership {
391
+ Take,
392
+ Borrow,
393
+ Copy,
394
+ };
395
+
390
396
// / A class that aggregates available values, loading them if they are not
391
397
// / available.
392
398
class AvailableValueAggregator {
@@ -396,7 +402,7 @@ class AvailableValueAggregator {
396
402
MutableArrayRef<AvailableValue> AvailableValueList;
397
403
SmallVectorImpl<PMOMemoryUse> &Uses;
398
404
DeadEndBlocks &deadEndBlocks;
399
- bool isTake ;
405
+ AvailableValueExpectedOwnership expectedOwnership ;
400
406
401
407
// / Keep track of all instructions that we have added. Once we are done
402
408
// / promoting a value, we need to make sure that if we need to balance any
@@ -408,10 +414,11 @@ class AvailableValueAggregator {
408
414
AvailableValueAggregator (SILInstruction *Inst,
409
415
MutableArrayRef<AvailableValue> AvailableValueList,
410
416
SmallVectorImpl<PMOMemoryUse> &Uses,
411
- DeadEndBlocks &deadEndBlocks, bool isTake)
417
+ DeadEndBlocks &deadEndBlocks,
418
+ AvailableValueExpectedOwnership expectedOwnership)
412
419
: M(Inst->getModule ()), B(Inst), Loc(Inst->getLoc ()),
413
420
AvailableValueList(AvailableValueList), Uses(Uses),
414
- deadEndBlocks(deadEndBlocks), isTake(isTake ) {}
421
+ deadEndBlocks(deadEndBlocks), expectedOwnership(expectedOwnership ) {}
415
422
416
423
// This is intended to be passed by reference only once constructed.
417
424
AvailableValueAggregator (const AvailableValueAggregator &) = delete;
@@ -435,6 +442,19 @@ class AvailableValueAggregator {
435
442
436
443
void print (llvm::raw_ostream &os) const ;
437
444
void dump () const LLVM_ATTRIBUTE_USED;
445
+
446
+ bool isTake () const {
447
+ return expectedOwnership == AvailableValueExpectedOwnership::Take;
448
+ }
449
+
450
+ bool isBorrow () const {
451
+ return expectedOwnership == AvailableValueExpectedOwnership::Borrow;
452
+ }
453
+
454
+ bool isCopy () const {
455
+ return expectedOwnership == AvailableValueExpectedOwnership::Copy;
456
+ }
457
+
438
458
private:
439
459
SILValue aggregateFullyAvailableValue (SILType loadTy, unsigned firstElt);
440
460
SILValue aggregateTupleSubElts (TupleType *tt, SILType loadTy,
@@ -526,7 +546,7 @@ SILValue AvailableValueAggregator::aggregateValues(SILType LoadTy,
526
546
bool isTopLevel) {
527
547
// If we are performing a take, make sure that we have available values for
528
548
// /all/ of our values. Otherwise, bail.
529
- if (isTopLevel && isTake && !canTake (LoadTy, FirstElt)) {
549
+ if (isTopLevel && isTake () && !canTake (LoadTy, FirstElt)) {
530
550
return SILValue ();
531
551
}
532
552
@@ -576,7 +596,7 @@ AvailableValueAggregator::aggregateFullyAvailableValue(SILType loadTy,
576
596
SILBuilderWithScope builder (insertPts[0 ], &insertedInsts);
577
597
SILLocation loc = insertPts[0 ]->getLoc ();
578
598
// If we have a take, just return the value.
579
- if (isTake)
599
+ if (isTake () )
580
600
return firstVal.getValue ();
581
601
// Otherwise, return a copy of the value.
582
602
return builder.emitCopyValueOperation (loc, firstVal.getValue ());
@@ -597,7 +617,7 @@ AvailableValueAggregator::aggregateFullyAvailableValue(SILType loadTy,
597
617
SILValue eltVal = firstVal.getValue ();
598
618
599
619
// If we are not taking, copy the element value.
600
- if (!isTake) {
620
+ if (!isTake () ) {
601
621
eltVal = builder.emitCopyValueOperation (loc, eltVal);
602
622
}
603
623
@@ -636,7 +656,7 @@ SILValue AvailableValueAggregator::aggregateTupleSubElts(TupleType *TT,
636
656
// compute an address to load from.
637
657
SILValue EltAddr;
638
658
if (anyMissing (FirstElt, NumSubElt, AvailableValueList)) {
639
- assert (!isTake && " When taking, values should never be missing?!" );
659
+ assert (!isTake () && " When taking, values should never be missing?!" );
640
660
EltAddr =
641
661
B.createTupleElementAddr (Loc, Address, EltNo, EltTy.getAddressType ());
642
662
}
@@ -663,7 +683,7 @@ SILValue AvailableValueAggregator::aggregateStructSubElts(StructDecl *sd,
663
683
// compute an address to load from.
664
684
SILValue eltAddr;
665
685
if (anyMissing (firstElt, numSubElt, AvailableValueList)) {
666
- assert (!isTake && " When taking, values should never be missing?!" );
686
+ assert (!isTake () && " When taking, values should never be missing?!" );
667
687
eltAddr =
668
688
B.createStructElementAddr (Loc, address, decl, eltTy.getAddressType ());
669
689
}
@@ -686,7 +706,7 @@ SILValue AvailableValueAggregator::handlePrimitiveValue(SILType loadTy,
686
706
687
707
// If the value is not available, load the value and update our use list.
688
708
if (!val) {
689
- assert (!isTake && " Should only take fully available values?!" );
709
+ assert (!isTake () && " Should only take fully available values?!" );
690
710
LoadInst *load = ([&]() {
691
711
if (B.hasOwnership ()) {
692
712
return B.createTrivialLoadOr (Loc, address,
@@ -1650,7 +1670,7 @@ bool AllocOptimize::promoteLoadCopy(LoadInst *li) {
1650
1670
// not available. We are "propagating" a +1 available value from the store
1651
1671
// points.
1652
1672
AvailableValueAggregator agg (li, availableValues, Uses, deadEndBlocks,
1653
- false /* isTake */ );
1673
+ AvailableValueExpectedOwnership::Copy );
1654
1674
SILValue newVal = agg.aggregateValues (loadTy, li->getOperand (), firstElt);
1655
1675
1656
1676
LLVM_DEBUG (llvm::dbgs () << " *** Promoting load: " << *li << " \n " );
@@ -1750,7 +1770,7 @@ bool AllocOptimize::promoteLoadBorrow(LoadBorrowInst *lbi) {
1750
1770
// not available. We are "propagating" a +1 available value from the store
1751
1771
// points.
1752
1772
AvailableValueAggregator agg (lbi, availableValues, Uses, deadEndBlocks,
1753
- false /* isTake */ );
1773
+ AvailableValueExpectedOwnership::Borrow );
1754
1774
SILValue newVal = agg.aggregateValues (loadTy, lbi->getOperand (), firstElt);
1755
1775
1756
1776
LLVM_DEBUG (llvm::dbgs () << " *** Promoting load: " << *lbi << " \n " );
@@ -1829,7 +1849,7 @@ bool AllocOptimize::canPromoteTake(
1829
1849
// available, we would need to split stores to promote this destroy_addr. We
1830
1850
// do not support that yet.
1831
1851
AvailableValueAggregator agg (inst, tmpList, Uses, deadEndBlocks,
1832
- true /* isTake */ );
1852
+ AvailableValueExpectedOwnership::Take );
1833
1853
if (!agg.canTake (loadTy, firstElt))
1834
1854
return false ;
1835
1855
@@ -1861,7 +1881,7 @@ void AllocOptimize::promoteDestroyAddr(
1861
1881
// type as the load did, and emit smaller) loads for any subelements that were
1862
1882
// not available.
1863
1883
AvailableValueAggregator agg (dai, availableValues, Uses, deadEndBlocks,
1864
- true /* isTake */ );
1884
+ AvailableValueExpectedOwnership::Take );
1865
1885
SILValue newVal = agg.aggregateValues (loadTy, address, firstElt);
1866
1886
1867
1887
++NumDestroyAddrPromoted;
@@ -1889,7 +1909,7 @@ void AllocOptimize::promoteLoadTake(
1889
1909
// type as the load did, and emit smaller) loads for any subelements that were
1890
1910
// not available.
1891
1911
AvailableValueAggregator agg (li, availableValues, Uses, deadEndBlocks,
1892
- true /* isTake */ );
1912
+ AvailableValueExpectedOwnership::Take );
1893
1913
SILValue newVal = agg.aggregateValues (loadTy, address, firstElt);
1894
1914
1895
1915
++NumLoadTakePromoted;
0 commit comments