Skip to content

SIL: Remove isEscapedByUser flag on convert_escape_to_noescape instruction #21637

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
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
4 changes: 2 additions & 2 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,10 +927,10 @@ class SILBuilder {

ConvertEscapeToNoEscapeInst *
createConvertEscapeToNoEscape(SILLocation Loc, SILValue Op, SILType Ty,
bool isEscapedByUser, bool lifetimeGuaranteed) {
bool lifetimeGuaranteed) {
return insert(ConvertEscapeToNoEscapeInst::create(
getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes,
isEscapedByUser, lifetimeGuaranteed));
lifetimeGuaranteed));
}

ThinFunctionToPointerInst *
Expand Down
3 changes: 1 addition & 2 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1267,8 +1267,7 @@ void SILCloner<ImplClass>::visitConvertEscapeToNoEscapeInst(
recordClonedInstruction(
Inst, getBuilder().createConvertEscapeToNoEscape(
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
getOpType(Inst->getType()), Inst->isEscapedByUser(),
Inst->isLifetimeGuaranteed()));
getOpType(Inst->getType()), Inst->isLifetimeGuaranteed()));
}

template<typename ImplClass>
Expand Down
16 changes: 3 additions & 13 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4037,36 +4037,26 @@ class ConvertEscapeToNoEscapeInst final
friend SILBuilder;

bool lifetimeGuaranteed;
bool isEscaped; // Even if we can analyze this
// instruction the user might have
// escaped it.

ConvertEscapeToNoEscapeInst(SILDebugLocation DebugLoc, SILValue Operand,
ArrayRef<SILValue> TypeDependentOperands,
SILType Ty, bool isEscapedByUser,
SILType Ty,
bool isLifetimeGuaranteed)
: UnaryInstructionWithTypeDependentOperandsBase(
DebugLoc, Operand, TypeDependentOperands, Ty),
lifetimeGuaranteed(isLifetimeGuaranteed),
isEscaped(isEscapedByUser) {
lifetimeGuaranteed(isLifetimeGuaranteed) {
assert(!Operand->getType().castTo<SILFunctionType>()->isNoEscape());
assert(Ty.castTo<SILFunctionType>()->isNoEscape());
}

static ConvertEscapeToNoEscapeInst *
create(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes,
bool isEscapedByUser, bool lifetimeGuaranteed);
bool lifetimeGuaranteed);
public:
bool isLifetimeGuaranteed() const {
return lifetimeGuaranteed;
}

bool isEscapedByUser() const {
return isEscaped;
}

void setEscapedByUser(bool isEscaped = true) { this->isEscaped = isEscaped; }
};

