Skip to content

Commit 1a22cd5

Browse files
committed
[ownership] Refactor out def-use compatibility checking out of gatherUsers() into a helper method.
This together with Operand::isConsumingUse() allows me to completely hide OperandOwnershipKindMap from the main flow of the algorithm which makes it easier to understand.
1 parent 7840069 commit 1a22cd5

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

lib/SIL/SILOwnershipVerifier.cpp

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ class SILValueOwnershipChecker {
127127

128128
private:
129129
bool checkUses();
130+
bool isCompatibleDefUse(Operand *op, ValueOwnershipKind ownershipKind,
131+
bool isGuaranteed);
132+
130133
bool gatherUsers(SmallVectorImpl<Operand *> &lifetimeEndingUsers,
131134
SmallVectorImpl<Operand *> &regularUsers,
132135
SmallVectorImpl<Operand *> &implicitRegularUsers);
@@ -184,6 +187,49 @@ bool SILValueOwnershipChecker::check() {
184187
return result.getValue();
185188
}
186189

190+
bool SILValueOwnershipChecker::isCompatibleDefUse(
191+
Operand *op, ValueOwnershipKind ownershipKind, bool isGuaranteed) {
192+
bool isGuaranteedSubValue = false;
193+
if (isGuaranteed && isGuaranteedForwardingInst(op->getUser())) {
194+
isGuaranteedSubValue = true;
195+
}
196+
auto *user = op->getUser();
197+
auto opOwnershipKindMap = op->getOwnershipKindMap(isGuaranteedSubValue);
198+
// If our ownership kind doesn't match, track that we found an error, emit
199+
// an error message optionally and then continue.
200+
if (opOwnershipKindMap.canAcceptKind(ownershipKind)) {
201+
return true;
202+
}
203+
204+
// If we did not support /any/ ownership kind, it means that we found a
205+
// conflicting answer so the kind map that was returned is the empty
206+
// map. Put out a more specific error here.
207+
if (!opOwnershipKindMap.data.any()) {
208+
handleError([&]() {
209+
llvm::errs() << "Function: '" << user->getFunction()->getName() << "'\n"
210+
<< "Ill-formed SIL! Unable to compute ownership kind "
211+
"map for user?!\n"
212+
<< "For terminator users, check that successors have "
213+
"compatible ownership kinds.\n"
214+
<< "Value: " << op->get() << "User: " << *user
215+
<< "Operand Number: " << op->getOperandNumber() << '\n'
216+
<< "Conv: " << ownershipKind << "\n\n";
217+
});
218+
return false;
219+
}
220+
221+
handleError([&]() {
222+
llvm::errs() << "Function: '" << user->getFunction()->getName() << "'\n"
223+
<< "Have operand with incompatible ownership?!\n"
224+
<< "Value: " << op->get() << "User: " << *user
225+
<< "Operand Number: " << op->getOperandNumber() << '\n'
226+
<< "Conv: " << ownershipKind << '\n'
227+
<< "OwnershipMap:\n"
228+
<< opOwnershipKindMap << '\n';
229+
});
230+
return false;
231+
}
232+
187233
bool SILValueOwnershipChecker::gatherUsers(
188234
SmallVectorImpl<Operand *> &lifetimeEndingUsers,
189235
SmallVectorImpl<Operand *> &nonLifetimeEndingUsers,
@@ -214,50 +260,15 @@ bool SILValueOwnershipChecker::gatherUsers(
214260
if (user->isTypeDependentOperand(*op))
215261
continue;
216262

217-
bool isGuaranteedSubValue = false;
218-
if (isGuaranteed && isGuaranteedForwardingInst(op->getUser())) {
219-
isGuaranteedSubValue = true;
220-
}
221-
222-
auto opOwnershipKindMap = op->getOwnershipKindMap(isGuaranteedSubValue);
223-
// If our ownership kind doesn't match, track that we found an error, emit
224-
// an error message optionally and then continue.
225-
if (!opOwnershipKindMap.canAcceptKind(ownershipKind)) {
263+
// First check if this recursive use is compatible with our values ownership
264+
// kind. If not, flag the error and continue so that we can report more
265+
// errors.
266+
if (!isCompatibleDefUse(op, ownershipKind, isGuaranteed)) {
226267
foundError = true;
227-
228-
// If we did not support /any/ ownership kind, it means that we found a
229-
// conflicting answer so the kind map that was returned is the empty
230-
// map. Put out a more specific error here.
231-
if (!opOwnershipKindMap.data.any()) {
232-
handleError([&]() {
233-
llvm::errs() << "Function: '" << user->getFunction()->getName()
234-
<< "'\n"
235-
<< "Ill-formed SIL! Unable to compute ownership kind "
236-
"map for user?!\n"
237-
<< "For terminator users, check that successors have "
238-
"compatible ownership kinds.\n"
239-
<< "Value: " << op->get() << "User: " << *user
240-
<< "Operand Number: " << op->getOperandNumber() << '\n'
241-
<< "Conv: " << ownershipKind << "\n\n";
242-
});
243-
continue;
244-
}
245-
246-
handleError([&]() {
247-
llvm::errs() << "Function: '" << user->getFunction()->getName() << "'\n"
248-
<< "Have operand with incompatible ownership?!\n"
249-
<< "Value: " << op->get() << "User: " << *user
250-
<< "Operand Number: " << op->getOperandNumber() << '\n'
251-
<< "Conv: " << ownershipKind << '\n'
252-
<< "OwnershipMap:\n"
253-
<< opOwnershipKindMap << '\n';
254-
});
255268
continue;
256269
}
257270

258-
auto lifetimeConstraint =
259-
opOwnershipKindMap.getLifetimeConstraint(ownershipKind);
260-
if (lifetimeConstraint == UseLifetimeConstraint::MustBeInvalidated) {
271+
if (op->isConsumingUse()) {
261272
LLVM_DEBUG(llvm::dbgs() << " Lifetime Ending User: " << *user);
262273
lifetimeEndingUsers.push_back(op);
263274
} else {

0 commit comments

Comments
 (0)