@@ -987,36 +987,21 @@ static bool findNonEscapingPartialApplyUses(PartialApplyInst *pai,
987
987
return true ;
988
988
}
989
989
990
- void UseState::initializeLiveness (
991
- FieldSensitiveMultiDefPrunedLiveRange &liveness) {
992
- assert (liveness.getNumSubElements () == getNumSubelements ());
993
- // We begin by initializing all of our init uses.
994
- for (auto initInstAndValue : initInsts) {
995
- LLVM_DEBUG (llvm::dbgs () << " Found def: " << *initInstAndValue.first );
990
+ static bool
991
+ addressBeginsInitialized (MarkUnresolvedNonCopyableValueInst *address) {
992
+ // FIXME: Whether the initial use is an initialization ought to be entirely
993
+ // derivable from the CheckKind of the mark instruction.
996
994
997
- liveness.initializeDef (initInstAndValue.first , initInstAndValue.second );
998
- }
995
+ SILValue operand = address->getOperand ();
999
996
1000
- // If we have a reinitInstAndValue that we are going to be able to convert
1001
- // into a simple init, add it as an init. We are going to consider the rest of
1002
- // our reinit uses to be liveness uses.
1003
- for (auto reinitInstAndValue : reinitInsts) {
1004
- if (isReinitToInitConvertibleInst (reinitInstAndValue.first )) {
1005
- LLVM_DEBUG (llvm::dbgs () << " Found def: " << *reinitInstAndValue.first );
1006
- liveness.initializeDef (reinitInstAndValue.first ,
1007
- reinitInstAndValue.second );
1008
- }
997
+ if (auto *mdi = dyn_cast<MarkDependenceInst>(operand)) {
998
+ operand = mdi->getValue ();
1009
999
}
1010
-
1011
- // FIXME: Whether the initial use is an initialization ought to be entirely
1012
- // derivable from the CheckKind of the mark instruction.
1013
1000
1014
- // Then check if our markedValue is from an argument that is in,
1015
- // in_guaranteed, inout, or inout_aliasable, consider the marked address to be
1016
- // the initialization point.
1017
- bool beginsInitialized = false ;
1018
1001
{
1019
- SILValue operand = address->getOperand ();
1002
+ // Then check if our markedValue is from an argument that is in,
1003
+ // in_guaranteed, inout, or inout_aliasable, consider the marked address to
1004
+ // be the initialization point.
1020
1005
if (auto *c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(operand))
1021
1006
operand = c->getOperand ();
1022
1007
if (auto *fArg = dyn_cast<SILFunctionArgument>(operand)) {
@@ -1034,7 +1019,7 @@ void UseState::initializeLiveness(
1034
1019
" an init... adding mark_unresolved_non_copyable_value as "
1035
1020
" init!\n " );
1036
1021
// We cheat here slightly and use our address's operand.
1037
- beginsInitialized = true ;
1022
+ return true ;
1038
1023
break ;
1039
1024
case swift::SILArgumentConvention::Indirect_Out:
1040
1025
llvm_unreachable (" Should never have out addresses here" );
@@ -1051,15 +1036,15 @@ void UseState::initializeLiveness(
1051
1036
}
1052
1037
1053
1038
// A read or write access always begins on an initialized value.
1054
- if (auto access = dyn_cast<BeginAccessInst>(address-> getOperand () )) {
1039
+ if (auto access = dyn_cast<BeginAccessInst>(operand )) {
1055
1040
switch (access->getAccessKind ()) {
1056
1041
case SILAccessKind::Deinit:
1057
1042
case SILAccessKind::Read:
1058
1043
case SILAccessKind::Modify:
1059
1044
LLVM_DEBUG (llvm::dbgs ()
1060
1045
<< " Found move only arg closure box use... "
1061
1046
" adding mark_unresolved_non_copyable_value as init!\n " );
1062
- beginsInitialized = true ;
1047
+ return true ;
1063
1048
break ;
1064
1049
case SILAccessKind::Init:
1065
1050
break ;
@@ -1069,7 +1054,8 @@ void UseState::initializeLiveness(
1069
1054
// See if our address is from a closure guaranteed box that we did not promote
1070
1055
// to an address. In such a case, just treat our
1071
1056
// mark_unresolved_non_copyable_value as the init of our value.
1072
- if (auto *projectBox = dyn_cast<ProjectBoxInst>(stripAccessMarkers (address->getOperand ()))) {
1057
+ if (auto *projectBox =
1058
+ dyn_cast<ProjectBoxInst>(stripAccessMarkers (operand))) {
1073
1059
if (auto *fArg = dyn_cast<SILFunctionArgument>(projectBox->getOperand ())) {
1074
1060
if (fArg ->isClosureCapture ()) {
1075
1061
assert (fArg ->getArgumentConvention () ==
@@ -1081,91 +1067,115 @@ void UseState::initializeLiveness(
1081
1067
LLVM_DEBUG (llvm::dbgs ()
1082
1068
<< " Found move only arg closure box use... "
1083
1069
" adding mark_unresolved_non_copyable_value as init!\n " );
1084
- beginsInitialized = true ;
1070
+ return true ;
1085
1071
}
1086
1072
} else if (auto *box = dyn_cast<AllocBoxInst>(
1087
1073
lookThroughOwnershipInsts (projectBox->getOperand ()))) {
1088
1074
LLVM_DEBUG (llvm::dbgs ()
1089
1075
<< " Found move only var allocbox use... "
1090
1076
" adding mark_unresolved_non_copyable_value as init!\n " );
1091
- beginsInitialized = true ;
1077
+ return true ;
1092
1078
}
1093
1079
}
1094
1080
1095
1081
// Check if our address is from a ref_element_addr. In such a case, we treat
1096
1082
// the mark_unresolved_non_copyable_value as the initialization.
1097
- if (auto *refEltAddr = dyn_cast<RefElementAddrInst>(
1098
- stripAccessMarkers (address-> getOperand () ))) {
1083
+ if (auto *refEltAddr =
1084
+ dyn_cast<RefElementAddrInst>( stripAccessMarkers (operand ))) {
1099
1085
LLVM_DEBUG (llvm::dbgs ()
1100
1086
<< " Found ref_element_addr use... "
1101
1087
" adding mark_unresolved_non_copyable_value as init!\n " );
1102
- beginsInitialized = true ;
1088
+ return true ;
1103
1089
}
1104
1090
1105
1091
// Check if our address is from a global_addr. In such a case, we treat the
1106
1092
// mark_unresolved_non_copyable_value as the initialization.
1107
1093
if (auto *globalAddr =
1108
- dyn_cast<GlobalAddrInst>(stripAccessMarkers (address-> getOperand () ))) {
1094
+ dyn_cast<GlobalAddrInst>(stripAccessMarkers (operand ))) {
1109
1095
LLVM_DEBUG (llvm::dbgs ()
1110
1096
<< " Found global_addr use... "
1111
1097
" adding mark_unresolved_non_copyable_value as init!\n " );
1112
- beginsInitialized = true ;
1098
+ return true ;
1113
1099
}
1114
1100
1115
- if (auto *ptai = dyn_cast<PointerToAddressInst>(
1116
- stripAccessMarkers (address-> getOperand () ))) {
1101
+ if (auto *ptai =
1102
+ dyn_cast<PointerToAddressInst>( stripAccessMarkers (operand ))) {
1117
1103
assert (ptai->isStrict ());
1118
1104
LLVM_DEBUG (llvm::dbgs ()
1119
1105
<< " Found pointer to address use... "
1120
1106
" adding mark_unresolved_non_copyable_value as init!\n " );
1121
- beginsInitialized = true ;
1107
+ return true ;
1122
1108
}
1123
-
1109
+
1124
1110
if (auto *bai = dyn_cast_or_null<BeginApplyInst>(
1125
- stripAccessMarkers (address-> getOperand () )->getDefiningInstruction ())) {
1111
+ stripAccessMarkers (operand )->getDefiningInstruction ())) {
1126
1112
LLVM_DEBUG (llvm::dbgs ()
1127
1113
<< " Adding accessor coroutine begin_apply as init!\n " );
1128
- beginsInitialized = true ;
1114
+ return true ;
1129
1115
}
1130
-
1116
+
1131
1117
if (auto *eai = dyn_cast<UncheckedTakeEnumDataAddrInst>(
1132
- stripAccessMarkers (address-> getOperand () ))) {
1118
+ stripAccessMarkers (operand ))) {
1133
1119
LLVM_DEBUG (llvm::dbgs ()
1134
1120
<< " Adding enum projection as init!\n " );
1135
- beginsInitialized = true ;
1121
+ return true ;
1136
1122
}
1137
1123
1138
1124
// Assume a strict check of a temporary or formal access is initialized
1139
1125
// before the check.
1140
- if (auto *asi = dyn_cast<AllocStackInst>(
1141
- stripAccessMarkers (address->getOperand ()));
1126
+ if (auto *asi = dyn_cast<AllocStackInst>(stripAccessMarkers (operand));
1142
1127
asi && address->isStrict ()) {
1143
1128
LLVM_DEBUG (llvm::dbgs ()
1144
1129
<< " Adding strict-marked alloc_stack as init!\n " );
1145
- beginsInitialized = true ;
1130
+ return true ;
1146
1131
}
1147
1132
1148
1133
// Assume a strict-checked value initialized before the check.
1149
1134
if (address->isStrict ()) {
1150
1135
LLVM_DEBUG (llvm::dbgs ()
1151
1136
<< " Adding strict marker as init!\n " );
1152
- beginsInitialized = true ;
1137
+ return true ;
1153
1138
}
1154
1139
1155
1140
// Assume a value whose deinit has been dropped has been initialized.
1156
- if (auto *ddi = dyn_cast<DropDeinitInst>(address-> getOperand () )) {
1141
+ if (auto *ddi = dyn_cast<DropDeinitInst>(operand )) {
1157
1142
LLVM_DEBUG (llvm::dbgs ()
1158
1143
<< " Adding copyable_to_move_only_wrapper as init!\n " );
1159
- beginsInitialized = true ;
1144
+ return true ;
1160
1145
}
1161
1146
1162
1147
// Assume a value wrapped in a MoveOnlyWrapper is initialized.
1163
- if (auto *m2c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(address-> getOperand () )) {
1148
+ if (auto *m2c = dyn_cast<CopyableToMoveOnlyWrapperAddrInst>(operand )) {
1164
1149
LLVM_DEBUG (llvm::dbgs ()
1165
1150
<< " Adding copyable_to_move_only_wrapper as init!\n " );
1166
- beginsInitialized = true ;
1151
+ return true ;
1167
1152
}
1168
-
1153
+ return false ;
1154
+ }
1155
+
1156
+ void UseState::initializeLiveness (
1157
+ FieldSensitiveMultiDefPrunedLiveRange &liveness) {
1158
+ assert (liveness.getNumSubElements () == getNumSubelements ());
1159
+ // We begin by initializing all of our init uses.
1160
+ for (auto initInstAndValue : initInsts) {
1161
+ LLVM_DEBUG (llvm::dbgs () << " Found def: " << *initInstAndValue.first );
1162
+
1163
+ liveness.initializeDef (initInstAndValue.first , initInstAndValue.second );
1164
+ }
1165
+
1166
+ // If we have a reinitInstAndValue that we are going to be able to convert
1167
+ // into a simple init, add it as an init. We are going to consider the rest of
1168
+ // our reinit uses to be liveness uses.
1169
+ for (auto reinitInstAndValue : reinitInsts) {
1170
+ if (isReinitToInitConvertibleInst (reinitInstAndValue.first )) {
1171
+ LLVM_DEBUG (llvm::dbgs () << " Found def: " << *reinitInstAndValue.first );
1172
+ liveness.initializeDef (reinitInstAndValue.first ,
1173
+ reinitInstAndValue.second );
1174
+ }
1175
+ }
1176
+
1177
+ bool beginsInitialized = addressBeginsInitialized (address);
1178
+
1169
1179
if (beginsInitialized) {
1170
1180
recordInitUse (address, address, liveness.getTopLevelSpan ());
1171
1181
liveness.initializeDef (SILValue (address), liveness.getTopLevelSpan ());
0 commit comments