Skip to content

[semantic-arc] In SILGen always assign a copy_value's argument to its result. #5661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/SIL/TypeLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ namespace {
void emitDestroyValue(SILBuilder &B, SILLocation loc,
SILValue aggValue) const override {
if (B.getFunction().hasQualifiedOwnership()) {
B.emitDestroyValueAndFold(loc, aggValue);
B.createDestroyValue(loc, aggValue);
return;
}

Expand Down Expand Up @@ -838,7 +838,7 @@ namespace {
void emitDestroyValue(SILBuilder &B, SILLocation loc,
SILValue value) const override {
if (B.getFunction().hasQualifiedOwnership()) {
B.emitDestroyValueAndFold(loc, value);
B.createDestroyValue(loc, value);
return;
}
B.emitReleaseValueAndFold(loc, value);
Expand All @@ -850,7 +850,7 @@ namespace {
"This method should never be called when performing a shallow "
"destroy value.");
if (B.getFunction().hasQualifiedOwnership()) {
B.emitDestroyValueAndFold(loc, value);
B.createDestroyValue(loc, value);
return;
}
B.emitReleaseValueAndFold(loc, value);
Expand Down Expand Up @@ -896,7 +896,7 @@ namespace {
void emitDestroyValue(SILBuilder &B, SILLocation loc,
SILValue value) const override {
if (B.getFunction().hasQualifiedOwnership()) {
B.emitDestroyValueAndFold(loc, value);
B.createDestroyValue(loc, value);
return;
}
B.emitStrongReleaseAndFold(loc, value);
Expand Down
6 changes: 2 additions & 4 deletions lib/SILGen/ManagedValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ ManagedValue ManagedValue::copy(SILGenFunction &gen, SILLocation l) {
assert(!lowering.isTrivial() && "trivial value has cleanup?");

if (!lowering.isAddressOnly()) {
lowering.emitCopyValue(gen.B, l, getValue());
return gen.emitManagedRValueWithCleanup(getValue(), lowering);
return gen.emitManagedRetain(l, getValue(), lowering);
}

SILValue buf = gen.emitTemporaryAllocation(l, getType());
Expand Down Expand Up @@ -66,8 +65,7 @@ ManagedValue ManagedValue::copyUnmanaged(SILGenFunction &gen, SILLocation loc) {

SILValue result;
if (!lowering.isAddressOnly()) {
lowering.emitCopyValue(gen.B, loc, getValue());
result = getValue();
result = lowering.emitCopyValue(gen.B, loc, getValue());
} else {
result = gen.emitTemporaryAllocation(loc, getType());
gen.B.createCopyAddr(loc, getValue(), result, IsNotTake,IsInitialization);
Expand Down
6 changes: 3 additions & 3 deletions lib/SILGen/SILGenApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2344,7 +2344,7 @@ RValue SILGenFunction::emitApply(
case ParameterConvention::Direct_Owned:
// If the callee will consume the 'self' parameter, let's retain it so we
// can keep it alive.
B.emitCopyValueOperation(loc, lifetimeExtendedSelf);
lifetimeExtendedSelf = B.emitCopyValueOperation(loc, lifetimeExtendedSelf);
break;
case ParameterConvention::Direct_Guaranteed:
case ParameterConvention::Direct_Unowned:
Expand Down Expand Up @@ -2425,7 +2425,7 @@ RValue SILGenFunction::emitApply(

case ResultConvention::Unowned:
// Unretained. Retain the value.
resultTL.emitCopyValue(B, loc, result);
result = resultTL.emitCopyValue(B, loc, result);
break;
}

Expand Down Expand Up @@ -5448,7 +5448,7 @@ static SILValue emitDynamicPartialApply(SILGenFunction &gen,
// Retain 'self' because the partial apply will take ownership.
// We can't simply forward 'self' because the partial apply is conditional.
if (!self->getType().isAddress())
gen.B.emitCopyValueOperation(loc, self);
self = gen.B.emitCopyValueOperation(loc, self);

SILValue result = gen.B.createPartialApply(loc, method, method->getType(), {},
self, partialApplyTy);
Expand Down
3 changes: 1 addition & 2 deletions lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,8 +883,7 @@ static SILValue emitObjCUnconsumedArgument(SILGenFunction &gen,
return tmp;
}

lowering.emitCopyValue(gen.B, loc, arg);
return arg;
return lowering.emitCopyValue(gen.B, loc, arg);
}

/// Bridge argument types and adjust retain count conventions for an ObjC thunk.
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ static ManagedValue emitBuiltinDestroy(SILGenFunction &gen,

// Destroy the value indirectly. Canonicalization will promote to loads
// and releases if appropriate.
gen.B.emitDestroyAddrAndFold(loc, addr);
gen.B.createDestroyAddr(loc, addr);

return ManagedValue::forUnmanaged(gen.emitEmptyTuple(loc));
}
Expand Down
4 changes: 2 additions & 2 deletions lib/SILGen/SILGenConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
B.createLoad(cleanupLoc, selfLV, LoadOwnershipQualifier::Unqualified);

// Emit a retain of the loaded value, since we return it +1.
lowering.emitCopyValue(B, cleanupLoc, selfValue);
selfValue = lowering.emitCopyValue(B, cleanupLoc, selfValue);

// Inject the self value into an optional if the constructor is failable.
if (ctor->getFailability() != OTK_None) {
Expand Down Expand Up @@ -675,7 +675,7 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
}

// We have to do a retain because we are returning the pointer +1.
B.emitCopyValueOperation(cleanupLoc, selfArg);
selfArg = B.emitCopyValueOperation(cleanupLoc, selfArg);

// Inject the self value into an optional if the constructor is failable.
if (ctor->getFailability() != OTK_None) {
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenConvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ ManagedValue SILGenFunction::emitProtocolMetatypeToObject(SILLocation loc,
// reference when we use it to prevent it being released and attempting to
// deallocate itself. It doesn't matter if we ever actually clean up that
// retain though.
B.createCopyValue(loc, value);
value = B.createCopyValue(loc, value);
return ManagedValue::forUnmanaged(value);
}

Expand Down
8 changes: 4 additions & 4 deletions lib/SILGen/SILGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ namespace {
public:
CleanupClosureConstant(SILValue closure) : closure(closure) {}
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.B.emitDestroyValueAndFold(l, closure);
gen.B.emitDestroyValueOperation(l, closure);
}
};
}
Expand Down Expand Up @@ -208,7 +208,7 @@ class ReleaseValueCleanup : public Cleanup {

void emit(SILGenFunction &gen, CleanupLocation l) override {
if (v->getType().isAddress())
gen.B.emitDestroyAddrAndFold(l, v);
gen.B.createDestroyAddr(l, v);
else
gen.B.emitDestroyValueOperation(l, v);
}
Expand Down Expand Up @@ -1304,7 +1304,7 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
// For a heap variable, the box is responsible for the value. We just need
// to give up our retain count on it.
if (loc.box) {
B.emitDestroyValueAndFold(silLoc, loc.box);
B.emitDestroyValueOperation(silLoc, loc.box);
return;
}

Expand All @@ -1314,7 +1314,7 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
if (!Val->getType().isAddress())
B.emitDestroyValueOperation(silLoc, Val);
else
B.emitDestroyAddrAndFold(silLoc, Val);
B.createDestroyAddr(silLoc, Val);
}

void SILGenFunction::deallocateUninitializedLocalVariable(SILLocation silLoc,
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenDestructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ void SILGenFunction::emitClassMemberDestruction(SILValue selfValue,
if (!ti.isTrivial()) {
SILValue addr = B.createRefElementAddr(cleanupLoc, selfValue, vd,
ti.getLoweredType().getAddressType());
B.emitDestroyAddrAndFold(cleanupLoc, addr);
B.createDestroyAddr(cleanupLoc, addr);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenDynamicCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ namespace {
SGFContext ctx) {
// Retain the result if this is copy-on-success.
if (!shouldTakeOnSuccess(consumption))
origTargetTL.emitCopyValue(SGF.B, Loc, value);
value = origTargetTL.emitCopyValue(SGF.B, Loc, value);

// Enter a cleanup for the +1 result.
ManagedValue result
Expand Down
7 changes: 3 additions & 4 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ManagedValue SILGenFunction::emitManagedRetain(SILLocation loc,
return ManagedValue::forUnmanaged(v);
assert(!lowering.isAddressOnly() && "cannot retain an unloadable type");

lowering.emitCopyValue(B, loc, v);
v = lowering.emitCopyValue(B, loc, v);
return emitManagedRValueWithCleanup(v, lowering);
}

Expand Down Expand Up @@ -546,7 +546,7 @@ emitRValueWithAccessor(SILGenFunction &SGF, SILLocation loc,
case AddressorKind::Owning:
case AddressorKind::NativeOwning:
// Emit the release immediately.
SGF.B.emitDestroyValueAndFold(loc, addressorResult.second.forward(SGF));
SGF.B.emitDestroyValueOperation(loc, addressorResult.second.forward(SGF));
break;
case AddressorKind::NativePinning:
// Emit the unpin immediately.
Expand Down Expand Up @@ -3234,8 +3234,7 @@ class AutoreleasingWritebackComponent : public LogicalPathComponent {
auto strongType = SILType::getPrimitiveObjectType(
unowned->getType().castTo<UnmanagedStorageType>().getReferentType());
auto owned = gen.B.createUnmanagedToRef(loc, unowned, strongType);
gen.B.createCopyValue(loc, owned);
auto ownedMV = gen.emitManagedRValueWithCleanup(owned);
auto ownedMV = gen.emitManagedRetain(loc, owned);

// Reassign the +1 storage with it.
ownedMV.assignInto(gen, loc, base.getUnmanagedValue());
Expand Down
5 changes: 2 additions & 3 deletions lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
}

// Just retain a by-val let.
B.emitCopyValueOperation(loc, Val);
Val = B.emitCopyValueOperation(loc, Val);
} else {
// If we have a mutable binding for a 'let', such as 'self' in an
// 'init' method, load it.
Expand Down Expand Up @@ -321,8 +321,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
if (canGuarantee) {
capturedArgs.push_back(ManagedValue::forUnmanaged(vl.box));
} else {
B.createCopyValue(loc, vl.box);
capturedArgs.push_back(emitManagedRValueWithCleanup(vl.box));
capturedArgs.push_back(emitManagedRetain(loc, vl.box));
}
escapesToMark.push_back(vl.value);
} else {
Expand Down
20 changes: 9 additions & 11 deletions lib/SILGen/SILGenLValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,7 @@ namespace {
// we've still got a release active.
SILValue baseValue = (isFinal ? base.forward(gen) : base.getValue());
if (!isFinal)
gen.B.createCopyValue(loc, baseValue);
baseValue = gen.B.createCopyValue(loc, baseValue);

gen.B.createStrongUnpin(loc, baseValue, Atomicity::Atomic);
}
Expand Down Expand Up @@ -2162,8 +2162,7 @@ SILValue SILGenFunction::emitConversionToSemanticRValue(SILLocation loc,
auto result = B.createUnmanagedToRef(loc, src,
SILType::getPrimitiveObjectType(unmanagedType.getReferentType()));
// SEMANTIC ARC TODO: Does this need a cleanup?
B.createCopyValue(loc, result);
return result;
return B.createCopyValue(loc, result);
}

llvm_unreachable("unexpected storage type that differs from type-of-rvalue");
Expand Down Expand Up @@ -2207,8 +2206,7 @@ static SILValue emitLoadOfSemanticRValue(SILGenFunction &gen,
auto result = gen.B.createUnmanagedToRef(loc, value,
SILType::getPrimitiveObjectType(unmanagedType.getReferentType()));
// SEMANTIC ARC TODO: Does this need a cleanup?
gen.B.createCopyValue(loc, result);
return result;
return gen.B.createCopyValue(loc, result);
}

// NSString * must be bridged to String.
Expand Down Expand Up @@ -2242,7 +2240,7 @@ static void emitStoreOfSemanticRValue(SILGenFunction &gen,
gen.B.createStoreWeak(loc, value, dest, isInit);

// store_weak doesn't take ownership of the input, so cancel it out.
gen.B.emitDestroyValueAndFold(loc, value);
gen.B.emitDestroyValueOperation(loc, value);
return;
}

Expand All @@ -2254,15 +2252,15 @@ static void emitStoreOfSemanticRValue(SILGenFunction &gen,
gen.B.createStoreUnowned(loc, value, dest, isInit);

// store_unowned doesn't take ownership of the input, so cancel it out.
gen.B.emitDestroyValueAndFold(loc, value);
gen.B.emitDestroyValueOperation(loc, value);
return;
}

auto unownedValue =
gen.B.createRefToUnowned(loc, value, storageType.getObjectType());
gen.B.createUnownedRetain(loc, unownedValue, Atomicity::Atomic);
emitUnloweredStoreOfCopy(gen.B, loc, unownedValue, dest, isInit);
gen.B.emitDestroyValueAndFold(loc, value);
gen.B.emitDestroyValueOperation(loc, value);
return;
}

Expand All @@ -2272,7 +2270,7 @@ static void emitStoreOfSemanticRValue(SILGenFunction &gen,
auto unmanagedValue =
gen.B.createRefToUnmanaged(loc, value, storageType.getObjectType());
emitUnloweredStoreOfCopy(gen.B, loc, unmanagedValue, dest, isInit);
gen.B.emitDestroyValueAndFold(loc, value);
gen.B.emitDestroyValueOperation(loc, value);
return;
}

Expand Down Expand Up @@ -2362,15 +2360,15 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,

SILValue unowned = B.createRefToUnowned(loc, semanticValue, storageType);
B.createUnownedRetain(loc, unowned, Atomicity::Atomic);
B.emitDestroyValueAndFold(loc, semanticValue);
B.emitDestroyValueOperation(loc, semanticValue);
return unowned;
}

// For @unmanaged types, place into an unmanaged box.
if (storageType.is<UnmanagedStorageType>()) {
SILValue unmanaged =
B.createRefToUnmanaged(loc, semanticValue, storageType);
B.emitDestroyValueAndFold(loc, semanticValue);
B.emitDestroyValueOperation(loc, semanticValue);
return unmanaged;
}

Expand Down
5 changes: 2 additions & 3 deletions lib/SILGen/SILGenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ static ManagedValue manageParam(SILGenFunction &gen,
// Unowned parameters are only guaranteed at the instant of the call, so we
// must retain them even if we're in a context that can accept a +0 value.
case ParameterConvention::Direct_Unowned:
gen.getTypeLowering(paramValue->getType())
paramValue = gen.getTypeLowering(paramValue->getType())
.emitCopyValue(gen.B, loc, paramValue);
SWIFT_FALLTHROUGH;
case ParameterConvention::Direct_Owned:
Expand Down Expand Up @@ -2121,8 +2121,7 @@ void ResultPlanner::execute(ArrayRef<SILValue> innerDirectResults,
"reabstraction of returns_inner_pointer function");
SWIFT_FALLTHROUGH;
case ResultConvention::Unowned:
resultTL.emitCopyValue(Gen.B, Loc, resultValue);
return Gen.emitManagedRValueWithCleanup(resultValue, resultTL);
return Gen.emitManagedRetain(Loc, resultValue, resultTL);
}
llvm_unreachable("bad result convention!");
};
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenProlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class StrongReleaseCleanup : public Cleanup {
public:
StrongReleaseCleanup(SILValue box) : box(box) {}
void emit(SILGenFunction &gen, CleanupLocation l) override {
gen.B.emitDestroyValueAndFold(l, box);
gen.B.emitDestroyValueOperation(l, box);
}
};
} // end anonymous namespace
Expand Down
17 changes: 11 additions & 6 deletions test/ClangImporter/optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ class A {
return ""
}
// CHECK-LABEL: sil hidden [thunk] @_TToFC8optional1A3foofT_GSqSS_ : $@convention(objc_method) (A) -> @autoreleased Optional<NSString>
// CHECK: bb0([[SELF:%.*]] : $A):
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[T0:%.*]] = function_ref @_TFC8optional1A3foofT_GSqSS_
// CHECK-NEXT: [[T1:%.*]] = apply [[T0]](%0)
// CHECK-NEXT: destroy_value
// CHECK-NEXT: [[T1:%.*]] = apply [[T0]]([[SELF_COPY]])
// CHECK-NEXT: destroy_value [[SELF_COPY]]
// CHECK: [[T2:%.*]] = select_enum [[T1]]
// CHECK-NEXT: cond_br [[T2]]
// Something branch: project value, translate, inject into result.
Expand All @@ -33,10 +35,13 @@ class A {

@objc func bar(x x : String?) {}
// CHECK-LABEL: sil hidden [thunk] @_TToFC8optional1A3barfT1xGSqSS__T_ : $@convention(objc_method) (Optional<NSString>, A) -> ()
// CHECK: [[T1:%.*]] = select_enum %0
// CHECK: bb0([[ARG:%.*]] : $Optional<NSString>, [[SELF:%.*]] : $A):
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[T1:%.*]] = select_enum [[ARG_COPY]]
// CHECK-NEXT: cond_br [[T1]]
// Something branch: project value, translate, inject into result.
// CHECK: [[NSSTR:%.*]] = unchecked_enum_data %0
// CHECK: [[NSSTR:%.*]] = unchecked_enum_data [[ARG_COPY]]
// CHECK: [[T0:%.*]] = function_ref @_TZFE10FoundationSS36_unconditionallyBridgeFromObjectiveCfGSqCSo8NSString_SS
// Make a temporary initialized string that we're going to clobber as part of the conversion process (?).
// CHECK-NEXT: [[NSSTR_BOX:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt.1, [[NSSTR]] : $NSString
Expand All @@ -50,8 +55,8 @@ class A {
// Continuation.
// CHECK: bb3([[T0:%.*]] : $Optional<String>):
// CHECK: [[T1:%.*]] = function_ref @_TFC8optional1A3barfT1xGSqSS__T_
// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], %1)
// CHECK-NEXT: destroy_value %1
// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[SELF_COPY]])
// CHECK-NEXT: destroy_value [[SELF_COPY]]
// CHECK-NEXT: return [[T2]] : $()
}

Expand Down
Loading