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 @@ -794,9 +794,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 @@ -3951,18 +3951,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 @@ -56,7 +56,7 @@ const uint16_t VERSION_MAJOR = 0;
/// 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 = 406; // Last change: EnumElementDecl resilience expansion
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 @@ -2495,7 +2495,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 @@ -2979,6 +2979,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 @@ -3012,7 +3016,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
17 changes: 11 additions & 6 deletions lib/SILGen/SILGenBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,10 @@ ManagedValue SILGenBuilder::createConvertFunction(SILLocation loc,
return cloner.clone(result);
}

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

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

Expand All @@ -221,9 +222,13 @@ ManagedValue SILGenBuilder::createConvertEscapeToNoEscape(SILLocation loc,
!fnType->isNoEscape() && resultFnType->isNoEscape() &&
"Expect a escaping to noescape conversion");

SILValue fnValue = fn.ensurePlusOne(SGF, loc).forward(SGF);
SILValue result = createConvertEscapeToNoEscape(loc, fnValue, resultTy);
getSILGenFunction().enterPostponedCleanup(fnValue);
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);
}

Expand Down
6 changes: 4 additions & 2 deletions lib/SILGen/SILGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,10 @@ class SILGenBuilder : public SILBuilder {
SILType resultTy);

using SILBuilder::createConvertEscapeToNoEscape;
ManagedValue createConvertEscapeToNoEscape(SILLocation loc, ManagedValue fn,
SILType resultTy);
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 @@ -1617,15 +1617,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
29 changes: 19 additions & 10 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 @@ -3041,7 +3045,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 @@ -3100,7 +3105,8 @@ 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);
fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy,
postponeToNoEscapeCleanup);
}

return fn;
Expand Down Expand Up @@ -3196,11 +3202,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 @@ -3209,12 +3216,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