@@ -882,12 +882,41 @@ void SILInstruction::verifyOperandOwnership() const {
882882 }
883883}
884884
885+ static void verifySILValueHelper (const SILFunction *f, SILValue value,
886+ DeadEndBlocks *deadEndBlocks) {
887+ assert (!isa<SILUndef>(value) &&
888+ " We assume we are always passed arguments or instruction results" );
889+
890+ // If the given function has unqualified ownership or we have been asked by
891+ // the user not to verify this function, there is nothing to verify.
892+ if (!f->hasOwnership () || !f->shouldVerifyOwnership ())
893+ return ;
894+
895+ using BehaviorKind = LinearLifetimeChecker::ErrorBehaviorKind;
896+ Optional<LinearLifetimeChecker::ErrorBuilder> errorBuilder;
897+ if (IsSILOwnershipVerifierTestingEnabled) {
898+ errorBuilder.emplace (*f, BehaviorKind::PrintMessageAndReturnFalse);
899+ } else {
900+ errorBuilder.emplace (*f, BehaviorKind::PrintMessageAndAssert);
901+ }
902+
903+ SmallPtrSet<SILBasicBlock *, 32 > liveBlocks;
904+ if (deadEndBlocks) {
905+ SILValueOwnershipChecker (*deadEndBlocks, value, *errorBuilder, liveBlocks)
906+ .check ();
907+ } else {
908+ DeadEndBlocks deadEndBlocks (f);
909+ SILValueOwnershipChecker (deadEndBlocks, value, *errorBuilder, liveBlocks)
910+ .check ();
911+ }
912+ }
913+
885914void SILValue::verifyOwnership (DeadEndBlocks *deadEndBlocks) const {
886915 if (DisableOwnershipVerification)
887916 return ;
888917
889918 // Do not validate SILUndef values.
890- if (isa<SILUndef>(Value ))
919+ if (isa<SILUndef>(* this ))
891920 return ;
892921
893922#ifdef NDEBUG
@@ -898,8 +927,8 @@ void SILValue::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
898927 // that if we run into something that we do not understand, we do not assert
899928 // in user code even tohugh we aren't going to actually verify (the default
900929 // behavior when -sil-verify-all is disabled).
901- auto *Mod = Value->getModule ();
902- if (!Mod || !Mod ->getOptions ().VerifyAll )
930+ auto *mod = Value->getModule ();
931+ if (!mod || !mod ->getOptions ().VerifyAll )
903932 return ;
904933#endif
905934
@@ -911,31 +940,51 @@ void SILValue::verifyOwnership(DeadEndBlocks *deadEndBlocks) const {
911940 }
912941 }
913942
943+ // If we are testing the verifier, bail so we only print errors once when
944+ // performing a full verification a function at a time by the
945+ // OwnershipVerifierStateDumper pass, instead of additionally in the
946+ // SILBuilder and in the actual SIL verifier that may be run by sil-opt.
947+ if (IsSILOwnershipVerifierTestingEnabled)
948+ return ;
949+
914950 // Since we do not have SILUndef, we now know that getFunction() should return
915951 // a real function. Assert in case this assumption is no longer true.
916- SILFunction *f = (*this )->getFunction ();
952+ auto *f = (*this )->getFunction ();
917953 assert (f && " Instructions and arguments should have a function" );
954+ verifySILValueHelper (f, *this , deadEndBlocks);
955+ }
956+
957+ void SILFunction::verifyOwnership (DeadEndBlocks *deadEndBlocks) const {
958+ if (DisableOwnershipVerification)
959+ return ;
960+
961+ #ifdef NDEBUG
962+ // When compiling without asserts enabled, only verify ownership if
963+ // -sil-verify-all is set.
964+ //
965+ // NOTE: We purposely return if we do can not look up a module here to ensure
966+ // that if we run into something that we do not understand, we do not assert
967+ // in user code even tohugh we aren't going to actually verify (the default
968+ // behavior when -sil-verify-all is disabled).
969+ auto *mod = getParent ();
970+ if (!mod || !mod->getOptions ().VerifyAll )
971+ return ;
972+ #endif
918973
919974 // If the given function has unqualified ownership or we have been asked by
920975 // the user not to verify this function, there is nothing to verify.
921- if (!f-> hasOwnership () || !f-> shouldVerifyOwnership ())
976+ if (!hasOwnership () || !shouldVerifyOwnership ())
922977 return ;
923978
924- using BehaviorKind = LinearLifetimeChecker::ErrorBehaviorKind;
925- Optional<LinearLifetimeChecker::ErrorBuilder> errorBuilder;
926- if (IsSILOwnershipVerifierTestingEnabled) {
927- errorBuilder.emplace (*f, BehaviorKind::PrintMessageAndReturnFalse);
928- } else {
929- errorBuilder.emplace (*f, BehaviorKind::PrintMessageAndAssert);
930- }
979+ for (auto &block : *this ) {
980+ for (auto *arg : block.getArguments ()) {
981+ verifySILValueHelper (this , arg, deadEndBlocks);
982+ }
931983
932- SmallPtrSet<SILBasicBlock *, 32 > liveBlocks;
933- if (deadEndBlocks) {
934- SILValueOwnershipChecker (*deadEndBlocks, *this , *errorBuilder, liveBlocks)
935- .check ();
936- } else {
937- DeadEndBlocks deadEndBlocks (f);
938- SILValueOwnershipChecker (deadEndBlocks, *this , *errorBuilder, liveBlocks)
939- .check ();
984+ for (auto &inst : block) {
985+ for (auto result : inst.getResults ()) {
986+ verifySILValueHelper (this , result, deadEndBlocks);
987+ }
988+ }
940989 }
941990}
0 commit comments