Skip to content

[pull] swiftwasm from main #3813

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 18 commits into from
Oct 30, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
bc09cc9
[SILGen] Handled foreign funcs with async, error, and more.
nate-chandler Oct 28, 2021
e400a96
GSB: Loosen up verifyGenericSignature()
slavapestov Oct 29, 2021
153654c
GSB: Perform conditional requirement inference in AbstractGenericSign…
slavapestov Oct 29, 2021
22609ac
Merge pull request #39957 from nate-chandler/rdar80704984_2
nate-chandler Oct 29, 2021
f9122a7
[moveOnly] Implement a new _copy function that performs an explicit c…
gottesmm Oct 29, 2021
3a5049f
[stdlib] Mark _move as public.
gottesmm Oct 29, 2021
89e0f45
[Result Builders] Correct type witness substitution when computing in…
hborla Oct 29, 2021
06fbca6
Merge pull request #39983 from slavapestov/gsb-conditional-inference
slavapestov Oct 30, 2021
17def18
[Result Builders] When inferring result builder attributes on value w…
hborla Oct 30, 2021
3ea9e9e
Merge pull request #39984 from gottesmm/pr-135d6a4f34ad56ff7b7f978fdb…
gottesmm Oct 30, 2021
f38f25a
AST: Factor out AbstractGenericSignatureRequest into a new buildGener…
slavapestov Oct 30, 2021
ee5a3fe
AST: AbstractGenericSignatureRequest and InferredGenericSignatureRequ…
slavapestov Oct 30, 2021
25ac1f5
AST: Refactor verifyGenericSignature() to use AbstractGenericSignatur…
slavapestov Oct 30, 2021
0eb6622
AST: Move expensive generic signature checks to GenericSignature.cpp
slavapestov Oct 30, 2021
0d167a4
AST: Move GenericSignatureBuilder.h from include/swift/AST/ to lib/AST/
slavapestov Oct 30, 2021
c31a590
Merge pull request #39988 from hborla/result-builder-attr-substitution
hborla Oct 30, 2021
0251957
[SE-0320] Added protocol CodingKeyRepresentable (#34458)
mortenbekditlevsen Oct 30, 2021
78de7d1
Merge pull request #39990 from slavapestov/completely-encapsulate-gsb
slavapestov Oct 30, 2021
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
30 changes: 30 additions & 0 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5205,6 +5205,36 @@ independent of the operand. In terms of specific types:
In ownership qualified functions, a ``copy_value`` produces a +1 value that must
be consumed at most once along any path through the program.

explicit_copy_value
```````````````````

::

sil-instruction ::= 'explicit_copy_value' sil-operand

%1 = explicit_copy_value %0 : $A

Performs a copy of a loadable value as if by the value's type lowering and
returns the copy. The returned copy semantically is a value that is completely
independent of the operand. In terms of specific types:

1. For trivial types, this is equivalent to just propagating through the trivial
value.
2. For reference types, this is equivalent to performing a ``strong_retain``
operation and returning the reference.
3. For ``@unowned`` types, this is equivalent to performing an
``unowned_retain`` and returning the operand.
4. For aggregate types, this is equivalent to recursively performing a
``copy_value`` on its components, forming a new aggregate from the copied
components, and then returning the new aggregate.

In ownership qualified functions, a ``explicit_copy_value`` produces a +1 value
that must be consumed at most once along any path through the program.

When move only variable checking is performed, ``explicit_copy_value`` is
treated as an explicit copy asked for by the user that should not be rewritten
and should be treated as a non-consuming use.

move_value
``````````

Expand Down
18 changes: 18 additions & 0 deletions include/swift/AST/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,24 @@ BUILTIN_MISC_OPERATION(DestroyTaskGroup,
/// the SILVerifier.
BUILTIN_MISC_OPERATION(Move, "move", "", Special)

/// A builtin that can only be called from a transparent generic function. Takes
/// two operands, the first operand the result address, the second operand the
/// input address. Transforms into
///
/// %input = load [take] %inputAddr
/// %result = explicit_copy_value %input
/// store %result to [init] %resultAddr
/// store %input to [init] %inputAddr
///
/// transparently inlined into a caller that has the generic of the callee
/// specialized into a loadable type. If the transparent inlining does not
/// specialize the type (due to being inlined into a non-generic context, the
/// SILVerifier will abort).
///
/// Illegal to call except for in Swift._copy in the stdlib. This is enforced by
/// the SILVerifier.
BUILTIN_MISC_OPERATION(Copy, "copy", "", Special)

// BUILTIN_MISC_OPERATION_WITH_SILGEN - Miscellaneous operations that are
// specially emitted during SIL generation.
//
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,10 @@ NOTE(capturepromotion_variable_defined_here,none,
ERROR(move_operator_used_on_generic_or_existential_value, none,
"move() used on a generic or existential value", ())

// copy operator used on generic or evalue
ERROR(copy_operator_used_on_generic_or_existential_value, none,
"copy() used on a generic or existential value", ())

// noimplicitcopy on generic or existential binding
ERROR(noimplicitcopy_used_on_generic_or_existential, none,
"@_noImplicitCopy can not be used on a generic or existential typed "
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/SemanticAttrs.def
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ SEMANTICS_ATTR(FORCE_EMIT_OPT_REMARK_PREFIX, "optremark")
SEMANTICS_ATTR(OBJC_FORBID_ASSOCIATED_OBJECTS, "objc.forbidAssociatedObjects")

SEMANTICS_ATTR(LIFETIMEMANAGEMENT_MOVE, "lifetimemanagement.move")
SEMANTICS_ATTR(LIFETIMEMANAGEMENT_COPY, "lifetimemanagement.copy")

SEMANTICS_ATTR(NO_PERFORMANCE_ANALYSIS, "no_performance_analysis")

Expand Down
1 change: 1 addition & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ LANGUAGE_FEATURE(BuiltinBuildExecutor, 0, "Executor-building builtins", true)
LANGUAGE_FEATURE(BuiltinBuildMainExecutor, 0, "MainActor executor building builtin", true)
LANGUAGE_FEATURE(BuiltinCreateAsyncTaskInGroup, 0, "MainActor executor building builtin", true)
LANGUAGE_FEATURE(BuiltinMove, 0, "Builtin.move()", true)
LANGUAGE_FEATURE(BuiltinCopy, 0, "Builtin.copy()", true)

#undef LANGUAGE_FEATURE
9 changes: 9 additions & 0 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,15 @@ class SILBuilder {
CopyValueInst(getSILDebugLocation(Loc), operand));
}

ExplicitCopyValueInst *createExplicitCopyValue(SILLocation Loc,
SILValue operand) {
assert(!operand->getType().isTrivial(getFunction()) &&
"Should not be passing trivial values to this api. Use instead "
"emitCopyValueOperation");
return insert(new (getModule())
ExplicitCopyValueInst(getSILDebugLocation(Loc), operand));
}

DestroyValueInst *createDestroyValue(SILLocation Loc, SILValue operand,
bool poisonRefs = false) {
assert(isLoadableOrOpaque(operand->getType()));
Expand Down
15 changes: 15 additions & 0 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,21 @@ void SILCloner<ImplClass>::visitCopyValueInst(CopyValueInst *Inst) {
getOpValue(Inst->getOperand())));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitExplicitCopyValueInst(
ExplicitCopyValueInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
if (!getBuilder().hasOwnership()) {
SILValue newValue = getBuilder().emitCopyValueOperation(
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()));
return recordFoldedValue(Inst, newValue);
}

recordClonedInstruction(
Inst, getBuilder().createExplicitCopyValue(
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitMoveValueInst(MoveValueInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
Expand Down
9 changes: 9 additions & 0 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -7267,6 +7267,15 @@ class CopyValueInst
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
};

class ExplicitCopyValueInst
: public UnaryInstructionBase<SILInstructionKind::ExplicitCopyValueInst,
SingleValueInstruction> {
friend class SILBuilder;

ExplicitCopyValueInst(SILDebugLocation DebugLoc, SILValue operand)
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
};

#define UNCHECKED_REF_STORAGE(Name, ...) \
class StrongCopy##Name##ValueInst \
: public UnaryInstructionBase< \
Expand Down
4 changes: 4 additions & 0 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,10 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
// A copy_value's retain semantics are fully encapsulated in OSSA
// invariants. It has no side effects relative to other OSSA values.
BRIDGED_SINGLE_VALUE_INST(CopyValueInst, copy_value,
SingleValueInstruction, None, DoesNotRelease)
// A copy_value instruction that was explicitly asked for by the user. Left
// alone by OSSA optimizations.
SINGLE_VALUE_INST(ExplicitCopyValueInst, explicit_copy_value,
SingleValueInstruction, None, DoesNotRelease)
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \
Expand Down
2 changes: 2 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2816,6 +2816,8 @@ static bool usesFeatureBuiltinMove(Decl *decl) {
return false;
}

static bool usesFeatureBuiltinCopy(Decl *decl) { return false; }

static bool usesFeatureInheritActorContext(Decl *decl) {
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
for (auto param : *func->getParameters()) {
Expand Down
10 changes: 10 additions & 0 deletions lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,11 @@ static ValueDecl *getMoveOperation(ASTContext &ctx, Identifier id) {
_parameters(_owned(_typeparam(0))), _typeparam(0));
}

static ValueDecl *getCopyOperation(ASTContext &ctx, Identifier id) {
return getBuiltinFunction(ctx, id, _thin, _generics(_unrestricted),
_parameters(_typeparam(0)), _typeparam(0));
}

static ValueDecl *getTransferArrayOperation(ASTContext &ctx, Identifier id) {
return getBuiltinFunction(ctx, id, _thin,
_generics(_unrestricted),
Expand Down Expand Up @@ -2528,6 +2533,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
return nullptr;
return getMoveOperation(Context, Id);

case BuiltinValueKind::Copy:
if (!Types.empty())
return nullptr;
return getCopyOperation(Context, Id);

#define BUILTIN(id, name, Attrs)
#define BUILTIN_BINARY_OPERATION(id, name, attrs)
#define BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(id, name, attrs, overload) \
Expand Down
8 changes: 6 additions & 2 deletions lib/AST/GenericSignatureBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2377,8 +2377,7 @@ GenericSignatureBuilder::resolveConcreteConformance(ResolvedType type,
bool hasExplicitSource = llvm::any_of(
equivClass->concreteTypeConstraints,
[](const ConcreteConstraint &constraint) {
return (!constraint.source->isDerivedRequirement() &&
constraint.source->getLoc().isValid());
return !constraint.source->isDerivedRequirement();
});

if (hasExplicitSource) {
Expand Down Expand Up @@ -8513,6 +8512,11 @@ void GenericSignatureBuilder::verifyGenericSignature(ASTContext &context,
std::move(builder).computeGenericSignature(
/*allowConcreteGenericParams=*/true);

// If the new signature once again contains the removed requirement, it's
// not redundant.
if (newSig->isEqual(sig))
continue;

// If the removed requirement is satisfied by the new generic signature,
// it is redundant. Complain.
if (newSig->isRequirementSatisfied(requirements[victimIndex])) {
Expand Down
11 changes: 11 additions & 0 deletions lib/IRGen/GenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,5 +1319,16 @@ if (Builtin.ID == BuiltinValueKind::id) { \
return;
}

if (Builtin.ID == BuiltinValueKind::Copy) {
auto input = args.claimNext();
auto result = args.claimNext();
SILType addrTy = argTypes[0];
const TypeInfo &addrTI = IGF.getTypeInfo(addrTy);
Address inputAttr = addrTI.getAddressForPointer(input);
Address resultAttr = addrTI.getAddressForPointer(result);
addrTI.initializeWithCopy(IGF, resultAttr, inputAttr, addrTy, false);
return;
}

llvm_unreachable("IRGen unimplemented for this builtin!");
}
3 changes: 3 additions & 0 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,9 @@ class IRGenSILFunction :
void visitRetainValueInst(RetainValueInst *i);
void visitRetainValueAddrInst(RetainValueAddrInst *i);
void visitCopyValueInst(CopyValueInst *i);
void visitExplicitCopyValueInst(ExplicitCopyValueInst *i) {
llvm_unreachable("Valid only when ownership is enabled");
}
void visitMoveValueInst(MoveValueInst *i) {
auto e = getLoweredExplosion(i->getOperand());
setLoweredExplosion(i, e);
Expand Down
2 changes: 2 additions & 0 deletions lib/SIL/IR/OperandOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ OPERAND_OWNERSHIP(InstantaneousUse, SetDeallocating)
OPERAND_OWNERSHIP(UnownedInstantaneousUse, DebugValue)
OPERAND_OWNERSHIP(UnownedInstantaneousUse, CopyBlock)
OPERAND_OWNERSHIP(UnownedInstantaneousUse, CopyValue)
OPERAND_OWNERSHIP(UnownedInstantaneousUse, ExplicitCopyValue)
OPERAND_OWNERSHIP(UnownedInstantaneousUse, ObjCMethod)
OPERAND_OWNERSHIP(UnownedInstantaneousUse, ObjCSuperMethod)
OPERAND_OWNERSHIP(UnownedInstantaneousUse, UnmanagedRetainValue)
Expand Down Expand Up @@ -776,6 +777,7 @@ BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, GlobalStringTablePointer)
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, TypePtrAuthDiscriminator)
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, IntInstrprofIncrement)
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, Move)
BUILTIN_OPERAND_OWNERSHIP(UnownedInstantaneousUse, Copy)
BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, StartAsyncLet)
BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, EndAsyncLet)
BUILTIN_OPERAND_OWNERSHIP(DestroyingConsume, StartAsyncLetWithLocalBuffer)
Expand Down
4 changes: 4 additions & 0 deletions lib/SIL/IR/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
*this << getIDAndType(I->getOperand());
}

void visitExplicitCopyValueInst(ExplicitCopyValueInst *I) {
*this << getIDAndType(I->getOperand());
}

void visitMoveValueInst(MoveValueInst *I) {
*this << getIDAndType(I->getOperand());
}
Expand Down
2 changes: 2 additions & 0 deletions lib/SIL/IR/ValueOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ CONSTANT_OWNERSHIP_INST(Owned, AllocRefDynamic)
CONSTANT_OWNERSHIP_INST(Owned, CopyBlock)
CONSTANT_OWNERSHIP_INST(Owned, CopyBlockWithoutEscaping)
CONSTANT_OWNERSHIP_INST(Owned, CopyValue)
CONSTANT_OWNERSHIP_INST(Owned, ExplicitCopyValue)
CONSTANT_OWNERSHIP_INST(Owned, MoveValue)
CONSTANT_OWNERSHIP_INST(Owned, EndCOWMutation)
CONSTANT_OWNERSHIP_INST(Owned, KeyPath)
Expand Down Expand Up @@ -557,6 +558,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, EndAsyncLetLifetime)
CONSTANT_OWNERSHIP_BUILTIN(None, CreateTaskGroup)
CONSTANT_OWNERSHIP_BUILTIN(None, DestroyTaskGroup)
CONSTANT_OWNERSHIP_BUILTIN(None, Move)
CONSTANT_OWNERSHIP_BUILTIN(None, Copy)

#undef CONSTANT_OWNERSHIP_BUILTIN

Expand Down
1 change: 1 addition & 0 deletions lib/SIL/Parser/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3138,6 +3138,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
UNARY_INSTRUCTION(IsUnique)
UNARY_INSTRUCTION(DestroyAddr)
UNARY_INSTRUCTION(CopyValue)
UNARY_INSTRUCTION(ExplicitCopyValue)
UNARY_INSTRUCTION(MoveValue)
UNARY_INSTRUCTION(EndBorrow)
UNARY_INSTRUCTION(DestructureStruct)
Expand Down
1 change: 1 addition & 0 deletions lib/SIL/Utils/InstructionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
case SILInstructionKind::RetainValueInst:
case SILInstructionKind::BeginCOWMutationInst:
case SILInstructionKind::CopyValueInst:
case SILInstructionKind::ExplicitCopyValueInst:
case SILInstructionKind::SetDeallocatingInst:
case SILInstructionKind::IsUniqueInst:
case SILInstructionKind::IsEscapingClosureInst:
Expand Down
4 changes: 2 additions & 2 deletions lib/SIL/Utils/MemAccessUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2191,9 +2191,9 @@ static void visitBuiltinAddress(BuiltinInst *builtin,
visitor(&builtin->getAllOperands()[2]);
return;

// This consumes its second parameter (the arg) and takes/places that value
// into the first parameter (the result).
// These effect both operands.
case BuiltinValueKind::Move:
case BuiltinValueKind::Copy:
visitor(&builtin->getAllOperands()[1]);
return;

Expand Down
16 changes: 16 additions & 0 deletions lib/SIL/Verifier/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2001,6 +2001,22 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
require(BI->getFunction()->hasSemanticsAttr(semanticName),
"_move used within a generic context");
}

if (builtinKind == BuiltinValueKind::Copy) {
// We expect that this builtin will be specialized during transparent
// inlining into explicit_copy_value if we inline into a non-generic
// context. If the builtin still remains and is not in the specific copy
// semantic function (which is the only function marked with
// semantics::LIFETIMEMANAGEMENT_COPY), then we know that we did
// transparent inlining into a function that did not result in the Builtin
// being specialized out which is user error.
//
// NOTE: Once we have opaque values, this restriction will go away. This
// is just so we can call Builtin.copy outside of the stdlib.
auto semanticName = semantics::LIFETIMEMANAGEMENT_COPY;
require(BI->getFunction()->hasSemanticsAttr(semanticName),
"_copy used within a generic context");
}
}

void checkFunctionRefBaseInst(FunctionRefBaseInst *FRI) {
Expand Down
Loading