@@ -236,7 +236,30 @@ class InstructionVisitor : public SILCloner<InstructionVisitor> {
236236 Cloned->eraseFromParent ();
237237 }
238238
239- SILValue getMappedValue (SILValue Value) { return Value; }
239+ // This method retrieves the operand passed as \p Value as mapped
240+ // in a previous instruction.
241+ SILValue getMappedValue (SILValue Value) {
242+ switch (mode) {
243+ case VisitMode::DetectSerializableInst:
244+ // Typically, the type of the operand (\p Value) is already checked
245+ // and remapped as the resulting type of a previous instruction, so
246+ // rechecking the type isn't necessary. However, certain instructions
247+ // have operands that weren’t previously mapped, such as:
248+ //
249+ // ```
250+ // bb0(%0 : $*Foo):
251+ // %1 = struct_element_addr %0 : $*Foo, #Foo.bar
252+ // ```
253+ // where the operand of the first instruction is the argument of the
254+ // basic block. In such case, an explicit check for the operand's type
255+ // is required to ensure serializability.
256+ remapType (Value->getType ());
257+ break ;
258+ case VisitMode::SerializeInst:
259+ break ;
260+ }
261+ return Value;
262+ }
240263
241264 SILBasicBlock *remapBasicBlock (SILBasicBlock *BB) { return BB; }
242265
@@ -493,27 +516,17 @@ bool CrossModuleOptimization::canSerializeFunction(
493516
494517 // Check if any instruction prevents serializing the function.
495518 InstructionVisitor visitor (*function, *this , InstructionVisitor::VisitMode::DetectSerializableInst);
519+
496520 for (SILBasicBlock &block : *function) {
497521 for (SILInstruction &inst : block) {
498522 visitor.getBuilder ().setInsertionPoint (&inst);
499- // First, visit each instruction and see if its result
500- // types (lowered) are serializalbe.
523+ // First, visit each instruction and see if its
524+ // canonical or substituted types are serializalbe.
501525 visitor.visit (&inst);
502526 if (!visitor.canSerializeTypesInInst (&inst)) {
503527 M.reclaimUnresolvedLocalArchetypeDefinitions ();
504528 return false ;
505529 }
506-
507- // Next, check operand types (lowered) for serializability
508- // as they are not tracked in the visit above.
509- for (Operand &op : inst.getAllOperands ()) {
510- auto remapped = visitor.remapType (op.get ()->getType ());
511- if (!canSerializeType (remapped)) {
512- M.reclaimUnresolvedLocalArchetypeDefinitions ();
513- return false ;
514- }
515- }
516-
517530 // Next, check for any fields that weren't visited.
518531 if (!canSerializeFieldsByInstructionKind (&inst, canSerializeFlags, maxDepth)) {
519532 M.reclaimUnresolvedLocalArchetypeDefinitions ();
0 commit comments