@@ -145,12 +145,30 @@ struct UseDefChainVisitor
145145 case ProjectionKind::Tuple: {
146146 // These are merges if we have multiple fields.
147147 auto *tti = cast<TupleElementAddrInst>(inst);
148+
149+ // See if our result type is a sendable type. In such a case, we do not
150+ // want to look through the tuple_element_addr since we do not want to
151+ // identify the sendable type with the non-sendable operand. These we
152+ // are always going to ignore anyways since a sendable let/var field of
153+ // a struct can always be used.
154+ if (!isNonSendableType (tti->getType (), tti->getFunction ()))
155+ return SILValue ();
156+
148157 isMerge |= tti->getOperand ()->getType ().getNumTupleElements () > 1 ;
149158 break ;
150159 }
151160 case ProjectionKind::Struct:
152- // These are merges if we have multiple fields.
153161 auto *sea = cast<StructElementAddrInst>(inst);
162+
163+ // See if our result type is a sendable type. In such a case, we do not
164+ // want to look through the struct_element_addr since we do not want to
165+ // identify the sendable type with the non-sendable operand. These we
166+ // are always going to ignore anyways since a sendable let/var field of
167+ // a struct can always be used.
168+ if (!isNonSendableType (sea->getType (), sea->getFunction ()))
169+ return SILValue ();
170+
171+ // These are merges if we have multiple fields.
154172 isMerge |= sea->getOperand ()->getType ().getNumNominalFields () > 1 ;
155173 break ;
156174 }
@@ -1147,13 +1165,21 @@ class PartitionOpTranslator {
11471165 case SILInstructionKind::EndInitLetRefInst:
11481166 case SILInstructionKind::InitEnumDataAddrInst:
11491167 case SILInstructionKind::OpenExistentialAddrInst:
1150- case SILInstructionKind::StructElementAddrInst:
1151- case SILInstructionKind::TupleElementAddrInst:
11521168 case SILInstructionKind::UncheckedRefCastInst:
11531169 case SILInstructionKind::UncheckedTakeEnumDataAddrInst:
11541170 case SILInstructionKind::UpcastInst:
11551171 return translateSILLookThrough (inst->getResult (0 ), inst->getOperand (0 ));
11561172
1173+ case SILInstructionKind::TupleElementAddrInst:
1174+ case SILInstructionKind::StructElementAddrInst: {
1175+ auto *svi = cast<SingleValueInstruction>(inst);
1176+ // If we have a sendable field... we can always access it after
1177+ // transferring... so do not track this.
1178+ if (!isNonSendableType (svi->getType ()))
1179+ return ;
1180+ return translateSILLookThrough (svi->getResult (0 ), svi->getOperand (0 ));
1181+ }
1182+
11571183 // We identify tuple results with their operand's id.
11581184 case SILInstructionKind::DestructureTupleInst:
11591185 case SILInstructionKind::DestructureStructInst:
@@ -1183,23 +1209,44 @@ class PartitionOpTranslator {
11831209 case SILInstructionKind::PointerToAddressInst:
11841210 case SILInstructionKind::ProjectBlockStorageInst:
11851211 case SILInstructionKind::RefToUnmanagedInst:
1186- case SILInstructionKind::StructExtractInst:
11871212 case SILInstructionKind::TailAddrInst:
11881213 case SILInstructionKind::ThickToObjCMetatypeInst:
11891214 case SILInstructionKind::ThinToThickFunctionInst:
11901215 case SILInstructionKind::UncheckedAddrCastInst:
11911216 case SILInstructionKind::UncheckedEnumDataInst:
11921217 case SILInstructionKind::UncheckedOwnershipConversionInst:
11931218 case SILInstructionKind::UnmanagedToRefInst:
1219+ return translateSILAssign (inst);
11941220
11951221 // RefElementAddrInst is not considered to be a lookThrough since we want to
11961222 // consider the address projected from the class to be a separate value that
11971223 // is in the same region as the parent operand. The reason that we want to
11981224 // do this is to ensure that if we assign into the ref_element_addr memory,
11991225 // we do not consider writes into the struct that contains the
12001226 // ref_element_addr to be merged into.
1201- case SILInstructionKind::RefElementAddrInst:
1227+ case SILInstructionKind::RefElementAddrInst: {
1228+ auto *reai = cast<RefElementAddrInst>(inst);
1229+ // If we are accessing a let of a Sendable type, do not treat the
1230+ // ref_element_addr as a require use.
1231+ if (reai->getField ()->isLet () && !isNonSendableType (reai->getType ())) {
1232+ LLVM_DEBUG (llvm::dbgs () << " Found a let! Not tracking!\n " );
1233+ return ;
1234+ }
1235+ return translateSILAssign (inst);
1236+ }
1237+
1238+ case SILInstructionKind::TupleExtractInst:
1239+ case SILInstructionKind::StructExtractInst: {
1240+ auto *svi = cast<SingleValueInstruction>(inst);
1241+ // If our result is a Sendable type regardless of if it is a let or a var,
1242+ // we do not need to track it.
1243+ if (!isNonSendableType (svi->getType ())) {
1244+ LLVM_DEBUG (llvm::dbgs ()
1245+ << " Found a sendable field... Not Tracking!\n " );
1246+ return ;
1247+ }
12021248 return translateSILAssign (inst);
1249+ }
12031250
12041251 // / Enum inst is handled specially since if it does not have an argument,
12051252 // / we must assign fresh. Otherwise, we must propagate.
0 commit comments