@@ -417,6 +417,11 @@ static bool visitScopeEndsRequiringInit(
417417 llvm_unreachable (" invalid check!?" );
418418 }
419419
420+ // Look through wrappers.
421+ if (auto m = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(operand)) {
422+ operand = m->getOperand ();
423+ }
424+
420425 // Check for inout types of arguments that are marked with consumable and
421426 // assignable.
422427 if (auto *fArg = dyn_cast<SILFunctionArgument>(operand)) {
@@ -1007,6 +1012,7 @@ void UseState::initializeLiveness(
10071012 // Then check if our markedValue is from an argument that is in,
10081013 // in_guaranteed, inout, or inout_aliasable, consider the marked address to be
10091014 // the initialization point.
1015+ bool beginsInitialized = false ;
10101016 {
10111017 SILValue operand = address->getOperand ();
10121018 if (auto *c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(operand))
@@ -1025,8 +1031,7 @@ void UseState::initializeLiveness(
10251031 " an init... adding mark_unresolved_non_copyable_value as "
10261032 " init!\n " );
10271033 // We cheat here slightly and use our address's operand.
1028- recordInitUse (address, address, liveness.getTopLevelSpan ());
1029- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1034+ beginsInitialized = true ;
10301035 break ;
10311036 case swift::SILArgumentConvention::Indirect_Out:
10321037 llvm_unreachable (" Should never have out addresses here" );
@@ -1042,6 +1047,22 @@ void UseState::initializeLiveness(
10421047 }
10431048 }
10441049
1050+ // A read or write access always begins on an initialized value.
1051+ if (auto access = dyn_cast<BeginAccessInst>(address->getOperand ())) {
1052+ switch (access->getAccessKind ()) {
1053+ case SILAccessKind::Deinit:
1054+ case SILAccessKind::Read:
1055+ case SILAccessKind::Modify:
1056+ LLVM_DEBUG (llvm::dbgs ()
1057+ << " Found move only arg closure box use... "
1058+ " adding mark_unresolved_non_copyable_value as init!\n " );
1059+ beginsInitialized = true ;
1060+ break ;
1061+ case SILAccessKind::Init:
1062+ break ;
1063+ }
1064+ }
1065+
10451066 // See if our address is from a closure guaranteed box that we did not promote
10461067 // to an address. In such a case, just treat our
10471068 // mark_unresolved_non_copyable_value as the init of our value.
@@ -1057,16 +1078,14 @@ void UseState::initializeLiveness(
10571078 LLVM_DEBUG (llvm::dbgs ()
10581079 << " Found move only arg closure box use... "
10591080 " adding mark_unresolved_non_copyable_value as init!\n " );
1060- recordInitUse (address, address, liveness.getTopLevelSpan ());
1061- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1081+ beginsInitialized = true ;
10621082 }
10631083 } else if (auto *box = dyn_cast<AllocBoxInst>(
10641084 lookThroughOwnershipInsts (projectBox->getOperand ()))) {
10651085 LLVM_DEBUG (llvm::dbgs ()
10661086 << " Found move only var allocbox use... "
10671087 " adding mark_unresolved_non_copyable_value as init!\n " );
1068- recordInitUse (address, address, liveness.getTopLevelSpan ());
1069- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1088+ beginsInitialized = true ;
10701089 }
10711090 }
10721091
@@ -1077,8 +1096,7 @@ void UseState::initializeLiveness(
10771096 LLVM_DEBUG (llvm::dbgs ()
10781097 << " Found ref_element_addr use... "
10791098 " adding mark_unresolved_non_copyable_value as init!\n " );
1080- recordInitUse (address, address, liveness.getTopLevelSpan ());
1081- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1099+ beginsInitialized = true ;
10821100 }
10831101
10841102 // Check if our address is from a global_addr. In such a case, we treat the
@@ -1088,8 +1106,7 @@ void UseState::initializeLiveness(
10881106 LLVM_DEBUG (llvm::dbgs ()
10891107 << " Found global_addr use... "
10901108 " adding mark_unresolved_non_copyable_value as init!\n " );
1091- recordInitUse (address, address, liveness.getTopLevelSpan ());
1092- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1109+ beginsInitialized = true ;
10931110 }
10941111
10951112 if (auto *ptai = dyn_cast<PointerToAddressInst>(
@@ -1098,24 +1115,21 @@ void UseState::initializeLiveness(
10981115 LLVM_DEBUG (llvm::dbgs ()
10991116 << " Found pointer to address use... "
11001117 " adding mark_unresolved_non_copyable_value as init!\n " );
1101- recordInitUse (address, address, liveness.getTopLevelSpan ());
1102- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1118+ beginsInitialized = true ;
11031119 }
11041120
11051121 if (auto *bai = dyn_cast_or_null<BeginApplyInst>(
11061122 stripAccessMarkers (address->getOperand ())->getDefiningInstruction ())) {
11071123 LLVM_DEBUG (llvm::dbgs ()
11081124 << " Adding accessor coroutine begin_apply as init!\n " );
1109- recordInitUse (address, address, liveness.getTopLevelSpan ());
1110- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1125+ beginsInitialized = true ;
11111126 }
11121127
11131128 if (auto *eai = dyn_cast<UncheckedTakeEnumDataAddrInst>(
11141129 stripAccessMarkers (address->getOperand ()))) {
11151130 LLVM_DEBUG (llvm::dbgs ()
11161131 << " Adding enum projection as init!\n " );
1117- recordInitUse (address, address, liveness.getTopLevelSpan ());
1118- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1132+ beginsInitialized = true ;
11191133 }
11201134
11211135 // Assume a strict check of a temporary or formal access is initialized
@@ -1125,32 +1139,33 @@ void UseState::initializeLiveness(
11251139 asi && address->isStrict ()) {
11261140 LLVM_DEBUG (llvm::dbgs ()
11271141 << " Adding strict-marked alloc_stack as init!\n " );
1128- recordInitUse (address, address, liveness.getTopLevelSpan ());
1129- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1142+ beginsInitialized = true ;
11301143 }
11311144
11321145 // Assume a strict-checked value initialized before the check.
11331146 if (address->isStrict ()) {
11341147 LLVM_DEBUG (llvm::dbgs ()
11351148 << " Adding strict marker as init!\n " );
1136- recordInitUse (address, address, liveness.getTopLevelSpan ());
1137- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1149+ beginsInitialized = true ;
11381150 }
11391151
11401152 // Assume a value whose deinit has been dropped has been initialized.
11411153 if (auto *ddi = dyn_cast<DropDeinitInst>(address->getOperand ())) {
11421154 LLVM_DEBUG (llvm::dbgs ()
11431155 << " Adding copyable_to_move_only_wrapper as init!\n " );
1144- recordInitUse (address, address, liveness.getTopLevelSpan ());
1145- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1156+ beginsInitialized = true ;
11461157 }
11471158
11481159 // Assume a value wrapped in a MoveOnlyWrapper is initialized.
11491160 if (auto *m2c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(address->getOperand ())) {
11501161 LLVM_DEBUG (llvm::dbgs ()
11511162 << " Adding copyable_to_move_only_wrapper as init!\n " );
1163+ beginsInitialized = true ;
1164+ }
1165+
1166+ if (beginsInitialized) {
11521167 recordInitUse (address, address, liveness.getTopLevelSpan ());
1153- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1168+ liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
11541169 }
11551170
11561171 // Now that we have finished initialization of defs, change our multi-maps
0 commit comments