@@ -852,10 +852,11 @@ static bool tryToSinkRefCountAcrossSelectEnum(CondBranchInst *CondBr,
852
852
return true ;
853
853
}
854
854
855
- static bool tryToSinkRefCountInst (SILBasicBlock::iterator T,
856
- SILBasicBlock::iterator I,
857
- bool CanSinkToSuccessors, AliasAnalysis *AA,
858
- RCIdentityFunctionInfo *RCIA) {
855
+ static bool tryTosinkIncrementsIntoSwitchRegions (SILBasicBlock::iterator T,
856
+ SILBasicBlock::iterator I,
857
+ bool CanSinkToSuccessors,
858
+ AliasAnalysis *AA,
859
+ RCIdentityFunctionInfo *RCIA) {
859
860
// The following methods should only be attempted if we can sink to our
860
861
// successor.
861
862
if (CanSinkToSuccessors) {
@@ -874,168 +875,15 @@ static bool tryToSinkRefCountInst(SILBasicBlock::iterator T,
874
875
return true ;
875
876
}
876
877
877
- if (!isa<StrongRetainInst>(I) && !isa<RetainValueInst>(I))
878
- return false ;
879
-
880
- SILValue Ptr = I->getOperand (0 );
881
- if (auto B = valueHasARCDecrementOrCheckInInstructionRange (Ptr, std::next (I),
882
- T, AA)) {
883
- DEBUG (llvm::dbgs () << " Moving " << *I);
884
- I->moveBefore (&**B);
885
- return true ;
886
- }
887
-
888
- // Ok, we have a ref count instruction that *could* be sunk. If we have a
889
- // terminator that we cannot sink through or the cfg will not let us sink
890
- // into our predecessors, just move the increment before the terminator.
891
- if (!CanSinkToSuccessors ||
892
- (!isa<CheckedCastBranchInst>(T) && !isa<CondBranchInst>(T))) {
893
- DEBUG (llvm::dbgs () << " Moving " << *I);
894
- I->moveBefore (&*T);
895
- return true ;
896
- }
897
-
898
- // Ok, it is legal for us to sink this increment to our successors. Create a
899
- // copy of this instruction in each one of our successors unless they are
900
- // ignorable trap blocks.
901
- DEBUG (llvm::dbgs () << " Sinking " << *I);
902
- SILBuilderWithScope Builder (T, &*I);
903
- for (auto &Succ : T->getParent ()->getSuccessors ()) {
904
- SILBasicBlock *SuccBB = Succ.getBB ();
905
-
906
- if (isARCInertTrapBB (SuccBB))
907
- continue ;
908
-
909
- Builder.setInsertionPoint (&*SuccBB->begin ());
910
- if (isa<StrongRetainInst>(I)) {
911
- Builder.createStrongRetain (I->getLoc (), Ptr, Atomicity::Atomic);
912
- } else {
913
- assert (isa<RetainValueInst>(I) && " This can only be retain_value" );
914
- Builder.createRetainValue (I->getLoc (), Ptr, Atomicity::Atomic);
915
- }
916
- }
917
-
918
- // Then erase this instruction.
919
- I->eraseFromParent ();
920
- NumSunk++;
921
- return true ;
922
- }
923
-
924
- static bool isRetainAvailableInSomeButNotAllPredecessors (
925
- SILValue Ptr, SILBasicBlock *BB, AliasAnalysis *AA,
926
- RCIdentityFunctionInfo *RCIA,
927
- llvm::SmallDenseMap<SILBasicBlock *, Optional<SILInstruction *>, 4 >
928
- &CheckUpToInstruction) {
929
- bool AvailInSome = false ;
930
- bool NotAvailInSome = false ;
931
-
932
- Ptr = RCIA->getRCIdentityRoot (Ptr);
933
-
934
- // Check whether a retain on the pointer is available in the predecessors.
935
- for (auto *Pred : BB->getPreds ()) {
936
-
937
- // Find the first retain of the pointer.
938
- auto Retain = std::find_if (
939
- Pred->rbegin (), Pred->rend (), [=](const SILInstruction &I) -> bool {
940
- if (!isa<StrongRetainInst>(I) && !isa<RetainValueInst>(I))
941
- return false ;
942
-
943
- return Ptr == RCIA->getRCIdentityRoot (I.getOperand (0 ));
944
- });
945
-
946
- // Check that there is no decrement or check from the increment to the end
947
- // of the basic block. After we have hoisted the first release this release
948
- // would prevent further hoisting. Instead we check that no decrement or
949
- // check occurs up to this hoisted release.
950
- auto End = CheckUpToInstruction[Pred];
951
- auto EndIt = SILBasicBlock::iterator (End ? *End : Pred->getTerminator ());
952
- if (Retain == Pred->rend () || valueHasARCDecrementOrCheckInInstructionRange (
953
- Ptr, Retain->getIterator (), EndIt, AA)) {
954
- NotAvailInSome = true ;
955
- continue ;
956
- }
957
-
958
- // Alright, the retain is 'available' for merging with a release from a
959
- // successor block.
960
- AvailInSome = true ;
961
- }
962
-
963
- return AvailInSome && NotAvailInSome;
878
+ // At this point, this is a retain on a regular SSA value, leave it to retain
879
+ // release code motion to sink.
880
+ return false ;
964
881
}
965
882
966
- static bool hoistDecrementsToPredecessors (SILBasicBlock *BB, AliasAnalysis *AA,
967
- RCIdentityFunctionInfo *RCIA) {
968
- if (BB->getSinglePredecessor ())
969
- return false ;
970
-
971
- // Make sure we can move potential decrements to the predecessors and collect
972
- // retains we could match.
973
- for (auto *Pred : BB->getPreds ())
974
- if (!Pred->getSingleSuccessor ())
975
- return false ;
976
-
977
- bool HoistedDecrement = false ;
978
-
979
- // When we hoist a release to the predecessor block this release would block
980
- // hoisting further releases because it looks like a ARC decrement in the
981
- // predecessor block. Instead once we hoisted a release we scan only to this
982
- // release when looking for ARC decrements or checks.
983
- llvm::SmallDenseMap<SILBasicBlock *, Optional<SILInstruction *>, 4 >
984
- CheckUpToInstruction;
985
-
986
- for (auto It = BB->begin (); It != BB->end ();) {
987
- auto *Inst = &*It;
988
- ++It;
989
-
990
- if (!isa<StrongReleaseInst>(Inst) && !isa<ReleaseValueInst>(Inst))
991
- continue ;
992
-
993
- SILValue Ptr = Inst->getOperand (0 );
994
-
995
- // The pointer must be defined outside of this basic block.
996
- if (Ptr->getParentBB () == BB)
997
- continue ;
998
-
999
- // No arc use to the beginning of this block.
1000
- if (valueHasARCUsesInInstructionRange (Ptr, BB->begin (), Inst->getIterator (),
1001
- AA))
1002
- continue ;
1003
-
1004
- if (!isRetainAvailableInSomeButNotAllPredecessors (Ptr, BB, AA, RCIA,
1005
- CheckUpToInstruction))
1006
- continue ;
1007
-
1008
- // Hoist decrement to predecessors.
1009
- DEBUG (llvm::dbgs () << " Hoisting " << *Inst);
1010
- SILBuilderWithScope Builder (Inst);
1011
- for (auto *PredBB : BB->getPreds ()) {
1012
- Builder.setInsertionPoint (PredBB->getTerminator ());
1013
- SILInstruction *Release;
1014
- if (isa<StrongReleaseInst>(Inst)) {
1015
- Release =
1016
- Builder.createStrongRelease (Inst->getLoc (), Ptr, Atomicity::Atomic);
1017
- } else {
1018
- assert (isa<ReleaseValueInst>(Inst) && " This can only be retain_value" );
1019
- Release =
1020
- Builder.createReleaseValue (Inst->getLoc (), Ptr, Atomicity::Atomic);
1021
- }
1022
- // Update the last instruction to consider when looking for ARC uses or
1023
- // decrements in predecessor blocks.
1024
- if (!CheckUpToInstruction[PredBB])
1025
- CheckUpToInstruction[PredBB] = Release;
1026
- }
1027
-
1028
- Inst->eraseFromParent ();
1029
- HoistedDecrement = true ;
1030
- }
1031
-
1032
- return HoistedDecrement;
1033
- }
1034
883
// / Try sink a retain as far as possible. This is either to successor BBs,
1035
884
// / or as far down the current BB as possible
1036
- static bool sinkRefCountIncrement (SILBasicBlock *BB, AliasAnalysis *AA,
1037
- RCIdentityFunctionInfo *RCIA) {
1038
-
885
+ static bool sinkIncrementsIntoSwitchRegions (SILBasicBlock *BB, AliasAnalysis *AA,
886
+ RCIdentityFunctionInfo *RCIA) {
1039
887
// Make sure that each one of our successors only has one predecessor,
1040
888
// us.
1041
889
// If that condition is not true, we can still sink to the end of this BB,
@@ -1067,13 +915,16 @@ static bool sinkRefCountIncrement(SILBasicBlock *BB, AliasAnalysis *AA,
1067
915
// terminator, sink the ref count inst into either our successors.
1068
916
// 2. If there are such decrements, move the retain right before that
1069
917
// decrement.
1070
- Changed |= tryToSinkRefCountInst (S->getIterator (), Inst->getIterator (),
1071
- CanSinkToSuccessor, AA, RCIA);
918
+ Changed |= tryTosinkIncrementsIntoSwitchRegions (S->getIterator (),
919
+ Inst->getIterator (),
920
+ CanSinkToSuccessor,
921
+ AA, RCIA);
1072
922
}
1073
923
1074
924
// Handle the first instruction in the BB.
1075
925
Changed |=
1076
- tryToSinkRefCountInst (S->getIterator (), SI, CanSinkToSuccessor, AA, RCIA);
926
+ tryTosinkIncrementsIntoSwitchRegions (S->getIterator (), SI,
927
+ CanSinkToSuccessor, AA, RCIA);
1077
928
return Changed;
1078
929
}
1079
930
@@ -1747,12 +1598,17 @@ static bool processFunction(SILFunction *F, AliasAnalysis *AA,
1747
1598
DEBUG (llvm::dbgs () << " Attempting to move releases into "
1748
1599
" predecessors!\n " );
1749
1600
1750
- if (HoistReleases)
1601
+ // Perform a relatively local forms of retain sinking and release hoisting
1602
+ // regarding switch regions and SILargument. This are not handled by retain
1603
+ // release code motion.
1604
+ if (HoistReleases) {
1751
1605
Changed |= State.hoistDecrementsIntoSwitchRegions (AA);
1606
+ }
1752
1607
1608
+ // Sink switch related retains.
1609
+ Changed |= sinkIncrementsIntoSwitchRegions (State.getBB (), AA, RCIA);
1753
1610
Changed |= State.sinkIncrementsOutOfSwitchRegions (AA, RCIA);
1754
1611
1755
-
1756
1612
// Then attempt to sink code from predecessors. This can include retains
1757
1613
// which is why we always attempt to move releases up the CFG before sinking
1758
1614
// code from predecessors. We will never sink the hoisted releases from
@@ -1768,15 +1624,6 @@ static bool processFunction(SILFunction *F, AliasAnalysis *AA,
1768
1624
// Then perform the dataflow.
1769
1625
DEBUG (llvm::dbgs () << " Performing the dataflow!\n " );
1770
1626
Changed |= State.process ();
1771
-
1772
- // Finally we try to sink retain instructions from this BB to the next BB.
1773
- if (!DisableSILRRCodeMotion)
1774
- Changed |= sinkRefCountIncrement (State.getBB (), AA, RCIA);
1775
-
1776
- // And hoist decrements to predecessors. This is beneficial if we can then
1777
- // match them up with an increment in some of the predecessors.
1778
- if (!DisableSILRRCodeMotion && HoistReleases)
1779
- Changed |= hoistDecrementsToPredecessors (State.getBB (), AA, RCIA);
1780
1627
}
1781
1628
1782
1629
return Changed;
0 commit comments