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
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ private struct CollectedEffects {
addEffects(.destroy, to: inst.operands[0].value, fromInitialPath: SmallProjectionPath(.anyValueFields))

case is ReturnInst:
if inst.parentFunction.convention.hasGuaranteedAddressResult {
if inst.parentFunction.convention.hasAddressResult {
addEffects(.read, to: inst.operands[0].value)
}

Expand Down
4 changes: 0 additions & 4 deletions SwiftCompilerSources/Sources/SIL/ApplySite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,6 @@ extension ApplySite {
public var hasGuaranteedResult: Bool {
functionConvention.hasGuaranteedResult
}

public var hasGuaranteedAddressResult: Bool {
functionConvention.hasGuaranteedAddressResult
}
}

extension ApplySite {
Expand Down
4 changes: 2 additions & 2 deletions SwiftCompilerSources/Sources/SIL/Argument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,8 @@ public enum ArgumentConvention : CustomStringConvertible {
self = .directUnowned
case .pack:
self = .packOut
case .guaranteed, .guaranteedAddress:
fatalError("Result conventions @guaranteed and @guaranteed_addr are always returned directly")
case .guaranteed, .guaranteedAddress, .inout:
fatalError("Result conventions @guaranteed, @guaranteed_address and @inout are always returned directly")
}
}

Expand Down
23 changes: 18 additions & 5 deletions SwiftCompilerSources/Sources/SIL/FunctionConvention.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,20 @@ public struct FunctionConvention : CustomStringConvertible {
if results.count != 1 {
return false
}
return results[0].convention == .guaranteed
if hasLoweredAddresses {
return results[0].convention == .guaranteed
}
return results[0].convention == .guaranteed || results[0].convention == .guaranteedAddress
}

public var hasGuaranteedAddressResult: Bool {
public var hasAddressResult: Bool {
if results.count != 1 {
return false
}
return results[0].convention == .guaranteedAddress
if hasLoweredAddresses {
return results[0].convention == .guaranteedAddress || results[0].convention == .inout
}
return results[0].convention == .inout
}

public var description: String {
Expand Down Expand Up @@ -147,7 +153,7 @@ public struct ResultInfo : CustomStringConvertible {
return hasLoweredAddresses || type.isExistentialArchetypeWithError()
case .pack:
return true
case .owned, .unowned, .unownedInnerPointer, .autoreleased, .guaranteed, .guaranteedAddress:
case .owned, .unowned, .unownedInnerPointer, .autoreleased, .guaranteed, .guaranteedAddress, .inout:
return false
}
}
Expand Down Expand Up @@ -373,13 +379,17 @@ public enum ResultConvention : CustomStringConvertible {
case owned

/// The caller is responsible for using the returned address within a valid
/// scope. This is valid only for borrow and mutate accessors.
/// scope. This is valid only for borrow accessors.
case guaranteedAddress

/// The caller is responsible for using the returned value within a valid
/// scope. This is valid only for borrow accessors.
case guaranteed

/// The caller is responsible for mutating the returned address within a valid
/// scope. This is valid only for mutate accessors.
case `inout`

/// The caller is not responsible for destroying this return value. Its type may be trivial, or it may simply be offered unsafely. It is valid at the instant of the return, but further operations may invalidate it.
case unowned

Expand Down Expand Up @@ -423,6 +433,8 @@ public enum ResultConvention : CustomStringConvertible {
return "guaranteed"
case .guaranteedAddress:
return "guaranteedAddress"
case .inout:
return "inout"
}
}
}
Expand Down Expand Up @@ -456,6 +468,7 @@ extension ResultConvention {
case .Pack: self = .pack
case .Guaranteed: self = .guaranteed
case .GuaranteedAddress: self = .guaranteedAddress
case .Inout: self = .inout
default:
fatalError("unsupported result convention")
}
Expand Down
3 changes: 3 additions & 0 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,9 @@ mangled in to disambiguate.
RESULT-CONVENTION ::= 'u' // unowned inner pointer
RESULT-CONVENTION ::= 'a' // auto-released
RESULT-CONVENTION ::= 'k' // pack
RESULT-CONVENTION ::= 'l' // guaranteed address
RESULT-CONVENTION ::= 'g' // guaranteed
RESULT-CONVENTION ::= 'm' // inout

RESULT-DIFFERENTIABILITY ::= 'w' // @noDerivative

Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/TypeAttr.def
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ SIMPLE_SIL_TYPE_ATTR(pack_out, PackOut)
SIMPLE_SIL_TYPE_ATTR(owned, Owned)
SIMPLE_SIL_TYPE_ATTR(unowned_inner_pointer, UnownedInnerPointer)
SIMPLE_SIL_TYPE_ATTR(guaranteed, Guaranteed)
SIMPLE_SIL_TYPE_ATTR(guaranteed_addr, GuaranteedAddress)
SIMPLE_SIL_TYPE_ATTR(guaranteed_address, GuaranteedAddress)
SIMPLE_SIL_TYPE_ATTR(autoreleased, Autoreleased)
SIMPLE_SIL_TYPE_ATTR(callee_owned, CalleeOwned)
SIMPLE_SIL_TYPE_ATTR(callee_guaranteed, CalleeGuaranteed)
Expand Down
30 changes: 21 additions & 9 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -4814,12 +4814,16 @@ enum class ResultConvention : uint8_t {
Pack,

/// The caller is responsible for using the returned address within a valid
/// scope. This is valid only for borrow and mutate accessors.
/// scope. This is valid only for borrow accessors.
GuaranteedAddress,

/// The caller is responsible for using the returned value within a valid
/// scope. This is valid only for borrow accessors.
Guaranteed,

/// The caller is responsible for mutating the returned address within a valid
/// scope. This is valid only for mutate accessors.
Inout,
};

// Does this result require indirect storage for the purpose of reabstraction?
Expand Down Expand Up @@ -4976,12 +4980,20 @@ class SILResultInfo {
return getConvention() == ResultConvention::Pack;
}

bool isGuaranteedAddressResult() const {
return getConvention() == ResultConvention::GuaranteedAddress;
bool isAddressResult(bool loweredAddresses) const {
if (loweredAddresses) {
return getConvention() == ResultConvention::GuaranteedAddress ||
getConvention() == ResultConvention::Inout;
}
return getConvention() == ResultConvention::Inout;
}

bool isGuaranteedResult() const {
return getConvention() == ResultConvention::Guaranteed;
bool isGuaranteedResult(bool loweredAddresses) const {
if (loweredAddresses) {
return getConvention() == ResultConvention::Guaranteed;
}
return getConvention() == ResultConvention::Guaranteed ||
getConvention() == ResultConvention::GuaranteedAddress;
}

/// Transform this SILResultInfo by applying the user-provided
Expand Down Expand Up @@ -5424,18 +5436,18 @@ class SILFunctionType final
return hasErrorResult() && getErrorResult().isFormalIndirect();
}

bool hasGuaranteedResult() const {
bool hasGuaranteedResult(bool loweredAddresses) const {
if (getNumResults() != 1) {
return false;
}
return getResults()[0].isGuaranteedResult();
return getResults()[0].isGuaranteedResult(loweredAddresses);
}

bool hasGuaranteedAddressResult() const {
bool hasAddressResult(bool loweredAddresses) const {
if (getNumResults() != 1) {
return false;
}
return getResults()[0].isGuaranteedAddressResult();
return getResults()[0].isAddressResult(loweredAddresses);
}

struct IndirectFormalResultFilter {
Expand Down
2 changes: 1 addition & 1 deletion include/swift/SIL/MemAccessUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ inline bool isGuaranteedAddressReturn(SILValue value) {
if (!defInst) {
return false;
}
return defInst->hasGuaranteedAddressResult();
return defInst->hasAddressResult();
}

/// Return the source address after stripping as many access projections as
Expand Down
1 change: 1 addition & 0 deletions include/swift/SIL/SILBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ enum class BridgedResultConvention {
Pack,
GuaranteedAddress,
Guaranteed,
Inout
};

struct BridgedResultInfo {
Expand Down
28 changes: 22 additions & 6 deletions include/swift/SIL/SILFunctionConventions.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ class SILFunctionConventions {
if (silConv.loweredAddresses)
return funcTy->getDirectFormalResultsType(silConv.getModule(), context);

if (funcTy->hasAddressResult(silConv.loweredAddresses)) {
assert(funcTy->getNumDirectFormalResults() == 1);
return SILType::getPrimitiveAddressType(
funcTy->getSingleDirectFormalResult().getReturnValueType(
silConv.getModule(), funcTy, context));
}

return funcTy->getAllResultsSubstType(silConv.getModule(), context);
}

Expand Down Expand Up @@ -322,16 +329,24 @@ class SILFunctionConventions {
if (funcTy->getNumResults() != 1) {
return false;
}
return funcTy->getResults()[0].getConvention() ==
ResultConvention::Guaranteed;
auto resultConvention = funcTy->getResults()[0].getConvention();
if (silConv.loweredAddresses) {
return resultConvention == ResultConvention::Guaranteed;
}
return resultConvention == ResultConvention::Guaranteed ||
resultConvention == ResultConvention::GuaranteedAddress;
}

bool hasGuaranteedAddressResult() const {
bool hasAddressResult() const {
if (funcTy->getNumResults() != 1) {
return false;
}
return funcTy->getResults()[0].getConvention() ==
ResultConvention::GuaranteedAddress;
auto resultConvention = funcTy->getResults()[0].getConvention();
if (silConv.loweredAddresses) {
return resultConvention == ResultConvention::GuaranteedAddress ||
resultConvention == ResultConvention::Inout;
}
return resultConvention == ResultConvention::Inout;
}

struct SILResultTypeFunc;
Expand Down Expand Up @@ -675,6 +690,7 @@ inline bool SILModuleConventions::isIndirectSILResult(SILResultInfo result,
case ResultConvention::Autoreleased:
case ResultConvention::GuaranteedAddress:
case ResultConvention::Guaranteed:
case ResultConvention::Inout:
return false;
}

Expand All @@ -699,7 +715,7 @@ inline SILType
SILModuleConventions::getSILResultInterfaceType(SILResultInfo result,
bool loweredAddresses) {
return SILModuleConventions::isIndirectSILResult(result, loweredAddresses) ||
result.isGuaranteedAddressResult()
result.isAddressResult(loweredAddresses)
? SILType::getPrimitiveAddressType(result.getInterfaceType())
: SILType::getPrimitiveObjectType(result.getInterfaceType());
}
Expand Down
5 changes: 3 additions & 2 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3154,8 +3154,9 @@ class ApplyInst final
bool hasGuaranteedResult() const {
return getSubstCalleeConv().hasGuaranteedResult();
}
bool hasGuaranteedAddressResult() const {
return getSubstCalleeConv().hasGuaranteedAddressResult();

bool hasAddressResult() const {
return getSubstCalleeConv().hasAddressResult();
}
};

Expand Down
8 changes: 5 additions & 3 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2288,10 +2288,12 @@ static char getResultConvention(ResultConvention conv) {
case ResultConvention::Autoreleased: return 'a';
case ResultConvention::Pack: return 'k';
case ResultConvention::GuaranteedAddress:
return 'g';
return 'l';
case ResultConvention::Guaranteed:
return 'G';
}
return 'g';
case ResultConvention::Inout:
return 'm';
}
llvm_unreachable("bad result convention");
}

Expand Down
4 changes: 3 additions & 1 deletion lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7941,9 +7941,11 @@ static StringRef getStringForResultConvention(ResultConvention conv) {
case ResultConvention::Autoreleased: return "@autoreleased ";
case ResultConvention::Pack: return "@pack_out ";
case ResultConvention::GuaranteedAddress:
return "@guaranteed_addr ";
return "@guaranteed_address ";
case ResultConvention::Guaranteed:
return "@guaranteed ";
case ResultConvention::Inout:
return "@inout ";
}
llvm_unreachable("bad result convention");
}
Expand Down
9 changes: 9 additions & 0 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2296,6 +2296,15 @@ NodePointer Demangler::demangleImplResultConvention(Node::Kind ConvKind) {
case 'u': attr = "@unowned_inner_pointer"; break;
case 'a': attr = "@autoreleased"; break;
case 'k': attr = "@pack_out"; break;
case 'l':
attr = "@guaranteed_address";
break;
case 'g':
attr = "@guaranteed";
break;
case 'm':
attr = "@inout";
break;
default:
pushBack();
return nullptr;
Expand Down
20 changes: 12 additions & 8 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2226,14 +2226,18 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
Buffer << 'z';
LLVM_FALLTHROUGH;
case Node::Kind::ImplResult: {
char ConvCh = llvm::StringSwitch<char>(Child->getFirstChild()->getText())
.Case("@out", 'r')
.Case("@owned", 'o')
.Case("@unowned", 'd')
.Case("@unowned_inner_pointer", 'u')
.Case("@autoreleased", 'a')
.Case("@pack_out", 'k')
.Default(0);
char ConvCh =
llvm::StringSwitch<char>(Child->getFirstChild()->getText())
.Case("@out", 'r')
.Case("@owned", 'o')
.Case("@unowned", 'd')
.Case("@unowned_inner_pointer", 'u')
.Case("@autoreleased", 'a')
.Case("@pack_out", 'k')
.Case("@guaranteed_address", 'l')
.Case("@guaranteed", 'g')
.Case("@inout", 'm')
.Default(0);
if (!ConvCh) {
return MANGLING_ERROR(ManglingError::InvalidImplParameterConvention,
Child->getFirstChild());
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/CallEmission.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class CallEmission {
virtual void emitCallToUnmappedExplosion(llvm::CallBase *call,
Explosion &out) = 0;
void emitYieldsToExplosion(Explosion &out);
void emitGuaranteedAddressToExplosion(Explosion &out);
void emitAddressResultToExplosion(Explosion &out);
void setKeyPathAccessorArguments(Explosion &in, bool isOutlined,
Explosion &out);
virtual FunctionPointer getCalleeFunctionPointer() = 0;
Expand Down
Loading