@@ -482,7 +482,6 @@ static bool upwardScanForInit(SILInstruction *inst, UseState &useState) {
482
482
namespace {
483
483
484
484
struct MoveKillsCopyableAddressesObjectChecker {
485
- SmallSetVector<SILValue, 32 > addressesToCheck;
486
485
SILFunction *fn;
487
486
UseState useState;
488
487
llvm::DenseMap<SILBasicBlock *, SILInstruction *> useBlocks;
@@ -496,7 +495,7 @@ struct MoveKillsCopyableAddressesObjectChecker {
496
495
bool performSingleBasicBlockAnalysisForAllMarkMoves (SILValue address);
497
496
bool performGlobalDataflow (SILValue address);
498
497
499
- bool check ();
498
+ bool check (SILValue address );
500
499
501
500
void emitDiagnosticForMove (SILValue borrowedValue,
502
501
StringRef borrowedValueName, MoveValueInst *mvi);
@@ -850,130 +849,112 @@ bool MoveKillsCopyableAddressesObjectChecker::performGlobalDataflow(
850
849
return madeChange;
851
850
}
852
851
853
- bool MoveKillsCopyableAddressesObjectChecker::check () {
854
- if (addressesToCheck.empty ())
852
+ bool MoveKillsCopyableAddressesObjectChecker::check (SILValue address) {
853
+ auto accessPathWithBase = AccessPathWithBase::compute (address);
854
+ auto accessPath = accessPathWithBase.accessPath ;
855
+
856
+ // Bail on an invalid AccessPath.
857
+ //
858
+ // AccessPath completeness is verified independently--it may be invalid in
859
+ // extraordinary situations. When AccessPath is valid, we know all its uses
860
+ // are recognizable.
861
+ //
862
+ // NOTE: If due to an invalid access path we fail here, we will just error
863
+ // on the _move since the _move would not have been handled.
864
+ if (!accessPath.isValid ())
855
865
return false ;
856
866
857
- LLVM_DEBUG (llvm::dbgs () << " Visiting Function: " << fn->getName () << " \n " );
858
- auto addressToProcess =
859
- llvm::makeArrayRef (addressesToCheck.begin (), addressesToCheck.end ());
860
-
861
- bool madeChange = false ;
862
-
863
- while (!addressToProcess.empty ()) {
864
- auto address = addressToProcess.front ();
865
- addressToProcess = addressToProcess.drop_front (1 );
866
- LLVM_DEBUG (llvm::dbgs () << " Visiting: " << *address);
867
-
868
- auto accessPathWithBase = AccessPathWithBase::compute (address);
869
- auto accessPath = accessPathWithBase.accessPath ;
870
-
871
- // Bail on an invalid AccessPath.
872
- //
873
- // AccessPath completeness is verified independently--it may be invalid in
874
- // extraordinary situations. When AccessPath is valid, we know all its uses
875
- // are recognizable.
876
- //
877
- // NOTE: If due to an invalid access path we fail here, we will just error
878
- // on the _move since the _move would not have been handled.
879
- if (!accessPath.isValid ())
880
- continue ;
881
-
882
- GatherLexicalLifetimeUseVisitor visitor (useState);
883
- SWIFT_DEFER { visitor.clear (); };
884
- visitor.reset (address);
885
- if (!visitAccessPathUses (visitor, accessPath, fn))
886
- continue ;
867
+ GatherLexicalLifetimeUseVisitor visitor (useState);
868
+ SWIFT_DEFER { visitor.clear (); };
869
+ visitor.reset (address);
870
+ if (!visitAccessPathUses (visitor, accessPath, fn))
871
+ return false ;
887
872
888
- // See if our base address is an inout. If we found any moves, add as a
889
- // liveness use all function terminators.
890
- if (auto *fArg = dyn_cast<SILFunctionArgument>(address)) {
891
- if (fArg ->hasConvention (SILArgumentConvention::Indirect_Inout)) {
892
- if (visitor.useState .markMoves .size ()) {
893
- SmallVector<SILBasicBlock *, 2 > exitingBlocks;
894
- fn->findExitingBlocks (exitingBlocks);
895
- for (auto *block : exitingBlocks) {
896
- visitor.useState .livenessUses .insert (block->getTerminator ());
897
- }
873
+ // See if our base address is an inout. If we found any moves, add as a
874
+ // liveness use all function terminators.
875
+ if (auto *fArg = dyn_cast<SILFunctionArgument>(address)) {
876
+ if (fArg ->hasConvention (SILArgumentConvention::Indirect_Inout)) {
877
+ if (visitor.useState .markMoves .size ()) {
878
+ SmallVector<SILBasicBlock *, 2 > exitingBlocks;
879
+ fn->findExitingBlocks (exitingBlocks);
880
+ for (auto *block : exitingBlocks) {
881
+ visitor.useState .livenessUses .insert (block->getTerminator ());
898
882
}
899
883
}
900
884
}
885
+ }
901
886
902
- // Now initialize our data structures.
903
- SWIFT_DEFER {
904
- useBlocks.clear ();
905
- initBlocks.clear ();
906
- destroyBlocks.clear ();
907
- reinitBlocks.clear ();
908
- markMovesToDataflow.clear ();
909
- };
910
-
911
- // Perform the single basic block analysis emitting a diagnostic/pairing
912
- // mark_unresolved_move_addr and destroys if needed. If we discover a
913
- // mark_move that propagates its state out of the current block, this
914
- // routine also prepares the pass for running the multi-basic block
915
- // diagnostic.
916
- if (performSingleBasicBlockAnalysisForAllMarkMoves (address)) {
917
- LLVM_DEBUG (llvm::dbgs () << " Performed single block analysis!\n " );
918
- madeChange = true ;
919
- continue ;
920
- }
887
+ // Now initialize our data structures.
888
+ SWIFT_DEFER {
889
+ useBlocks.clear ();
890
+ initBlocks.clear ();
891
+ destroyBlocks.clear ();
892
+ reinitBlocks.clear ();
893
+ markMovesToDataflow.clear ();
894
+ };
921
895
922
- // Go through all init uses and if we don't see any other of our uses, then
923
- // mark this as an "init block".
924
- for (auto *init : useState.inits ) {
925
- if (upwardScanForInit (init, useState)) {
926
- LLVM_DEBUG (llvm::dbgs () << " Found use block at: " << *init);
927
- initBlocks.insert (init->getParent ());
928
- }
896
+ // Perform the single basic block analysis emitting a diagnostic/pairing
897
+ // mark_unresolved_move_addr and destroys if needed. If we discover a
898
+ // mark_move that propagates its state out of the current block, this
899
+ // routine also prepares the pass for running the multi-basic block
900
+ // diagnostic.
901
+ if (performSingleBasicBlockAnalysisForAllMarkMoves (address)) {
902
+ LLVM_DEBUG (llvm::dbgs () << " Performed single block analysis!\n " );
903
+ return true ;
904
+ }
905
+
906
+ // Go through all init uses and if we don't see any other of our uses, then
907
+ // mark this as an "init block".
908
+ for (auto *init : useState.inits ) {
909
+ if (upwardScanForInit (init, useState)) {
910
+ LLVM_DEBUG (llvm::dbgs () << " Found use block at: " << *init);
911
+ initBlocks.insert (init->getParent ());
929
912
}
913
+ }
930
914
931
- // Then go through all normal uses and do upwardScanForUseOut.
932
- for (auto *user : useState.livenessUses ) {
933
- if (upwardScanForUseOut (user, useState)) {
934
- LLVM_DEBUG (llvm::dbgs () << " Found liveness block at: " << *user);
935
- useBlocks[user->getParent ()] = user;
936
- }
915
+ // Then go through all normal uses and do upwardScanForUseOut.
916
+ for (auto *user : useState.livenessUses ) {
917
+ if (upwardScanForUseOut (user, useState)) {
918
+ LLVM_DEBUG (llvm::dbgs () << " Found liveness block at: " << *user);
919
+ useBlocks[user->getParent ()] = user;
937
920
}
921
+ }
938
922
939
- for (auto destroyOpt : useState.destroys ) {
940
- // Any destroys we eliminated when processing single basic blocks will be
941
- // nullptr. Skip them!
942
- if (!destroyOpt)
943
- continue ;
923
+ for (auto destroyOpt : useState.destroys ) {
924
+ // Any destroys we eliminated when processing single basic blocks will be
925
+ // nullptr. Skip them!
926
+ if (!destroyOpt)
927
+ continue ;
944
928
945
- auto *destroy = *destroyOpt;
929
+ auto *destroy = *destroyOpt;
946
930
947
- auto iter = useState.destroyToIndexMap .find (destroy);
948
- assert (iter != useState.destroyToIndexMap .end ());
931
+ auto iter = useState.destroyToIndexMap .find (destroy);
932
+ assert (iter != useState.destroyToIndexMap .end ());
949
933
950
- if (upwardScanForDestroys (destroy, useState)) {
951
- LLVM_DEBUG (llvm::dbgs () << " Found destroy block at: " << *destroy);
952
- destroyBlocks[destroy->getParent ()] = destroy;
953
- }
934
+ if (upwardScanForDestroys (destroy, useState)) {
935
+ LLVM_DEBUG (llvm::dbgs () << " Found destroy block at: " << *destroy);
936
+ destroyBlocks[destroy->getParent ()] = destroy;
954
937
}
938
+ }
955
939
956
- for (auto reinitOpt : useState.reinits ) {
957
- // Any destroys we eliminated when processing single basic blocks will be
958
- // nullptr. Skip them!
959
- if (!reinitOpt)
960
- continue ;
940
+ for (auto reinitOpt : useState.reinits ) {
941
+ // Any destroys we eliminated when processing single basic blocks will be
942
+ // nullptr. Skip them!
943
+ if (!reinitOpt)
944
+ continue ;
961
945
962
- auto *reinit = *reinitOpt;
963
- auto iter = useState.reinitToIndexMap .find (reinit);
964
- assert (iter != useState.reinitToIndexMap .end ());
946
+ auto *reinit = *reinitOpt;
947
+ auto iter = useState.reinitToIndexMap .find (reinit);
948
+ assert (iter != useState.reinitToIndexMap .end ());
965
949
966
- if (upwardScanForDestroys (reinit, useState)) {
967
- LLVM_DEBUG (llvm::dbgs () << " Found reinit block at: " << *reinit);
968
- reinitBlocks[reinit->getParent ()] = reinit;
969
- }
950
+ if (upwardScanForDestroys (reinit, useState)) {
951
+ LLVM_DEBUG (llvm::dbgs () << " Found reinit block at: " << *reinit);
952
+ reinitBlocks[reinit->getParent ()] = reinit;
970
953
}
971
-
972
- // Ok, we are setup. Perform the global dataflow!
973
- madeChange |= performGlobalDataflow (address);
974
954
}
975
955
976
- return madeChange;
956
+ // Ok, we are setup. Perform the global dataflow!
957
+ return performGlobalDataflow (address);
977
958
}
978
959
979
960
// ===----------------------------------------------------------------------===//
@@ -991,18 +972,16 @@ class MoveKillsCopyableAddressesCheckerPass : public SILFunctionTransform {
991
972
if (getFunction ()->wasDeserializedCanonical ())
992
973
return ;
993
974
994
- bool madeChange = false ;
995
-
996
975
assert (fn->getModule ().getStage () == SILStage::Raw &&
997
976
" Should only run on Raw SIL" );
998
977
999
- MoveKillsCopyableAddressesObjectChecker checker ( getFunction ()) ;
978
+ SmallSetVector<SILValue, 32 > addressesToCheck ;
1000
979
1001
980
for (auto *arg : fn->front ().getSILFunctionArguments ()) {
1002
981
if (arg->getType ().isAddress () &&
1003
982
(arg->hasConvention (SILArgumentConvention::Indirect_In) ||
1004
983
arg->hasConvention (SILArgumentConvention::Indirect_Inout)))
1005
- checker. addressesToCheck .insert (arg);
984
+ addressesToCheck.insert (arg);
1006
985
}
1007
986
1008
987
for (auto &block : *fn) {
@@ -1014,14 +993,26 @@ class MoveKillsCopyableAddressesCheckerPass : public SILFunctionTransform {
1014
993
// Only check lexical alloc_stack that were not emitted as vars.
1015
994
if (asi->isLexical ()) {
1016
995
LLVM_DEBUG (llvm::dbgs () << " Found lexical alloc_stack: " << *asi);
1017
- checker. addressesToCheck .insert (asi);
996
+ addressesToCheck.insert (asi);
1018
997
continue ;
1019
998
}
1020
999
}
1021
1000
}
1022
1001
}
1023
1002
1024
- madeChange |= checker.check ();
1003
+ LLVM_DEBUG (llvm::dbgs () << " Visiting Function: " << fn->getName () << " \n " );
1004
+ auto addressToProcess =
1005
+ llvm::makeArrayRef (addressesToCheck.begin (), addressesToCheck.end ());
1006
+
1007
+ MoveKillsCopyableAddressesObjectChecker checker (getFunction ());
1008
+ bool madeChange = false ;
1009
+
1010
+ while (!addressToProcess.empty ()) {
1011
+ auto address = addressToProcess.front ();
1012
+ addressToProcess = addressToProcess.drop_front (1 );
1013
+ LLVM_DEBUG (llvm::dbgs () << " Visiting: " << *address);
1014
+ madeChange |= checker.check (address);
1015
+ }
1025
1016
1026
1017
if (madeChange) {
1027
1018
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
0 commit comments