@@ -672,7 +672,6 @@ OwnershipLifetimeExtender::createPlusZeroBorrow(SILValue newValue,
672
672
callbacks.createdNewInst (ebi);
673
673
callbacks.createdNewInst (dvi);
674
674
}
675
-
676
675
return borrow;
677
676
}
678
677
@@ -1032,7 +1031,7 @@ OwnershipRAUWHelper::replaceAddressUses(SingleValueInstruction *oldValue,
1032
1031
// If we are replacing addresses, see if we need to handle interior pointer
1033
1032
// fixups. If we don't have any extra info, then we know that we can just RAUW
1034
1033
// without any further work.
1035
- if (!ctx->extraAddressFixupInfo .intPtrOp )
1034
+ if (!ctx->extraAddressFixupInfo .base )
1036
1035
return replaceAllUsesAndErase (oldValue, newValue, ctx->callbacks );
1037
1036
1038
1037
// We are RAUWing two addresses and we found that:
@@ -1045,25 +1044,26 @@ OwnershipRAUWHelper::replaceAddressUses(SingleValueInstruction *oldValue,
1045
1044
// interior pointer instruction and change the clone to use our new borrowed
1046
1045
// value. Then we RAUW as appropriate.
1047
1046
OwnershipLifetimeExtender extender{*ctx};
1048
- auto &extraInfo = ctx->extraAddressFixupInfo ;
1049
- auto intPtr = *extraInfo.intPtrOp ;
1047
+ auto base = ctx->extraAddressFixupInfo .base ;
1048
+ // FIXME: why does this use allAddressUsesFromOldValue instead of
1049
+ // guaranteedUsePoints?
1050
1050
BeginBorrowInst *bbi = extender.createPlusZeroBorrow (
1051
- intPtr->get (), llvm::makeArrayRef (extraInfo.allAddressUsesFromOldValue ));
1051
+ base.getReference (),
1052
+ llvm::makeArrayRef (
1053
+ ctx->extraAddressFixupInfo .allAddressUsesFromOldValue ));
1052
1054
auto bbiNext = &*std::next (bbi->getIterator ());
1053
- auto *newIntPtrUser =
1054
- cast<SingleValueInstruction>(intPtr-> getUser ()-> clone (bbiNext) );
1055
- ctx->callbacks .createdNewInst (newIntPtrUser );
1056
- newIntPtrUser ->setOperand (0 , bbi);
1055
+ auto *refProjection = cast<SingleValueInstruction>(base. getBaseAddress ());
1056
+ auto *newBase = refProjection-> clone (bbiNext);
1057
+ ctx->callbacks .createdNewInst (newBase );
1058
+ newBase ->setOperand (0 , bbi);
1057
1059
1058
1060
// Now that we have extended our lifetime as appropriate, we need to recreate
1059
- // the access path from newValue to intPtr but upon newIntPtr. Then we make it
1060
- // use newIntPtr.
1061
- auto *intPtrUser = cast<SingleValueInstruction>(intPtr->getUser ());
1062
-
1061
+ // the access path from newValue to refProjection but upon newBase.
1062
+ //
1063
1063
// This cloner invocation must match the canCloneUseDefChain check in the
1064
1064
// constructor.
1065
1065
auto checkBase = [&](SILValue srcAddr) {
1066
- return (srcAddr == intPtrUser ) ? SILValue (newIntPtrUser ) : SILValue ();
1066
+ return (srcAddr == refProjection ) ? SILValue (newBase ) : SILValue ();
1067
1067
};
1068
1068
SILValue clonedAddr =
1069
1069
cloneUseDefChain (newValue, /* insetPt*/ oldValue, checkBase);
@@ -1141,58 +1141,62 @@ OwnershipRAUWHelper::OwnershipRAUWHelper(OwnershipFixupContext &inputCtx,
1141
1141
if (!addressOwnership.hasLocalOwnershipLifetime ())
1142
1142
return ;
1143
1143
1144
- auto intPtrOp =
1145
- InteriorPointerOperand::inferFromResult (
1146
- addressOwnership.base .getBaseAddress ());
1147
- if (!intPtrOp) {
1144
+ ctx->extraAddressFixupInfo .base = addressOwnership.base ;
1145
+
1146
+ // For now, just gather up uses
1147
+ //
1148
+ // FIXME: get rid of allAddressUsesFromOldValue. Shouldn't this already be
1149
+ // included in guaranteedUsePoints?
1150
+ auto &oldValueUses = ctx->extraAddressFixupInfo .allAddressUsesFromOldValue ;
1151
+ // FIXME: The return value of findTransitiveUsesForAddress is currently
1152
+ // inverted.
1153
+ if (findTransitiveUsesForAddress (oldValue, oldValueUses)) {
1148
1154
invalidate ();
1149
1155
return ;
1150
1156
}
1151
-
1152
- ctx->extraAddressFixupInfo .intPtrOp = intPtrOp;
1153
- auto borrowedValue = intPtrOp.getSingleBorrowedValue ();
1154
- if (!borrowedValue) {
1155
- invalidate ();
1157
+ if (addressOwnership.areUsesWithinLifetime (oldValueUses, ctx->deBlocks )) {
1158
+ // We do not need to copy the base value! Clear the extra info we have.
1159
+ ctx->extraAddressFixupInfo .clear ();
1156
1160
return ;
1157
1161
}
1158
-
1159
- auto *intPtrInst =
1160
- cast<SingleValueInstruction>(intPtrOp.getUser ());
1162
+ // This cloner check must match the later cloner invocation in
1163
+ // getReplacementAddress()
1164
+ SILValue baseAddress = ctx->extraAddressFixupInfo .base .getBaseAddress ();
1165
+ auto *baseInst = cast<SingleValueInstruction>(baseAddress);
1161
1166
auto checkBase = [&](SILValue srcAddr) {
1162
- return (srcAddr == intPtrInst ) ? SILValue (intPtrInst ) : SILValue ();
1167
+ return (srcAddr == baseInst ) ? SILValue (baseInst ) : SILValue ();
1163
1168
};
1164
- // This cloner check must match the later cloner invocation in
1165
- // replaceAddressUses()
1166
1169
if (!canCloneUseDefChain (newValue, checkBase)) {
1167
1170
invalidate ();
1168
1171
return ;
1169
1172
}
1170
-
1171
- // For now, just gather up uses
1172
- auto &oldValueUses = ctx->extraAddressFixupInfo .allAddressUsesFromOldValue ;
1173
- if (findTransitiveUsesForAddress (oldValue, oldValueUses)) {
1174
- invalidate ();
1175
- return ;
1176
- }
1177
-
1178
- // Ok, at this point we know that we can optimize. The only question is if we
1179
- // need to perform the copy or not when we actually RAUW. So perform the is
1180
- // within region check. If we succeed, clear our extra state so we perform a
1181
- // normal RAUW.
1182
- if (borrowedValue.areUsesWithinLocalScope (oldValueUses, ctx->deBlocks )) {
1183
- // We do not need to copy the base value! Clear the extra info we have.
1184
- ctx->extraAddressFixupInfo .clear ();
1185
- }
1186
1173
}
1187
1174
1188
1175
SILBasicBlock::iterator
1189
1176
OwnershipRAUWHelper::perform (SingleValueInstruction *maybeTransformedNewValue) {
1190
1177
assert (isValid () && " OwnershipRAUWHelper invalid?!" );
1191
1178
1192
1179
SILValue actualNewValue = newValue;
1193
- if (maybeTransformedNewValue)
1180
+ if (maybeTransformedNewValue) {
1181
+ // Temporary variable for rebasing
1182
+ SILValue rewrittenNewValue = maybeTransformedNewValue;
1183
+ // Everything about \n newValue that the constructor checks should also be
1184
+ // true for rewrittenNewValue.
1185
+ // FIXME: enable these...
1186
+ // assert(rewrittenNewValue->getType() == newValue->getType());
1187
+ // assert(rewrittenNewValue->getOwnershipKind()
1188
+ // == newValue->getOwnershipKind());
1189
+ // assert(rewrittenNewValue->getParentBlock() == newValue->getParentBlock());
1190
+ assert (!newValue->getType ().isAddress () ||
1191
+ AddressOwnership (rewrittenNewValue) == AddressOwnership (newValue));
1192
+
1194
1193
actualNewValue = maybeTransformedNewValue;
1195
1194
1195
+ // TODO: newValue = rewrittenNewValue; (remove actualNewValue)
1196
+ }
1197
+ assert (newValue && " prepareReplacement can only be called once" );
1198
+ SWIFT_DEFER { newValue = SILValue (); };
1199
+
1196
1200
if (!oldValue->getFunction ()->hasOwnership ())
1197
1201
return replaceAllUsesAndErase (oldValue, actualNewValue, ctx->callbacks );
1198
1202
0 commit comments