Skip to content

Commit c110f0b

Browse files
authored
Merge pull request #14566 from gottesmm/pr-84f4d6b1f77131475b5abc2cd80f73ca6049bbaa
[silgen] Require ManagedValue::{forward,assign}Into to only accept pl…
2 parents cc8ef9d + 713e5f9 commit c110f0b

File tree

3 files changed

+47
-24
lines changed

3 files changed

+47
-24
lines changed

lib/SILGen/ManagedValue.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,29 +110,22 @@ SILValue ManagedValue::forward(SILGenFunction &SGF) const {
110110

111111
void ManagedValue::forwardInto(SILGenFunction &SGF, SILLocation loc,
112112
SILValue address) {
113-
if (!hasCleanup() && getOwnershipKind() != ValueOwnershipKind::Trivial)
114-
return copyUnmanaged(SGF, loc).forwardInto(SGF, loc, address);
115-
116-
if (hasCleanup())
117-
forwardCleanup(SGF);
118-
113+
assert(isPlusOne(SGF));
119114
auto &addrTL = SGF.getTypeLowering(address->getType());
120-
SGF.emitSemanticStore(loc, getValue(), address,
121-
addrTL, IsInitialization);
115+
SGF.emitSemanticStore(loc, forward(SGF), address, addrTL, IsInitialization);
122116
}
123117

124118
void ManagedValue::assignInto(SILGenFunction &SGF, SILLocation loc,
125119
SILValue address) {
126-
if (hasCleanup())
127-
forwardCleanup(SGF);
128-
120+
assert(isPlusOne(SGF));
129121
auto &addrTL = SGF.getTypeLowering(address->getType());
130-
SGF.emitSemanticStore(loc, getValue(), address, addrTL,
122+
SGF.emitSemanticStore(loc, forward(SGF), address, addrTL,
131123
IsNotInitialization);
132124
}
133125

134126
void ManagedValue::forwardInto(SILGenFunction &SGF, SILLocation loc,
135127
Initialization *dest) {
128+
assert(isPlusOne(SGF));
136129
dest->copyOrInitValueInto(SGF, loc, *this, /*isInit*/ true);
137130
dest->finishInitialization(SGF);
138131
}
@@ -208,3 +201,14 @@ ManagedValue ManagedValue::ensurePlusOne(SILGenFunction &SGF,
208201
}
209202
return *this;
210203
}
204+
205+
bool ManagedValue::isPlusOne(SILGenFunction &SGF) const {
206+
// Ignore trivial values and objects with trivial value ownership kind.
207+
if (getType().isTrivial(SGF.F.getModule()) ||
208+
(getType().isObject() &&
209+
getOwnershipKind() == ValueOwnershipKind::Trivial))
210+
return true;
211+
return hasCleanup();
212+
}
213+
214+
bool ManagedValue::isPlusZero() const { return hasCleanup(); }

lib/SILGen/ManagedValue.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,33 @@ class ManagedValue {
201201
// either +0 or trivial (in which case +0 vs +1 doesn't matter).
202202
return !hasCleanup();
203203
}
204-
204+
205+
/// Returns true if this is an managed value that can be used safely as a +1
206+
/// managed value.
207+
///
208+
/// This returns true iff:
209+
///
210+
/// 1. All sub-values are trivially typed.
211+
/// 2. There exists at least one non-trivial typed sub-value and all such
212+
/// sub-values all have cleanups.
213+
///
214+
/// *NOTE* Due to 1. isPlusOne and isPlusZero both return true for managed
215+
/// values consisting of only trivial values.
216+
bool isPlusOne(SILGenFunction &SGF) const;
217+
218+
/// Returns true if this is an ManagedValue that can be used safely as a +0
219+
/// ManagedValue.
220+
///
221+
/// Specifically, we return true if:
222+
///
223+
/// 1. All sub-values are trivially typed.
224+
/// 2. At least 1 subvalue is non-trivial and all such non-trivial values do
225+
/// not have a cleanup.
226+
///
227+
/// *NOTE* Due to 1. isPlusOne and isPlusZero both return true for
228+
/// ManagedValues consisting of only trivial values.
229+
bool isPlusZero() const;
230+
205231
SILValue getLValueAddress() const {
206232
assert(isLValue() && "This isn't an lvalue");
207233
return getValue();

lib/SILGen/RValue.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -788,20 +788,13 @@ void RValue::verify(SILGenFunction &SGF) const & {
788788
}
789789

790790
bool RValue::isPlusOne(SILGenFunction &SGF) const & {
791-
return llvm::all_of(values, [&SGF](ManagedValue mv) -> bool {
792-
// Ignore trivial values and objects with trivial value ownership kind.
793-
if (mv.getType().isTrivial(SGF.F.getModule()) ||
794-
(mv.getType().isObject() &&
795-
mv.getOwnershipKind() == ValueOwnershipKind::Trivial))
796-
return true;
797-
return mv.hasCleanup();
798-
});
791+
return llvm::all_of(
792+
values, [&SGF](ManagedValue mv) -> bool { return mv.isPlusOne(SGF); });
799793
}
800794

801795
bool RValue::isPlusZero(SILGenFunction &SGF) const & {
802-
return llvm::none_of(values, [](ManagedValue mv) -> bool {
803-
return mv.hasCleanup();
804-
});
796+
return llvm::none_of(values,
797+
[](ManagedValue mv) -> bool { return mv.isPlusZero(); });
805798
}
806799

807800
const TypeLowering &RValue::getTypeLowering(SILGenFunction &SGF) const & {

0 commit comments

Comments
 (0)