Skip to content
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
6 changes: 4 additions & 2 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -797,9 +797,11 @@ class SILBuilder {
}

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

ThinFunctionToPointerInst *
Expand Down
8 changes: 4 additions & 4 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -984,10 +984,10 @@ template <typename ImplClass>
void SILCloner<ImplClass>::visitConvertEscapeToNoEscapeInst(
ConvertEscapeToNoEscapeInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst, getBuilder().createConvertEscapeToNoEscape(
getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand()),
getOpType(Inst->getType())));
doPostProcess(
Inst, getBuilder().createConvertEscapeToNoEscape(
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
getOpType(Inst->getType()), Inst->isLifetimeGuaranteed()));
}

template<typename ImplClass>
Expand Down
16 changes: 12 additions & 4 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3916,18 +3916,26 @@ class ConvertEscapeToNoEscapeInst final
ConvertEscapeToNoEscapeInst, ConversionInst> {
friend SILBuilder;

bool lifetimeGuaranteed;

ConvertEscapeToNoEscapeInst(SILDebugLocation DebugLoc, SILValue Operand,
ArrayRef<SILValue> TypeDependentOperands,
SILType Ty)
ArrayRef<SILValue> TypeDependentOperands,
SILType Ty, bool isLifetimeGuaranteed)
: UnaryInstructionWithTypeDependentOperandsBase(
DebugLoc, Operand, TypeDependentOperands, Ty) {
DebugLoc, Operand, TypeDependentOperands, Ty),
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);
SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes,
bool lifetimeGuaranteed);
public:
bool isLifetimeGuaranteed() const {
return lifetimeGuaranteed;
}
};

/// ThinFunctionToPointerInst - Convert a thin function pointer to a
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t VERSION_MINOR = 402; // Last change: effects(releasenone)
const uint16_t VERSION_MINOR = 407; // Last change: convert_escape_to_noescape

using DeclIDField = BCFixed<31>;

