@@ -82,225 +82,7 @@ bool swift::siloptimizer::
8282 if (!mmci || !mmci->hasMoveCheckerKind () || !mmci->getType ().isObject ())
8383 continue ;
8484
85- // Handle guaranteed/owned move arguments and values.
86- //
87- // We are pattern matching against these patterns:
88- //
89- // bb0(%0 : @guaranteed $T):
90- // %1 = copy_value %0
91- // %2 = mark_unresolved_non_copyable_value [no_consume_or_assign] %1
92- // bb0(%0 : @owned $T):
93- // %1 = mark_unresolved_non_copyable_value [no_consume_or_assign] %2
94- //
95- // This is forming a let or an argument.
96- // bb0:
97- // %1 = move_value [lexical] %0
98- // %2 = mark_unresolved_non_copyable_value [consumable_and_assignable]
99- // %1
100- //
101- // This occurs when SILGen materializes a temporary move only value?
102- // bb0:
103- // %1 = begin_borrow [lexical] %0
104- // %2 = copy_value %1
105- // %3 = mark_unresolved_non_copyable_value [no_consume_or_assign] %2
106- if (mmci->getOperand ()->getType ().isMoveOnly () &&
107- !mmci->getOperand ()->getType ().isMoveOnlyWrapped ()) {
108- if (auto *cvi = dyn_cast<CopyValueInst>(mmci->getOperand ())) {
109- if (auto *arg = dyn_cast<SILFunctionArgument>(cvi->getOperand ())) {
110- if (arg->getOwnershipKind () == OwnershipKind::Guaranteed) {
111- moveIntroducersToProcess.insert (mmci);
112- continue ;
113- }
114- }
115-
116- // In the case we have a resilient argument, we may have the following
117- // pattern:
118- //
119- // bb0(%0 : $*Type): // in_guaranteed
120- // %1 = load_borrow %0
121- // %2 = copy_value
122- // %3 = mark_unresolved_non_copyable_value [no_copy_or_assign]
123- if (auto *lbi = dyn_cast<LoadBorrowInst>(cvi->getOperand ())) {
124- if (auto *arg = dyn_cast<SILFunctionArgument>(lbi->getOperand ())) {
125- if (arg->getKnownParameterInfo ().isIndirectInGuaranteed ()) {
126- moveIntroducersToProcess.insert (mmci);
127- continue ;
128- }
129- }
130- }
131-
132- if (auto *bbi = dyn_cast<BeginBorrowInst>(cvi->getOperand ())) {
133- if (bbi->isLexical ()) {
134- moveIntroducersToProcess.insert (mmci);
135- continue ;
136- }
137- }
138- }
139-
140- // Any time we have a move_value, we can process it.
141- if (auto *mvi = dyn_cast<MoveValueInst>(mmci->getOperand ())) {
142- moveIntroducersToProcess.insert (mmci);
143- continue ;
144- }
145-
146- if (auto *arg = dyn_cast<SILFunctionArgument>(mmci->getOperand ())) {
147- if (arg->getOwnershipKind () == OwnershipKind::Owned) {
148- moveIntroducersToProcess.insert (mmci);
149- continue ;
150- }
151- }
152- }
153-
154- // Handle guaranteed arguments.
155- //
156- // We are pattern matching this pattern:
157- //
158- // bb0(%0 : @guaranteed $T):
159- // %1 = copyable_to_moveonlywrapper [guaranteed] %0
160- // %2 = copy_value %1
161- // %3 = mark_unresolved_non_copyable_value [no_consume_or_assign] %2
162- //
163- // NOTE: Unlike with owned arguments, we do not need to insert a
164- // begin_borrow lexical since the lexical value comes from the guaranteed
165- // argument itself.
166- //
167- // NOTE: When we are done checking, we will eliminate the copy_value,
168- // mark_unresolved_non_copyable_value inst to leave the IR in a guaranteed
169- // state.
170- if (auto *cvi = dyn_cast<CopyValueInst>(mmci->getOperand ())) {
171- if (auto *cvt = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(
172- cvi->getOperand ())) {
173- if (auto *arg = dyn_cast<SILFunctionArgument>(cvt->getOperand ())) {
174- if (arg->isNoImplicitCopy () &&
175- arg->getOwnershipKind () == OwnershipKind::Guaranteed) {
176- moveIntroducersToProcess.insert (mmci);
177- continue ;
178- }
179- }
180- }
181- }
182-
183- // Handle trivial arguments and values.
184- //
185- // In the instruction stream this looks like:
186- //
187- // bb0(%0 : $Trivial):
188- // %1 = copyable_to_moveonlywrapper [owned] %0
189- // %2 = move_value [lexical] %1
190- // %3 = mark_unresolved_non_copyable_value [consumable_and_assignable] %2
191- //
192- // *OR*
193- //
194- // bb0(%0 : $Trivial):
195- // %1 = copyable_to_moveonlywrapper [owned] %0
196- // %2 = move_value [lexical] %1
197- // %3 = mark_unresolved_non_copyable_value [no_consume_or_assign] %2
198- //
199- // We are relying on a structural SIL requirement that %0 has only one
200- // use, %1. This is validated by the SIL verifier. In this case, we need
201- // the move_value [lexical] to ensure that we get a lexical scope for the
202- // non-trivial value.
203- if (auto *mvi = dyn_cast<MoveValueInst>(mmci->getOperand ())) {
204- if (mvi->isLexical ()) {
205- if (auto *cvt = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(
206- mvi->getOperand ())) {
207- if (cvt->getOperand ()->getType ().isTrivial (*fn)) {
208- moveIntroducersToProcess.insert (mmci);
209- continue ;
210- }
211- }
212- }
213- }
214-
215- // Handle owned arguments.
216- //
217- // We are pattern matching this:
218- //
219- // bb0(%0 : @owned $T):
220- // %1 = copyable_to_moveonlywrapper [owned] %0
221- // %2 = move_value [lexical] %1
222- // %3 = mark_unresolved_non_copyable_value
223- // [consumable_and_assignable_owned] %2
224- if (auto *mvi = dyn_cast<MoveValueInst>(mmci->getOperand ())) {
225- if (mvi->isLexical ()) {
226- if (auto *cvt = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(
227- mvi->getOperand ())) {
228- if (auto *arg = dyn_cast<SILFunctionArgument>(cvt->getOperand ())) {
229- if (arg->isNoImplicitCopy ()) {
230- moveIntroducersToProcess.insert (mmci);
231- continue ;
232- }
233- }
234- }
235- }
236- }
237-
238- // Handle non-trivial values.
239- //
240- // We are looking for the following pattern:
241- //
242- // %1 = begin_borrow [lexical] %0
243- // %2 = copy_value %1
244- // %3 = copyable_to_moveonlywrapper [owned] %2
245- // %4 = mark_unresolved_non_copyable_value [consumable_and_assignable]
246- //
247- // Or for a move only type, we look for a move_value [lexical].
248- if (auto *mvi = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(
249- mmci->getOperand ())) {
250- if (auto *cvi = dyn_cast<CopyValueInst>(mvi->getOperand ())) {
251- if (auto *bbi = dyn_cast<BeginBorrowInst>(cvi->getOperand ())) {
252- if (bbi->isLexical ()) {
253- moveIntroducersToProcess.insert (mmci);
254- continue ;
255- }
256- }
257- }
258- }
259-
260- // Handle trivial values.
261- //
262- // We pattern match:
263- //
264- // %1 = copyable_to_moveonlywrapper [owned] %0
265- // %2 = move_value [lexical] %1
266- // %3 = mark_unresolved_non_copyable_value [consumable_and_assignable] %2
267- if (auto *cvi = dyn_cast<ExplicitCopyValueInst>(mmci->getOperand ())) {
268- if (auto *bbi = dyn_cast<BeginBorrowInst>(cvi->getOperand ())) {
269- if (bbi->isLexical ()) {
270- moveIntroducersToProcess.insert (mmci);
271- continue ;
272- }
273- }
274- }
275-
276- // Handle guaranteed parameters of a resilient type used by a resilient
277- // function inside the module in which the resilient type is defined.
278- if (auto *cvi = dyn_cast<CopyValueInst>(mmci->getOperand ())) {
279- if (auto *cmi = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(cvi->getOperand ())) {
280- if (auto *lbi = dyn_cast<LoadBorrowInst>(cmi->getOperand ())) {
281- if (auto *arg = dyn_cast<SILFunctionArgument>(lbi->getOperand ())) {
282- if (arg->getKnownParameterInfo ().isIndirectInGuaranteed ()) {
283- moveIntroducersToProcess.insert (mmci);
284- continue ;
285- }
286- }
287- }
288- }
289- }
290-
291- // If we see a mark_unresolved_non_copyable_value that is marked no
292- // implicit copy that we don't understand, emit a diagnostic to fail the
293- // compilation. This ensures that if someone marks something no implicit
294- // copy and we fail to check it, we fail the compilation.
295- //
296- // We then RAUW the mark_unresolved_non_copyable_value once we have
297- // emitted the error since later passes expect that
298- // mark_unresolved_non_copyable_value has been eliminated by us. Since we
299- // are failing already, this is ok to do.
300- emitter.emitCheckerDoesntUnderstandDiagnostic (mmci);
301- mmci->replaceAllUsesWith (mmci->getOperand ());
302- mmci->eraseFromParent ();
303- localChanged = true ;
85+ moveIntroducersToProcess.insert (mmci);
30486 }
30587 }
30688 return localChanged;
0 commit comments