@@ -298,45 +298,55 @@ bool SILMoveOnlyWrappedTypeEliminator::process() {
298298 llvm::SmallSetVector<SILArgument *, 8 > touchedArgs;
299299 llvm::SmallSetVector<SILInstruction *, 8 > touchedInsts;
300300
301+ // For each value whose type is move-only wrapped:
302+ // - rewrite the value's type
303+ // - record its users for later visitation
304+ auto visitValue = [&touchedInsts, fn = fn,
305+ trivialOnly = trivialOnly](SILValue value) -> bool {
306+ if (!value->getType ().hasAnyMoveOnlyWrapping (fn))
307+ return false ;
308+
309+ // If we are looking at trivial only, skip non-trivial function args.
310+ if (trivialOnly && !isMoveOnlyWrappedTrivial (value))
311+ return false ;
312+
313+ for (auto *use : value->getNonTypeDependentUses ())
314+ touchedInsts.insert (use->getUser ());
315+
316+ value->unsafelyEliminateMoveOnlyWrapper (fn);
317+
318+ return true ;
319+ };
320+
301321 for (auto &bb : *fn) {
302322 for (auto *arg : bb.getArguments ()) {
303- if (!arg->getType ().hasAnyMoveOnlyWrapping (fn))
323+ bool relevant = visitValue (arg);
324+ if (!relevant)
304325 continue ;
305326
306- // If we are looking at trivial only, skip non-trivial function args.
307- if (trivialOnly &&
308- !arg->getType ().removingMoveOnlyWrapper ().isTrivial (*fn))
309- continue ;
310-
311- arg->unsafelyEliminateMoveOnlyWrapper (fn);
312-
313327 // If our new type is trivial, convert the arguments ownership to
314328 // None. Otherwise, preserve the ownership kind of the argument.
315329 if (arg->getType ().isTrivial (*fn))
316330 arg->setOwnershipKind (OwnershipKind::None);
317331 touchedArgs.insert (arg);
318- for ( auto *use : arg-> getNonTypeDependentUses ())
319- touchedInsts. insert (use-> getUser ()) ;
332+
333+ madeChange = true ;
320334 }
321335
322336 for (auto &ii : bb) {
323- for (SILValue v : ii.getResults ()) {
324- if (!v->getType ().hasAnyMoveOnlyWrapping (fn))
325- continue ;
326-
327- if (trivialOnly &&
328- !isMoveOnlyWrappedTrivial (v))
337+ bool touched = false ;
338+ for (SILValue value : ii.getResults ()) {
339+ bool relevant = visitValue (value);
340+ if (!relevant)
329341 continue ;
330342
331- v->unsafelyEliminateMoveOnlyWrapper (fn);
332- touchedInsts.insert (&ii);
333-
334- // Add all users as well. This ensures we visit things like
335- // destroy_value and end_borrow.
336- for (auto *use : v->getNonTypeDependentUses ())
337- touchedInsts.insert (use->getUser ());
338- madeChange = true ;
343+ touched = true ;
339344 }
345+ if (!touched)
346+ continue ;
347+ touchedInsts.insert (&ii);
348+
349+ madeChange = true ;
340350 }
341351 }
342352
0 commit comments