Expand Down
3 changes: 2 additions & 1 deletion lib/IRGen/LoadableByAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2494,7 +2494,8 @@ void LoadableByAddress::recreateConvInstrs() {
case SILInstructionKind::ConvertEscapeToNoEscapeInst: {
auto instr = cast<ConvertEscapeToNoEscapeInst>(convInstr);
newInstr = convBuilder.createConvertEscapeToNoEscape(
instr->getLoc(), instr->getOperand(), newType);
instr->getLoc(), instr->getOperand(), newType,
instr->isLifetimeGuaranteed());
break;
}
case SILInstructionKind::MarkDependenceInst: {
Expand Down
6 changes: 5 additions & 1 deletion lib/ParseSIL/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2947,6 +2947,10 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
SILType Ty;
Identifier ToToken;
SourceLoc ToLoc;
bool guaranteed = true;
if (Opcode == SILInstructionKind::ConvertEscapeToNoEscapeInst)
if(parseSILOptional(guaranteed, *this, "not_guaranteed"))
return true;
if (parseTypedValueRef(Val, B) ||
parseSILIdentifier(ToToken, ToLoc,
diag::expected_tok_in_sil_instr, "to") ||
Expand Down Expand Up @@ -2980,7 +2984,7 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
ResultVal = B.createConvertFunction(InstLoc, Val, Ty);
break;
case SILInstructionKind::ConvertEscapeToNoEscapeInst:
ResultVal = B.createConvertEscapeToNoEscape(InstLoc, Val, Ty);
ResultVal = B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, guaranteed);
break;
case SILInstructionKind::AddressToPointerInst:
ResultVal = B.createAddressToPointer(InstLoc, Val, Ty);
Expand Down
4 changes: 2 additions & 2 deletions lib/SIL/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1998,7 +1998,7 @@ ConvertFunctionInst::create(SILDebugLocation DebugLoc, SILValue Operand,

ConvertEscapeToNoEscapeInst *ConvertEscapeToNoEscapeInst::create(
SILDebugLocation DebugLoc, SILValue Operand, SILType Ty, SILFunction &F,
SILOpenedArchetypesState &OpenedArchetypes) {
SILOpenedArchetypesState &OpenedArchetypes, bool isLifetimeGuaranteed) {
SILModule &Mod = F.getModule();
SmallVector<SILValue, 8> TypeDependentOperands;
collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
Expand All @@ -2007,7 +2007,7 @@ ConvertEscapeToNoEscapeInst *ConvertEscapeToNoEscapeInst::create(
totalSizeToAlloc<swift::Operand>(1 + TypeDependentOperands.size());
void *Buffer = Mod.allocateInst(size, alignof(ConvertEscapeToNoEscapeInst));
auto *CFI = ::new (Buffer) ConvertEscapeToNoEscapeInst(
DebugLoc, Operand, TypeDependentOperands, Ty);
DebugLoc, Operand, TypeDependentOperands, Ty, isLifetimeGuaranteed);
// If we do not have lowered SIL, make sure that are not performing
// ABI-incompatible conversions.
//
Expand Down
3 changes: 2 additions & 1 deletion lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1435,7 +1435,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
printUncheckedConversionInst(CI, CI->getOperand());
}
void visitConvertEscapeToNoEscapeInst(ConvertEscapeToNoEscapeInst *CI) {
printUncheckedConversionInst(CI, CI->getOperand());
*this << (CI->isLifetimeGuaranteed() ? "" : "[not_guaranteed] ")
<< getIDAndType(CI->getOperand()) << " to " << CI->getType();
}
void visitThinFunctionToPointerInst(ThinFunctionToPointerInst *CI) {
printUncheckedConversionInst(CI, CI->getOperand());
Expand Down
14 changes: 5 additions & 9 deletions lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -925,23 +925,19 @@ SILGenFunction::emitBlockToFunc(SILLocation loc,

// Create it in the current function.
auto thunkValue = B.createFunctionRef(loc, thunk);
SingleValueInstruction *thunkedFn = B.createPartialApply(
ManagedValue thunkedFn = B.createPartialApply(
loc, thunkValue, SILType::getPrimitiveObjectType(substFnTy), subs,
block.forward(*this),
block,
SILType::getPrimitiveObjectType(loweredFuncTyWithoutNoEscape));

if (!loweredFuncTy->isNoEscape()) {
return emitManagedRValueWithCleanup(thunkedFn);
return thunkedFn;
}

// Handle the escaping to noescape conversion.
assert(loweredFuncTy->isNoEscape());

auto &funcTL = getTypeLowering(loweredFuncTy);
SingleValueInstruction *noEscapeThunkFn =
B.createConvertEscapeToNoEscape(loc, thunkedFn, funcTL.getLoweredType());
enterPostponedCleanup(thunkedFn);
return emitManagedRValueWithCleanup(noEscapeThunkFn);
return B.createConvertEscapeToNoEscape(loc, thunkedFn,
SILType::getPrimitiveObjectType(loweredFuncTy));
}

static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
Expand Down
25 changes: 25 additions & 0 deletions lib/SILGen/SILGenBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,31 @@ ManagedValue SILGenBuilder::createConvertFunction(SILLocation loc,
return cloner.clone(result);
}

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

auto fnType = fn.getType().castTo<SILFunctionType>();
auto resultFnType = resultTy.castTo<SILFunctionType>();

// Escaping to noescape conversion.
assert(resultFnType->getRepresentation() ==
SILFunctionTypeRepresentation::Thick &&
fnType->getRepresentation() ==
SILFunctionTypeRepresentation::Thick &&
!fnType->isNoEscape() && resultFnType->isNoEscape() &&
"Expect a escaping to noescape conversion");

SILValue fnValue = postponeToNoEscapeCleanup
? fn.ensurePlusOne(SGF, loc).forward(SGF)
: fn.getValue();
SILValue result = createConvertEscapeToNoEscape(loc, fnValue, resultTy,
postponeToNoEscapeCleanup);
if (postponeToNoEscapeCleanup)
getSILGenFunction().enterPostponedCleanup(fnValue);
return ManagedValue::forTrivialObjectRValue(result);
}

ManagedValue SILGenBuilder::createInitExistentialValue(
SILLocation loc, SILType existentialType, CanType formalConcreteType,
ManagedValue concrete, ArrayRef<ProtocolConformanceRef> conformances) {
Expand Down
6 changes: 6 additions & 0 deletions lib/SILGen/SILGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ class SILGenBuilder : public SILBuilder {
ManagedValue createConvertFunction(SILLocation loc, ManagedValue fn,
SILType resultTy);

using SILBuilder::createConvertEscapeToNoEscape;
ManagedValue
createConvertEscapeToNoEscape(SILLocation loc, ManagedValue fn,
SILType resultTy,
bool postponeToNoEscapeCleanup = true);

using SILBuilder::createStore;
/// Forward \p value into \p address.
///
Expand Down
7 changes: 5 additions & 2 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2090,8 +2090,11 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
if (srcRepTy != srcTy)
result = convertFunctionRepresentation(SGF, e, result, srcRepTy, srcTy);

if (srcTy != destTy)
result = SGF.emitTransformedValue(e, result, srcTy, destTy);
if (srcTy != destTy) {
bool postponeToNoEscapeCleanup = !isa<BindOptionalExpr>(e->getSubExpr());
result = SGF.emitTransformedValue(e, result, srcTy, destTy, SGFContext(),
postponeToNoEscapeCleanup);
}

if (destTy != destRepTy)
result = convertFunctionRepresentation(SGF, e, result, destTy, destRepTy);
Expand Down
6 changes: 4 additions & 2 deletions lib/SILGen/SILGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1614,15 +1614,17 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
ManagedValue emitTransformedValue(SILLocation loc, ManagedValue input,
CanType inputType,
CanType outputType,
SGFContext ctx = SGFContext());
SGFContext ctx = SGFContext(),
bool postponeToNoEscapeCleanup = true);

/// Most general form of the above.
ManagedValue emitTransformedValue(SILLocation loc, ManagedValue input,
AbstractionPattern inputOrigType,
CanType inputSubstType,
AbstractionPattern outputOrigType,
CanType outputSubstType,
SGFContext ctx = SGFContext());
SGFContext ctx = SGFContext(),
bool postponeToNoEscapeCleanup = true);
RValue emitTransformedValue(SILLocation loc, RValue &&input,
AbstractionPattern inputOrigType,
CanType inputSubstType,
Expand Down
51 changes: 24 additions & 27 deletions lib/SILGen/SILGenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ namespace {
CanType inputSubstType,
AbstractionPattern outputOrigType,
CanType outputSubstType,
SGFContext ctxt);
SGFContext ctxt,
bool postponeToNoEscapeCleanup = true);

/// Transform a metatype value.
ManagedValue transformMetatype(ManagedValue fn,
Expand All @@ -159,7 +160,8 @@ namespace {
CanAnyFunctionType inputSubstType,
AbstractionPattern outputOrigType,
CanAnyFunctionType outputSubstType,
const TypeLowering &expectedTL);
const TypeLowering &expectedTL,
bool postponeToNoEscapeCleanup = true);
};
} // end anonymous namespace
;
Expand Down Expand Up @@ -356,7 +358,8 @@ ManagedValue Transform::transform(ManagedValue v,
CanType inputSubstType,
AbstractionPattern outputOrigType,
CanType outputSubstType,
SGFContext ctxt) {
SGFContext ctxt,
bool postponeToNoEscapeCleanup) {
// Look through inout types.
if (isa<InOutType>(inputSubstType))
inputSubstType = CanType(inputSubstType->getInOutObjectType());
Expand Down Expand Up @@ -440,7 +443,8 @@ ManagedValue Transform::transform(ManagedValue v,
return transformFunction(v,
inputOrigType, inputFnType,
outputOrigType, outputFnType,
expectedTL);
expectedTL,
postponeToNoEscapeCleanup);
}

// - tuples of transformable values
Expand Down Expand Up @@ -2917,22 +2921,20 @@ static ManagedValue createThunk(SILGenFunction &SGF,

// Create it in our current function.
auto thunkValue = SGF.B.createFunctionRef(loc, thunk);
SingleValueInstruction *thunkedFn =
ManagedValue thunkedFn =
SGF.B.createPartialApply(loc, thunkValue,
SILType::getPrimitiveObjectType(substFnType),
subs, fn.ensurePlusOne(SGF, loc).forward(SGF),
subs, fn.ensurePlusOne(SGF, loc),
SILType::getPrimitiveObjectType(toType));

if (!expectedType->isNoEscape()) {
return SGF.emitManagedRValueWithCleanup(thunkedFn, expectedTL);
return thunkedFn;
}

// Handle the escaping to noescape conversion.
assert(expectedType->isNoEscape());
SingleValueInstruction *noEscapeThunkFn = SGF.B.createConvertEscapeToNoEscape(
loc, thunkedFn, expectedTL.getLoweredType());
SGF.enterPostponedCleanup(thunkedFn);
return SGF.emitManagedRValueWithCleanup(noEscapeThunkFn);
return SGF.B.createConvertEscapeToNoEscape(loc, thunkedFn,
SILType::getPrimitiveObjectType(expectedType));
}

static CanSILFunctionType buildWithoutActuallyEscapingThunkType(
Expand Down Expand Up @@ -3128,7 +3130,8 @@ ManagedValue Transform::transformFunction(ManagedValue fn,
CanAnyFunctionType inputSubstType,
AbstractionPattern outputOrigType,
CanAnyFunctionType outputSubstType,
const TypeLowering &expectedTL) {
const TypeLowering &expectedTL,
bool postponeToNoEscapeCleanup) {
assert(fn.getType().isObject() &&
"expected input to emitTransformedFunctionValue to be loaded");

Expand Down Expand Up @@ -3186,18 +3189,9 @@ ManagedValue Transform::transformFunction(ManagedValue fn,
SGF.B.createThinToThickFunction(Loc, fn.forward(SGF), resTy));
} else if (newFnType != expectedFnType) {
// Escaping to noescape conversion.
assert(expectedFnType->getRepresentation() ==
SILFunctionTypeRepresentation::Thick &&
fnType->getRepresentation() ==
SILFunctionTypeRepresentation::Thick &&
!fnType->isNoEscape() && expectedFnType->isNoEscape() &&
"Expect a escaping to noescape conversion");
SILType resTy = SILType::getPrimitiveObjectType(expectedFnType);
auto fnValue = fn.forward(SGF);
SGF.enterPostponedCleanup(fnValue);
SingleValueInstruction *noEscapeThunkFn =
SGF.B.createConvertEscapeToNoEscape(Loc, fnValue, resTy);
fn = SGF.emitManagedRValueWithCleanup(noEscapeThunkFn);
fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy,
postponeToNoEscapeCleanup);
}

return fn;
Expand Down Expand Up @@ -3293,11 +3287,12 @@ ManagedValue
SILGenFunction::emitTransformedValue(SILLocation loc, ManagedValue v,
CanType inputType,
CanType outputType,
SGFContext ctxt) {
SGFContext ctxt,
bool postponeToNoEscapeCleanup) {
return emitTransformedValue(loc, v,
AbstractionPattern(inputType), inputType,
AbstractionPattern(outputType), outputType,
ctxt);
ctxt, postponeToNoEscapeCleanup);
}

