@@ -39,57 +39,18 @@ bool ReborrowVerifier::verifyReborrowLifetime(SILPhiArgument *phiArg,
3939
4040void ReborrowVerifier::verifyReborrows (BorrowingOperand initialScopedOperand,
4141 SILValue value) {
42- SmallVector<std::tuple<Operand *, SILValue>, 4 > worklist;
43- // Initialize the worklist with borrow lifetime ending uses
44- initialScopedOperand.visitScopeEndingUses ([&](Operand *op) {
45- worklist.emplace_back (op, value);
46- return true ;
47- });
48-
49- while (!worklist.empty ()) {
50- Operand *borrowLifetimeEndOp;
51- SILValue baseVal;
52- std::tie (borrowLifetimeEndOp, baseVal) = worklist.pop_back_val ();
53- auto *borrowLifetimeEndUser = borrowLifetimeEndOp->getUser ();
54-
55- auto borrowingOperand = BorrowingOperand::get (borrowLifetimeEndOp);
56- if (!borrowingOperand || !borrowingOperand.isReborrow ())
57- continue ;
58-
59- if (isVisitedOp (borrowLifetimeEndOp, baseVal))
60- continue ;
61-
62- // Process reborrow
63- auto *branchInst = cast<BranchInst>(borrowLifetimeEndUser);
64- for (auto *succBlock : branchInst->getSuccessorBlocks ()) {
65- auto *phiArg = cast<SILPhiArgument>(
66- succBlock->getArgument (borrowLifetimeEndOp->getOperandNumber ()));
67- assert (phiArg->getOwnershipKind () == OwnershipKind::Guaranteed);
68-
69- SILValue newBaseVal = baseVal;
70- // If the previous base value was also passed as a phi arg, that will be
71- // the new base value.
72- for (auto *arg : succBlock->getArguments ()) {
73- if (arg->getIncomingPhiValue (branchInst->getParent ()) == baseVal) {
74- newBaseVal = arg;
75- break ;
76- }
77- }
78-
79- if (isVisitedPhiArg (phiArg, newBaseVal))
80- continue ;
81- addVisitedPhiArg (phiArg, newBaseVal);
82- verifyReborrowLifetime (phiArg, newBaseVal);
83-
84- // Find the scope ending uses of the guaranteed phi arg and add it to the
85- // worklist.
86- auto scopedValue = BorrowedValue (phiArg);
87- assert (scopedValue);
88- scopedValue.visitLocalScopeEndingUses ([&](Operand *op) {
89- addVisitedOp (op, newBaseVal);
90- worklist.emplace_back (op, newBaseVal);
91- return true ;
92- });
42+ auto visitReborrowBaseValuePair = [&](SILPhiArgument *phiArg,
43+ SILValue baseValue) {
44+ // If the (phiArg, baseValue) pair was not visited before, verify the
45+ // lifetime.
46+ auto it = reborrowToBaseValuesMap.find (phiArg);
47+ if (it == reborrowToBaseValuesMap.end () ||
48+ it->second .find (baseValue) == it->second .end ()) {
49+ reborrowToBaseValuesMap[phiArg].insert (baseValue);
50+ verifyReborrowLifetime (phiArg, baseValue);
9351 }
94- }
52+ };
53+ // For every unique reborrow/base value pair, verify the lifetime
54+ findTransitiveReborrowBaseValuePairs (initialScopedOperand, value,
55+ visitReborrowBaseValuePair);
9556}
0 commit comments