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