ManagedValue
Expand All @@ -3306,12 +3301,14 @@ SILGenFunction::emitTransformedValue(SILLocation loc, ManagedValue v,
CanType inputSubstType,
AbstractionPattern outputOrigType,
CanType outputSubstType,
SGFContext ctxt) {
SGFContext ctxt,
bool postponeToNoEscapeCleanup) {
return Transform(*this, loc).transform(v,
inputOrigType,
inputSubstType,
outputOrigType,
outputSubstType, ctxt);
outputSubstType, ctxt,
postponeToNoEscapeCleanup);
}

RValue
Expand Down
4 changes: 2 additions & 2 deletions lib/SILOptimizer/IPO/ClosureSpecializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,8 +662,8 @@ SILValue ClosureSpecCloner::cloneCalleeConversion(SILValue calleeValue,

auto *Cvt = cast<ConvertEscapeToNoEscapeInst>(calleeValue);
calleeValue = cloneCalleeConversion(Cvt->getOperand(), NewClosure, Builder);
return Builder.createConvertEscapeToNoEscape(CallSiteDesc.getLoc(),
calleeValue, Cvt->getType());
return Builder.createConvertEscapeToNoEscape(
CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), true);
}

/// \brief Populate the body of the cloned closure, modifying instructions as
Expand Down
Loading