/// ThinFunctionToPointerInst - Convert a thin function pointer to a
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/LoadableByAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2632,7 +2632,7 @@ void LoadableByAddress::recreateConvInstrs() {
auto instr = cast<ConvertEscapeToNoEscapeInst>(convInstr);
newInstr = convBuilder.createConvertEscapeToNoEscape(
instr->getLoc(), instr->getOperand(), newType,
instr->isEscapedByUser(), instr->isLifetimeGuaranteed());
instr->isLifetimeGuaranteed());
break;
}
case SILInstructionKind::MarkDependenceInst: {
Expand Down
11 changes: 3 additions & 8 deletions lib/ParseSIL/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3120,20 +3120,15 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
Identifier ToToken;
SourceLoc ToLoc;
bool not_guaranteed = false;
bool escaped = false;
bool without_actually_escaping = false;
if (Opcode == SILInstructionKind::ConvertEscapeToNoEscapeInst) {
StringRef attrName;
if (parseSILOptional(attrName, *this)) {
if (attrName.equals("escaped"))
escaped = true;
else if (attrName.equals("not_guaranteed"))
if (attrName.equals("not_guaranteed"))
not_guaranteed = true;
else
return true;
}
if (parseSILOptional(escaped, *this, "escaped"))
return true;
}
if (parseTypedValueRef(Val, B)
|| parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
Expand Down Expand Up @@ -3178,8 +3173,8 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
B.createConvertFunction(InstLoc, Val, Ty, without_actually_escaping);
break;
case SILInstructionKind::ConvertEscapeToNoEscapeInst:
ResultVal = B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, escaped,
!not_guaranteed);
ResultVal =
B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, !not_guaranteed);
break;
case SILInstructionKind::AddressToPointerInst:
ResultVal = B.createAddressToPointer(InstLoc, Val, Ty);
Expand Down
8 changes: 3 additions & 5 deletions lib/SIL/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1993,18 +1993,16 @@ ConvertFunctionInst *ConvertFunctionInst::create(

ConvertEscapeToNoEscapeInst *ConvertEscapeToNoEscapeInst::create(
SILDebugLocation DebugLoc, SILValue Operand, SILType Ty, SILFunction &F,
SILOpenedArchetypesState &OpenedArchetypes, bool isEscapedByUser,
bool isLifetimeGuaranteed) {
SILOpenedArchetypesState &OpenedArchetypes, bool isLifetimeGuaranteed) {
SILModule &Mod = F.getModule();
SmallVector<SILValue, 8> TypeDependentOperands;
collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
Ty.getASTType());
unsigned size =
totalSizeToAlloc<swift::Operand>(1 + TypeDependentOperands.size());
void *Buffer = Mod.allocateInst(size, alignof(ConvertEscapeToNoEscapeInst));
auto *CFI = ::new (Buffer)
ConvertEscapeToNoEscapeInst(DebugLoc, Operand, TypeDependentOperands, Ty,
isEscapedByUser, isLifetimeGuaranteed);
auto *CFI = ::new (Buffer) ConvertEscapeToNoEscapeInst(
DebugLoc, Operand, TypeDependentOperands, Ty, isLifetimeGuaranteed);
// If we do not have lowered SIL, make sure that are not performing
// ABI-incompatible conversions.
//
Expand Down
1 change: 0 additions & 1 deletion lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,6 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
}
void visitConvertEscapeToNoEscapeInst(ConvertEscapeToNoEscapeInst *CI) {
*this << (CI->isLifetimeGuaranteed() ? "" : "[not_guaranteed] ")
<< (CI->isEscapedByUser() ? "[escaped] " : "")
<< getIDAndType(CI->getOperand()) << " to " << CI->getType();
}
void visitThinFunctionToPointerInst(ThinFunctionToPointerInst *CI) {
Expand Down
3 changes: 0 additions & 3 deletions lib/SIL/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3683,9 +3683,6 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
// '[not_guaranteed]' or '[escaped]' attributes.
if (!SkipConvertEscapeToNoescapeAttributes &&
F.getModule().getStage() != SILStage::Raw) {
require(!ICI->isEscapedByUser(),
"convert_escape_to_noescape [escaped] not "
"allowed after mandatory passes");
require(ICI->isLifetimeGuaranteed(),
"convert_escape_to_noescape [not_guaranteed] not "
"allowed after mandatory passes");
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ SILGenFunction::emitBlockToFunc(SILLocation loc,
// Handle the escaping to noescape conversion.
assert(loweredFuncTy->isNoEscape());
return B.createConvertEscapeToNoEscape(
loc, thunkedFn, SILType::getPrimitiveObjectType(loweredFuncTy), false);
loc, thunkedFn, SILType::getPrimitiveObjectType(loweredFuncTy));
}

static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
Expand Down
7 changes: 3 additions & 4 deletions lib/SILGen/SILGenBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ SILGenBuilder::createConvertFunction(SILLocation loc, ManagedValue fn,
}

ManagedValue SILGenBuilder::createConvertEscapeToNoEscape(
SILLocation loc, ManagedValue fn, SILType resultTy,
bool isEscapedByUser) {
SILLocation loc, ManagedValue fn, SILType resultTy) {

auto fnType = fn.getType().castTo<SILFunctionType>();
auto resultFnType = resultTy.castTo<SILFunctionType>();
Expand All @@ -234,8 +233,8 @@ ManagedValue SILGenBuilder::createConvertEscapeToNoEscape(
(void)fnType;
(void)resultFnType;
SILValue fnValue = fn.getValue();
SILValue result = createConvertEscapeToNoEscape(
loc, fnValue, resultTy, isEscapedByUser, false);
SILValue result =
createConvertEscapeToNoEscape(loc, fnValue, resultTy, false);
return ManagedValue::forTrivialObjectRValue(result);
}

Expand Down
3 changes: 1 addition & 2 deletions lib/SILGen/SILGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,7 @@ class SILGenBuilder : public SILBuilder {
using SILBuilder::createConvertEscapeToNoEscape;
ManagedValue
createConvertEscapeToNoEscape(SILLocation loc, ManagedValue fn,
SILType resultTy,
bool isEscapedByUser);
SILType resultTy);

using SILBuilder::createStore;
/// Forward \p value into \p address.
Expand Down
4 changes: 2 additions & 2 deletions lib/SILGen/SILGenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3181,7 +3181,7 @@ static ManagedValue createThunk(SILGenFunction &SGF,
// Handle the escaping to noescape conversion.
assert(expectedType->isNoEscape());
return SGF.B.createConvertEscapeToNoEscape(
loc, thunkedFn, SILType::getPrimitiveObjectType(expectedType), false);
loc, thunkedFn, SILType::getPrimitiveObjectType(expectedType));
}

static CanSILFunctionType buildWithoutActuallyEscapingThunkType(
Expand Down Expand Up @@ -3355,7 +3355,7 @@ ManagedValue Transform::transformFunction(ManagedValue fn,
} else if (newFnType != expectedFnType) {
// Escaping to noescape conversion.
SILType resTy = SILType::getPrimitiveObjectType(expectedFnType);
fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy, false);
fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy);
}

