@@ -991,18 +991,7 @@ static bool isProjectBoxNonEscapingUse(ProjectBoxInst *PBI,
991
991
EscapeMutationScanningState &State) {
992
992
DEBUG (llvm::dbgs () << " Found project box: " << *PBI);
993
993
994
- // Check for mutations of the address component.
995
- SILValue Addr = PBI;
996
-
997
- // If the AllocBox is used by a mark_uninitialized, scan the MUI for
998
- // interesting uses.
999
- if (Addr->hasOneUse ()) {
1000
- SILInstruction *SingleAddrUser = Addr->use_begin ()->getUser ();
1001
- if (isa<MarkUninitializedInst>(SingleAddrUser))
1002
- Addr = SILValue (SingleAddrUser);
1003
- }
1004
-
1005
- for (Operand *AddrOp : Addr->getUses ()) {
994
+ for (Operand *AddrOp : PBI->getUses ()) {
1006
995
if (!isNonEscapingUse (AddrOp, State)) {
1007
996
DEBUG (llvm::dbgs () << " FAIL! Has escaping user of addr:"
1008
997
<< *AddrOp->getUser ());
@@ -1015,11 +1004,13 @@ static bool isProjectBoxNonEscapingUse(ProjectBoxInst *PBI,
1015
1004
1016
1005
static bool scanUsesForEscapesAndMutations (Operand *Op,
1017
1006
EscapeMutationScanningState &State) {
1018
- if (auto *PAI = dyn_cast<PartialApplyInst>(Op->getUser ())) {
1007
+ SILInstruction *User = Op->getUser ();
1008
+
1009
+ if (auto *PAI = dyn_cast<PartialApplyInst>(User)) {
1019
1010
return isPartialApplyNonEscapingUser (Op, PAI, State);
1020
1011
}
1021
1012
1022
- if (auto *PBI = dyn_cast<ProjectBoxInst>(Op-> getUser () )) {
1013
+ if (auto *PBI = dyn_cast<ProjectBoxInst>(User )) {
1023
1014
// It is assumed in later code that we will only have 1 project_box. This
1024
1015
// can be seen since there is no code for reasoning about multiple
1025
1016
// boxes. Just put in the restriction so we are consistent.
@@ -1029,20 +1020,16 @@ static bool scanUsesForEscapesAndMutations(Operand *Op,
1029
1020
return isProjectBoxNonEscapingUse (PBI, State);
1030
1021
}
1031
1022
1032
- // Given a top level copy value use, check all of its user operands as if
1033
- // they were apart of the use list of the base operand.
1034
- //
1035
- // This is because even though we are copying the box, a copy of the box is
1036
- // just a retain + bitwise copy of the pointer. This has nothing to do with
1037
- // whether or not the address escapes in some way.
1023
+ // Given a top level copy value use or mark_uninitialized, check all of its
1024
+ // user operands as if they were apart of the use list of the base operand.
1038
1025
//
1039
1026
// This is a separate code path from the non escaping user visitor check since
1040
1027
// we want to be more conservative around non-top level copies (i.e. a copy
1041
1028
// derived from a projection like instruction). In fact such a thing may not
1042
1029
// even make any sense!
1043
- if (auto *CVI = dyn_cast <CopyValueInst>(Op-> getUser () )) {
1044
- return all_of (CVI ->getUses (), [&State](Operand *CopyOp ) -> bool {
1045
- return scanUsesForEscapesAndMutations (CopyOp , State);
1030
+ if (isa <CopyValueInst>(User) || isa<MarkUninitializedInst>(User )) {
1031
+ return all_of (User ->getUses (), [&State](Operand *UserOp ) -> bool {
1032
+ return scanUsesForEscapesAndMutations (UserOp , State);
1046
1033
});
1047
1034
}
1048
1035
@@ -1171,36 +1158,18 @@ static SILValue getOrCreateProjectBoxHelper(SILValue PartialOperand) {
1171
1158
return B.createProjectBox (CVI->getLoc (), CVI, 0 );
1172
1159
}
1173
1160
1174
- // Otherwise, handle the alloc_box case.
1175
- auto *ABI = cast<AllocBoxInst>(PartialOperand);
1176
- // Load and copy from the address value, passing the result as an argument
1177
- // to the new closure.
1178
- //
1179
- // *NOTE* This code assumes that we only have one project box user. We
1180
- // enforce this with the assert below.
1181
- assert (count_if (ABI->getUses (), [](Operand *Op) -> bool {
1182
- return isa<ProjectBoxInst>(Op->getUser ());
1183
- }) == 1 );
1184
-
1185
- // If the address is marked uninitialized, load through the mark, so
1186
- // that DI can reason about it.
1187
- for (Operand *BoxValueUse : ABI->getUses ()) {
1188
- auto *PBI = dyn_cast<ProjectBoxInst>(BoxValueUse->getUser ());
1189
- if (!PBI)
1190
- continue ;
1191
-
1192
- auto *OptIter = PBI->getSingleUse ();
1193
- if (!OptIter)
1194
- continue ;
1195
-
1196
- if (!isa<MarkUninitializedInst>(OptIter->getUser ()))
1197
- continue ;
1198
-
1199
- return OptIter->getUser ();
1161
+ // Otherwise, handle the alloc_box case. If we have a mark_uninitialized on
1162
+ // the box, we create the project value through that.
1163
+ SILInstruction *Box = cast<AllocBoxInst>(PartialOperand);
1164
+ if (auto *Op = Box->getSingleUse ()) {
1165
+ if (auto *MUI = dyn_cast<MarkUninitializedInst>(Op->getUser ())) {
1166
+ Box = MUI;
1167
+ }
1200
1168
}
1201
1169
1202
- // Otherwise, just return a project_box.
1203
- return getOrCreateProjectBox (ABI, 0 );
1170
+ // Just return a project_box.
1171
+ SILBuilder B (std::next (Box->getIterator ()));
1172
+ return B.createProjectBox (Box->getLoc (), Box, 0 );
1204
1173
}
1205
1174
1206
1175
// / \brief Given a partial_apply instruction and a set of promotable indices,
0 commit comments