@@ -236,7 +236,30 @@ class InstructionVisitor : public SILCloner<InstructionVisitor> {
236
236
Cloned->eraseFromParent ();
237
237
}
238
238
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
+ }
240
263
241
264
SILBasicBlock *remapBasicBlock (SILBasicBlock *BB) { return BB; }
242
265
@@ -493,27 +516,17 @@ bool CrossModuleOptimization::canSerializeFunction(
493
516
494
517
// Check if any instruction prevents serializing the function.
495
518
InstructionVisitor visitor (*function, *this , InstructionVisitor::VisitMode::DetectSerializableInst);
519
+
496
520
for (SILBasicBlock &block : *function) {
497
521
for (SILInstruction &inst : block) {
498
522
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.
501
525
visitor.visit (&inst);
502
526
if (!visitor.canSerializeTypesInInst (&inst)) {
503
527
M.reclaimUnresolvedLocalArchetypeDefinitions ();
504
528
return false ;
505
529
}
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
-
517
530
// Next, check for any fields that weren't visited.
518
531
if (!canSerializeFieldsByInstructionKind (&inst, canSerializeFlags, maxDepth)) {
519
532
M.reclaimUnresolvedLocalArchetypeDefinitions ();
0 commit comments