@@ -417,6 +417,11 @@ static bool visitScopeEndsRequiringInit(
417
417
llvm_unreachable (" invalid check!?" );
418
418
}
419
419
420
+ // Look through wrappers.
421
+ if (auto m = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(operand)) {
422
+ operand = m->getOperand ();
423
+ }
424
+
420
425
// Check for inout types of arguments that are marked with consumable and
421
426
// assignable.
422
427
if (auto *fArg = dyn_cast<SILFunctionArgument>(operand)) {
@@ -1007,6 +1012,7 @@ void UseState::initializeLiveness(
1007
1012
// Then check if our markedValue is from an argument that is in,
1008
1013
// in_guaranteed, inout, or inout_aliasable, consider the marked address to be
1009
1014
// the initialization point.
1015
+ bool beginsInitialized = false ;
1010
1016
{
1011
1017
SILValue operand = address->getOperand ();
1012
1018
if (auto *c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(operand))
@@ -1025,8 +1031,7 @@ void UseState::initializeLiveness(
1025
1031
" an init... adding mark_unresolved_non_copyable_value as "
1026
1032
" init!\n " );
1027
1033
// 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 ;
1030
1035
break ;
1031
1036
case swift::SILArgumentConvention::Indirect_Out:
1032
1037
llvm_unreachable (" Should never have out addresses here" );
@@ -1042,6 +1047,22 @@ void UseState::initializeLiveness(
1042
1047
}
1043
1048
}
1044
1049
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
+
1045
1066
// See if our address is from a closure guaranteed box that we did not promote
1046
1067
// to an address. In such a case, just treat our
1047
1068
// mark_unresolved_non_copyable_value as the init of our value.
@@ -1057,16 +1078,14 @@ void UseState::initializeLiveness(
1057
1078
LLVM_DEBUG (llvm::dbgs ()
1058
1079
<< " Found move only arg closure box use... "
1059
1080
" 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 ;
1062
1082
}
1063
1083
} else if (auto *box = dyn_cast<AllocBoxInst>(
1064
1084
lookThroughOwnershipInsts (projectBox->getOperand ()))) {
1065
1085
LLVM_DEBUG (llvm::dbgs ()
1066
1086
<< " Found move only var allocbox use... "
1067
1087
" 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 ;
1070
1089
}
1071
1090
}
1072
1091
@@ -1077,8 +1096,7 @@ void UseState::initializeLiveness(
1077
1096
LLVM_DEBUG (llvm::dbgs ()
1078
1097
<< " Found ref_element_addr use... "
1079
1098
" 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 ;
1082
1100
}
1083
1101
1084
1102
// Check if our address is from a global_addr. In such a case, we treat the
@@ -1088,8 +1106,7 @@ void UseState::initializeLiveness(
1088
1106
LLVM_DEBUG (llvm::dbgs ()
1089
1107
<< " Found global_addr use... "
1090
1108
" 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 ;
1093
1110
}
1094
1111
1095
1112
if (auto *ptai = dyn_cast<PointerToAddressInst>(
@@ -1098,24 +1115,21 @@ void UseState::initializeLiveness(
1098
1115
LLVM_DEBUG (llvm::dbgs ()
1099
1116
<< " Found pointer to address use... "
1100
1117
" 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 ;
1103
1119
}
1104
1120
1105
1121
if (auto *bai = dyn_cast_or_null<BeginApplyInst>(
1106
1122
stripAccessMarkers (address->getOperand ())->getDefiningInstruction ())) {
1107
1123
LLVM_DEBUG (llvm::dbgs ()
1108
1124
<< " Adding accessor coroutine begin_apply as init!\n " );
1109
- recordInitUse (address, address, liveness.getTopLevelSpan ());
1110
- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1125
+ beginsInitialized = true ;
1111
1126
}
1112
1127
1113
1128
if (auto *eai = dyn_cast<UncheckedTakeEnumDataAddrInst>(
1114
1129
stripAccessMarkers (address->getOperand ()))) {
1115
1130
LLVM_DEBUG (llvm::dbgs ()
1116
1131
<< " Adding enum projection as init!\n " );
1117
- recordInitUse (address, address, liveness.getTopLevelSpan ());
1118
- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1132
+ beginsInitialized = true ;
1119
1133
}
1120
1134
1121
1135
// Assume a strict check of a temporary or formal access is initialized
@@ -1125,32 +1139,33 @@ void UseState::initializeLiveness(
1125
1139
asi && address->isStrict ()) {
1126
1140
LLVM_DEBUG (llvm::dbgs ()
1127
1141
<< " Adding strict-marked alloc_stack as init!\n " );
1128
- recordInitUse (address, address, liveness.getTopLevelSpan ());
1129
- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1142
+ beginsInitialized = true ;
1130
1143
}
1131
1144
1132
1145
// Assume a strict-checked value initialized before the check.
1133
1146
if (address->isStrict ()) {
1134
1147
LLVM_DEBUG (llvm::dbgs ()
1135
1148
<< " Adding strict marker as init!\n " );
1136
- recordInitUse (address, address, liveness.getTopLevelSpan ());
1137
- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1149
+ beginsInitialized = true ;
1138
1150
}
1139
1151
1140
1152
// Assume a value whose deinit has been dropped has been initialized.
1141
1153
if (auto *ddi = dyn_cast<DropDeinitInst>(address->getOperand ())) {
1142
1154
LLVM_DEBUG (llvm::dbgs ()
1143
1155
<< " 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 ;
1146
1157
}
1147
1158
1148
1159
// Assume a value wrapped in a MoveOnlyWrapper is initialized.
1149
1160
if (auto *m2c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(address->getOperand ())) {
1150
1161
LLVM_DEBUG (llvm::dbgs ()
1151
1162
<< " Adding copyable_to_move_only_wrapper as init!\n " );
1163
+ beginsInitialized = true ;
1164
+ }
1165
+
1166
+ if (beginsInitialized) {
1152
1167
recordInitUse (address, address, liveness.getTopLevelSpan ());
1153
- liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1168
+ liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
1154
1169
}
1155
1170
1156
1171
// Now that we have finished initialization of defs, change our multi-maps
0 commit comments