@@ -39,57 +39,18 @@ bool ReborrowVerifier::verifyReborrowLifetime(SILPhiArgument *phiArg,
39
39
40
40
void ReborrowVerifier::verifyReborrows (BorrowingOperand initialScopedOperand,
41
41
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);
93
51
}
94
- }
52
+ };
53
+ // For every unique reborrow/base value pair, verify the lifetime
54
+ findTransitiveReborrowBaseValuePairs (initialScopedOperand, value,
55
+ visitReborrowBaseValuePair);
95
56
}
0 commit comments