return fn;
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/IPO/ClosureSpecializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ SILValue ClosureSpecCloner::cloneCalleeConversion(
calleeValue = cloneCalleeConversion(Cvt->getOperand(), NewClosure, Builder,
NeedsRelease);
return Builder.createConvertEscapeToNoEscape(
CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), false, true);
CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), true);
}

/// Populate the body of the cloned closure, modifying instructions as
Expand Down
16 changes: 3 additions & 13 deletions lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static void extendLifetimeToEndOfFunction(SILFunction &Fn,

SILBuilderWithScope B(Cvt);
auto NewCvt = B.createConvertEscapeToNoEscape(
Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
Cvt->replaceAllUsesWith(NewCvt);
Cvt->eraseFromParent();
Cvt = NewCvt;
Expand Down Expand Up @@ -189,11 +189,6 @@ static SILInstruction *lookThroughRebastractionUsers(
static bool tryExtendLifetimeToLastUse(
ConvertEscapeToNoEscapeInst *Cvt,
llvm::DenseMap<SILInstruction *, SILInstruction *> &Memoized) {
// Don't optimize converts that might have been escaped by the function call
// (materializeForSet 'escapes' its arguments into the writeback buffer).
if (Cvt->isEscapedByUser())
return false;

// If there is a single user that is an apply this is simple: extend the
// lifetime of the operand until after the apply.
auto SingleUser = lookThroughRebastractionUsers(Cvt, Memoized);
Expand All @@ -215,7 +210,7 @@ static bool tryExtendLifetimeToLastUse(
{
SILBuilderWithScope B(Cvt);
auto NewCvt = B.createConvertEscapeToNoEscape(
Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
Cvt->replaceAllUsesWith(NewCvt);
Cvt->eraseFromParent();
Cvt = NewCvt;
Expand Down Expand Up @@ -264,11 +259,6 @@ static bool tryExtendLifetimeToLastUse(
/// diamonds. And a destroy of %closure at the last destroy of
/// %convertOptionalBlock.
static bool trySwitchEnumPeephole(ConvertEscapeToNoEscapeInst *Cvt) {
// Don't optimize converts that might have been escaped by the function call
// (materializeForSet 'escapes' its arguments into the writeback buffer).
if (Cvt->isEscapedByUser())
return false;

auto *blockArg = dyn_cast<SILArgument>(Cvt->getOperand());
if (!blockArg)
return false;
Expand Down Expand Up @@ -314,7 +304,7 @@ static bool trySwitchEnumPeephole(ConvertEscapeToNoEscapeInst *Cvt) {
{
SILBuilderWithScope B(Cvt);
auto NewCvt = B.createConvertEscapeToNoEscape(
Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
Cvt->replaceAllUsesWith(NewCvt);
Cvt->eraseFromParent();
}
Expand Down
3 changes: 1 addition & 2 deletions lib/Serialization/DeserializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1180,12 +1180,11 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
"Layout should be OneTypeOneOperand.");
bool isLifetimeGuaranteed = Attr & 0x01;
bool isEscaped = Attr & 0x02;
ResultVal = Builder.createConvertEscapeToNoEscape(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2)),
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory), isEscaped,
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory),
isLifetimeGuaranteed);
break;
}
Expand Down
2 changes: 0 additions & 2 deletions lib/Serialization/SerializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1489,8 +1489,6 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
if (SI.getKind() == SILInstructionKind::ConvertEscapeToNoEscapeInst) {
if (cast<ConvertEscapeToNoEscapeInst>(SI).isLifetimeGuaranteed())
attrs |= 0x01;
if (cast<ConvertEscapeToNoEscapeInst>(SI).isEscapedByUser())
attrs |= 0x02;
}
if (SI.getKind() == SILInstructionKind::ConvertFunctionInst) {
if (cast<ConvertFunctionInst>(SI).withoutActuallyEscaping())
Expand Down
4 changes: 0 additions & 4 deletions test/SIL/Parser/basic.sil
Original file line number Diff line number Diff line change
Expand Up @@ -1344,15 +1344,11 @@ entry(%0 : $@convention(thin) (AnyObject) -> Optional<AnyObject>):
// CHECK-LABEL: sil @convert_function_trivial
// CHECK: %1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
// CHECK: %2 = convert_escape_to_noescape [not_guaranteed] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
// CHECK: %3 = convert_escape_to_noescape [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
// CHECK: %4 = convert_escape_to_noescape [not_guaranteed] [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
// CHECK: return
sil @convert_function_trivial : $@convention(thin) (@owned @callee_guaranteed (AnyObject) -> Optional<AnyObject>) -> () {
entry(%0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject>):
%1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
%2 = convert_escape_to_noescape [not_guaranteed] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
%3 = convert_escape_to_noescape [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
%4 = convert_escape_to_noescape [not_guaranteed] [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
return undef : $()
}

Expand Down
4 changes: 0 additions & 4 deletions test/Serialization/sil_partial_apply_ownership.sil
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,13 @@ sil @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
// CHECK-LABEL: sil @partial_apply_convert
// CHECK: convert_escape_to_noescape %{{.*}} : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: convert_escape_to_noescape [not_guaranteed] %
// CHECK: convert_escape_to_noescape [escaped] %
// CHECK: convert_escape_to_noescape [not_guaranteed] [escaped] %
sil @partial_apply_convert : $@convention(thin) () -> () {
entry:
%f = function_ref @subject : $@convention(thin) (Builtin.Int64) -> ()
%z = integer_literal $Builtin.Int64, 0
%e = partial_apply [callee_guaranteed] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
%n = convert_escape_to_noescape %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
%x2 = convert_escape_to_noescape [not_guaranteed] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
%x3 = convert_escape_to_noescape [escaped] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
%x4 = convert_escape_to_noescape [not_guaranteed] [escaped] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
%n2 = mark_dependence %n : $@noescape @callee_guaranteed () -> () on %e : $@callee_guaranteed () -> ()
%f2 = function_ref @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
apply %f2(%n2) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
Expand Down