@@ -93,7 +93,10 @@ struct LiveValues {
93
93
// / For lexical AllocStackInsts, that is the copy made of the borrowed value.
94
94
// / For those that are non-lexical, that is the value that was stored into the
95
95
// / storage.
96
- SILValue replacement (AllocStackInst *asi) {
96
+ SILValue replacement (AllocStackInst *asi, SILInstruction *toReplace) {
97
+ if (isa<LoadBorrowInst>(toReplace)) {
98
+ return shouldAddLexicalLifetime (asi) ? borrow : stored;
99
+ }
97
100
return shouldAddLexicalLifetime (asi) ? copy : stored;
98
101
};
99
102
};
@@ -601,22 +604,8 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
601
604
602
605
if (isLoadFromStack (inst, asi)) {
603
606
assert (!runningVals || runningVals->isStorageValid );
604
- if (auto *lbi = dyn_cast<LoadBorrowInst>(inst)) {
605
- if (runningVals) {
606
- if (shouldAddLexicalLifetime (asi)) {
607
- replaceLoad (lbi, runningVals->value .borrow , asi, ctx,
608
- deleter, instructionsToDelete);
609
- }
610
- else {
611
- replaceLoad (lbi, runningVals->value .replacement (asi), asi, ctx,
612
- deleter, instructionsToDelete);
613
- }
614
- ++NumInstRemoved;
615
- }
616
- continue ;
617
- }
618
- auto *li = cast<LoadInst>(inst);
619
- if (li->getOwnershipQualifier () == LoadOwnershipQualifier::Take) {
607
+ auto *li = dyn_cast<LoadInst>(inst);
608
+ if (li && li->getOwnershipQualifier () == LoadOwnershipQualifier::Take) {
620
609
if (shouldAddLexicalLifetime (asi)) {
621
610
// End the lexical lifetime at a load [take]. The storage is no
622
611
// longer keeping the value alive.
@@ -639,11 +628,11 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
639
628
if (runningVals) {
640
629
// If we are loading from the AllocStackInst and we already know the
641
630
// content of the Alloca then use it.
642
- LLVM_DEBUG (llvm::dbgs () << " *** Promoting load: " << *li );
643
- replaceLoad (inst, runningVals->value .replacement (asi), asi, ctx,
631
+ LLVM_DEBUG (llvm::dbgs () << " *** Promoting load: " << *inst );
632
+ replaceLoad (inst, runningVals->value .replacement (asi, inst ), asi, ctx,
644
633
deleter, instructionsToDelete);
645
634
++NumInstRemoved;
646
- } else if (li->getOperand () == asi &&
635
+ } else if (li && li ->getOperand () == asi &&
647
636
li->getOwnershipQualifier () != LoadOwnershipQualifier::Copy) {
648
637
// If we don't know the content of the AllocStack then the loaded
649
638
// value *is* the new value;
@@ -669,7 +658,7 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
669
658
if (runningVals) {
670
659
assert (runningVals->isStorageValid );
671
660
SILBuilderWithScope (si, ctx).createDestroyValue (
672
- si->getLoc (), runningVals->value .replacement (asi));
661
+ si->getLoc (), runningVals->value .replacement (asi, si ));
673
662
} else {
674
663
SILBuilderWithScope localBuilder (si, ctx);
675
664
auto *newLoad = localBuilder.createLoad (si->getLoc (), asi,
@@ -736,17 +725,17 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
736
725
// promote this when we deal with hooking up phis.
737
726
if (auto *dvi = DebugValueInst::hasAddrVal (inst)) {
738
727
if (dvi->getOperand () == asi && runningVals)
739
- promoteDebugValueAddr (dvi, runningVals->value .replacement (asi), ctx ,
740
- deleter);
728
+ promoteDebugValueAddr (dvi, runningVals->value .replacement (asi, dvi) ,
729
+ ctx, deleter);
741
730
continue ;
742
731
}
743
732
744
733
// Replace destroys with a release of the value.
745
734
if (auto *dai = dyn_cast<DestroyAddrInst>(inst)) {
746
735
if (dai->getOperand () == asi) {
747
736
if (runningVals) {
748
- replaceDestroy (dai, runningVals->value .replacement (asi), ctx, deleter ,
749
- instructionsToDelete);
737
+ replaceDestroy (dai, runningVals->value .replacement (asi, dai), ctx ,
738
+ deleter, instructionsToDelete);
750
739
if (shouldAddLexicalLifetime (asi)) {
751
740
endLexicalLifetimeBeforeInst (asi, /* beforeInstruction=*/ dai, ctx,
752
741
runningVals->value );
@@ -764,7 +753,7 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
764
753
765
754
if (auto *dvi = dyn_cast<DestroyValueInst>(inst)) {
766
755
if (runningVals &&
767
- dvi->getOperand () == runningVals->value .replacement (asi)) {
756
+ dvi->getOperand () == runningVals->value .replacement (asi, dvi )) {
768
757
// Reset LastStore.
769
758
// So that we don't end up passing dead values as phi args in
770
759
// StackAllocationPromoter::fixBranchesAndUses
@@ -928,7 +917,7 @@ void StackAllocationPromoter::fixPhiPredBlock(BlockSetVector &phiBlocks,
928
917
929
918
LiveValues def = getEffectiveLiveOutValues (phiBlocks, predBlock);
930
919
931
- LLVM_DEBUG (llvm::dbgs () << " *** Found the definition: " << def.replacement (asi) );
920
+ LLVM_DEBUG (llvm::dbgs () << " *** Found the definition: " << def.stored );
932
921
933
922
llvm::SmallVector<SILValue> vals;
934
923
vals.push_back (def.stored );
@@ -1009,10 +998,10 @@ void StackAllocationPromoter::fixBranchesAndUses(BlockSetVector &phiBlocks,
1009
998
def = getEffectiveLiveInValues (phiBlocks, loadBlock);
1010
999
1011
1000
LLVM_DEBUG (llvm::dbgs () << " *** Replacing " << *li << " with Def "
1012
- << def.replacement (asi));
1001
+ << def.replacement (asi, li ));
1013
1002
1014
1003
// Replace the load with the definition that we found.
1015
- replaceLoad (li, def.replacement (asi), asi, ctx, deleter,
1004
+ replaceLoad (li, def.replacement (asi, li ), asi, ctx, deleter,
1016
1005
instructionsToDelete);
1017
1006
removedUser = true ;
1018
1007
++NumInstRemoved;
@@ -1030,15 +1019,15 @@ void StackAllocationPromoter::fixBranchesAndUses(BlockSetVector &phiBlocks,
1030
1019
// Replace debug_value w/ address-type value with
1031
1020
// a new debug_value w/ promoted value.
1032
1021
auto def = getEffectiveLiveInValues (phiBlocks, userBlock);
1033
- promoteDebugValueAddr (dvi, def.replacement (asi), ctx, deleter);
1022
+ promoteDebugValueAddr (dvi, def.replacement (asi, dvi ), ctx, deleter);
1034
1023
++NumInstRemoved;
1035
1024
continue ;
1036
1025
}
1037
1026
1038
1027
// Replace destroys with a release of the value.
1039
1028
if (auto *dai = dyn_cast<DestroyAddrInst>(user)) {
1040
1029
auto def = getEffectiveLiveInValues (phiBlocks, userBlock);
1041
- replaceDestroy (dai, def.replacement (asi), ctx, deleter,
1030
+ replaceDestroy (dai, def.replacement (asi, dai ), ctx, deleter,
1042
1031
instructionsToDelete);
1043
1032
continue ;
1044
1033
}
@@ -1638,8 +1627,8 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
1638
1627
}
1639
1628
runningVals->isStorageValid = false ;
1640
1629
}
1641
- replaceLoad (inst, runningVals->value .replacement (asi), asi, ctx, deleter ,
1642
- instructionsToDelete);
1630
+ replaceLoad (inst, runningVals->value .replacement (asi, inst ), asi, ctx,
1631
+ deleter, instructionsToDelete);
1643
1632
++NumInstRemoved;
1644
1633
continue ;
1645
1634
}
@@ -1651,7 +1640,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
1651
1640
if (si->getOwnershipQualifier () == StoreOwnershipQualifier::Assign) {
1652
1641
assert (runningVals && runningVals->isStorageValid );
1653
1642
SILBuilderWithScope (si, ctx).createDestroyValue (
1654
- si->getLoc (), runningVals->value .replacement (asi));
1643
+ si->getLoc (), runningVals->value .replacement (asi, si ));
1655
1644
}
1656
1645
auto oldRunningVals = runningVals;
1657
1646
runningVals = {LiveValues::toReplace (asi, /* replacement=*/ si->getSrc ()),
@@ -1674,8 +1663,8 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
1674
1663
if (auto *dvi = DebugValueInst::hasAddrVal (inst)) {
1675
1664
if (dvi->getOperand () == asi) {
1676
1665
if (runningVals) {
1677
- promoteDebugValueAddr (dvi, runningVals->value .replacement (asi), ctx ,
1678
- deleter);
1666
+ promoteDebugValueAddr (dvi, runningVals->value .replacement (asi, dvi) ,
1667
+ ctx, deleter);
1679
1668
} else {
1680
1669
// Drop debug_value of uninitialized void values.
1681
1670
assert (asi->getElementType ().isVoid () &&
@@ -1690,8 +1679,8 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
1690
1679
if (auto *dai = dyn_cast<DestroyAddrInst>(inst)) {
1691
1680
if (dai->getOperand () == asi) {
1692
1681
assert (runningVals && runningVals->isStorageValid );
1693
- replaceDestroy (dai, runningVals->value .replacement (asi), ctx, deleter ,
1694
- instructionsToDelete);
1682
+ replaceDestroy (dai, runningVals->value .replacement (asi, dai), ctx ,
1683
+ deleter, instructionsToDelete);
1695
1684
if (shouldAddLexicalLifetime (asi)) {
1696
1685
endLexicalLifetimeBeforeInst (asi, /* beforeInstruction=*/ dai, ctx,
1697
1686
runningVals->value );
0 commit comments