mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[region-isolation] When assigning RValues into memory, use tuple_addr_constructor instead of doing it in pieces.
I also included changes to the rest of the SIL optimizer pipeline to ensure that the part of the optimizer pipeline before we lower tuple_addr_constructor (which is right after we run TransferNonSendable) work as before. The reason why I am doing this is that this ensures that diagnostic passes can tell the difference in between: ``` x = (a, b, c) ``` and ``` x.0 = a x.1 = b x.2 = c ``` This is important for things like TransferNonSendable where assigning over the entire tuple element is treated differently from if one were to initialize it in pieces using projections. rdar://117880194
This commit is contained in:
@@ -558,36 +558,33 @@ void RValue::copyInto(SILGenFunction &SGF, SILLocation loc,
|
||||
copyOrInitValuesInto<ImplodeKind::Copy>(I, elts, type, loc, SGF);
|
||||
}
|
||||
|
||||
static void assignRecursive(SILGenFunction &SGF, SILLocation loc,
|
||||
CanType type, ArrayRef<ManagedValue> &srcValues,
|
||||
SILValue destAddr) {
|
||||
// Recurse into tuples.
|
||||
auto srcTupleType = dyn_cast<TupleType>(type);
|
||||
if (srcTupleType && !srcTupleType.containsPackExpansionType()) {
|
||||
assert(destAddr->getType().castTo<TupleType>()->getNumElements()
|
||||
== srcTupleType->getNumElements());
|
||||
for (auto eltIndex : indices(srcTupleType.getElementTypes())) {
|
||||
auto eltDestAddr = SGF.B.createTupleElementAddr(loc, destAddr, eltIndex);
|
||||
assignRecursive(SGF, loc, srcTupleType.getElementType(eltIndex),
|
||||
srcValues, eltDestAddr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, pull the front value off the list.
|
||||
auto srcValue = srcValues.front();
|
||||
srcValues = srcValues.slice(1);
|
||||
|
||||
srcValue.assignInto(SGF, loc, destAddr);
|
||||
}
|
||||
|
||||
void RValue::assignInto(SILGenFunction &SGF, SILLocation loc,
|
||||
SILValue destAddr) && {
|
||||
assert(isComplete() && "rvalue is not complete");
|
||||
assert(isPlusOneOrTrivial(SGF) && "Can not assign borrowed RValues");
|
||||
ArrayRef<ManagedValue> srcValues = values;
|
||||
assignRecursive(SGF, loc, type, srcValues, destAddr);
|
||||
assert(srcValues.empty() && "didn't claim all elements!");
|
||||
ArrayRef<ManagedValue> srcMvValues = values;
|
||||
|
||||
SWIFT_DEFER { assert(srcMvValues.empty() && "didn't claim all elements!"); };
|
||||
|
||||
// If we do not have a tuple, just bail early.
|
||||
auto srcTupleType = dyn_cast<TupleType>(type);
|
||||
if (!srcTupleType || srcTupleType.containsPackExpansionType()) {
|
||||
// Otherwise, pull the front value off the list.
|
||||
auto srcValue = srcMvValues.front();
|
||||
srcMvValues = srcMvValues.slice(1);
|
||||
srcValue.assignInto(SGF, loc, destAddr);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(destAddr->getType().castTo<TupleType>()->getNumElements() ==
|
||||
srcTupleType->getNumElements());
|
||||
|
||||
// If we do have any srcMvValues, then emit a TupleAddrConstructor. If we do
|
||||
// not have any, then our tuple must consist only of empty tuples.
|
||||
if (srcMvValues.size())
|
||||
SGF.B.createTupleAddrConstructor(loc, destAddr, srcMvValues,
|
||||
IsNotInitialization);
|
||||
srcMvValues = ArrayRef<ManagedValue>();
|
||||
}
|
||||
|
||||
ManagedValue RValue::getAsSingleValue(SILGenFunction &SGF, SILLocation loc) && {
|
||||
|
||||
Reference in New Issue
Block a user