Skip to content

[pull] swiftwasm from main #4091

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
Jan 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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: 4 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ final public class DeallocStackInst : Instruction, UnaryInstruction {
}
}

final public class DeallocStackRefInst : Instruction, UnaryInstruction {
public var allocRef: AllocRefInst { operand as! AllocRefInst }
}

final public class CondFailInst : Instruction, UnaryInstruction {
public override var mayTrap: Bool { true }

Expand Down
1 change: 1 addition & 0 deletions SwiftCompilerSources/Sources/SIL/Registration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public func registerSILClasses() {
register(EndAccessInst.self)
register(EndBorrowInst.self)
register(DeallocStackInst.self)
register(DeallocStackRefInst.self)
register(CondFailInst.self)
register(FixLifetimeInst.self)
register(DebugValueInst.self)
Expand Down
6 changes: 4 additions & 2 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -737,15 +737,17 @@ implementation details of a function type.
::

#if SWIFT_VERSION >= 5.1
type ::= 'Qr' // opaque result type (of current decl)
type ::= 'Qr' // opaque result type (of current decl, used for the first opaque type parameter only)
type ::= 'QR' INDEX // same as above, for subsequent opaque type parameters, INDEX is the ordinal -1
type ::= opaque-type-decl-name bound-generic-args 'Qo' INDEX // opaque type

opaque-type-decl-name ::= entity 'QO' // opaque result type of specified decl
#endif

#if SWIFT_VERSION >= 5.4
type ::= 'Qu' // opaque result type (of current decl)
type ::= 'Qu' // opaque result type (of current decl, first param)
// used for ObjC class runtime name purposes.
type ::= 'QU' INDEX
#endif

Opaque return types have a special short representation in the mangling of
Expand Down
20 changes: 16 additions & 4 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3143,8 +3143,8 @@ optional ``objc`` attribute indicates that the object should be
allocated using Objective-C's allocation methods (``+allocWithZone:``).

The optional ``stack`` attribute indicates that the object can be allocated
on the stack instead on the heap. In this case the instruction must have
balanced with a ``dealloc_ref [stack]`` instruction to mark the end of the
on the stack instead on the heap. In this case the instruction must be
balanced with a ``dealloc_stack_ref`` instruction to mark the end of the
object's lifetime.
Note that the ``stack`` attribute only specifies that stack allocation is
possible. The final decision on stack allocation is done during llvm IR
Expand Down Expand Up @@ -3381,13 +3381,25 @@ project_box

Given a ``@box T`` reference, produces the address of the value inside the box.

dealloc_stack_ref
`````````````````
::

sil-instruction ::= 'dealloc_stack_ref' sil-operand

dealloc_stack_ref %0 : $T
// $T must be a class type
// %0 must be an 'alloc_ref [stack]' instruction

Marks the deallocation of the stack space for an ``alloc_ref [stack]``.

dealloc_ref
```````````
::

sil-instruction ::= 'dealloc_ref' ('[' 'stack' ']')? sil-operand
sil-instruction ::= 'dealloc_ref' sil-operand

dealloc_ref [stack] %0 : $T
dealloc_ref %0 : $T
// $T must be a class type

Deallocates an uninitialized class type instance, bypassing the reference
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1514,6 +1514,9 @@ ERROR(access_control_extension_open,none,
ERROR(access_control_open_bad_decl,none,
"only classes and overridable class members can be declared 'open';"
" use 'public'", ())
WARNING(access_control_non_objc_open_member,none,
"non-'@objc' %0 in extensions cannot be overridden; use 'public' instead",
(DescriptiveDeclKind))

ERROR(invalid_decl_attribute,none,
"'%0' attribute cannot be applied to this declaration", (DeclAttribute))
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Demangling/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -329,5 +329,8 @@ NODE(AsyncSuspendResumePartialFunction)
// Added in Swift 5.6
NODE(AccessibleFunctionRecord)

// Added in Swift 5.7
NODE(OpaqueReturnTypeIndexed)

#undef CONTEXT_NODE
#undef NODE
10 changes: 7 additions & 3 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2005,10 +2005,14 @@ class SILBuilder {
return insert(new (getModule())
DeallocStackInst(getSILDebugLocation(Loc), operand));
}
DeallocRefInst *createDeallocRef(SILLocation Loc, SILValue operand,
bool canBeOnStack) {
DeallocStackRefInst *createDeallocStackRef(SILLocation Loc,
SILValue operand) {
return insert(new (getModule())
DeallocStackRefInst(getSILDebugLocation(Loc), operand));
}
DeallocRefInst *createDeallocRef(SILLocation Loc, SILValue operand) {
return insert(new (getModule()) DeallocRefInst(
getSILDebugLocation(Loc), operand, canBeOnStack));
getSILDebugLocation(Loc), operand));
}
DeallocPartialRefInst *createDeallocPartialRef(SILLocation Loc,
SILValue operand,
Expand Down
12 changes: 10 additions & 2 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -2488,8 +2488,16 @@ SILCloner<ImplClass>::visitDeallocRefInst(DeallocRefInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
recordClonedInstruction(
Inst, getBuilder().createDeallocRef(getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand()),
Inst->canAllocOnStack()));
getOpValue(Inst->getOperand())));
}

template<typename ImplClass>
void
SILCloner<ImplClass>::visitDeallocStackRefInst(DeallocStackRefInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
recordClonedInstruction(
Inst, getBuilder().createDeallocStackRef(getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand())));
}

template<typename ImplClass>
Expand Down
29 changes: 14 additions & 15 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -7619,6 +7619,18 @@ class DeallocStackInst :
: UnaryInstructionBase(DebugLoc, operand) {}
};

/// Like DeallocStackInst, but for `alloc_ref [stack]`.
class DeallocStackRefInst
: public UnaryInstructionBase<SILInstructionKind::DeallocStackRefInst,
DeallocationInst> {
friend SILBuilder;

DeallocStackRefInst(SILDebugLocation DebugLoc, SILValue Operand)
: UnaryInstructionBase(DebugLoc, Operand) {}
public:
AllocRefInst *getAllocRef() { return cast<AllocRefInst>(getOperand()); }
};

/// Deallocate memory for a reference type instance from a destructor or
/// failure path of a constructor.
///
Expand All @@ -7632,21 +7644,8 @@ class DeallocRefInst :
DeallocationInst> {
friend SILBuilder;

private:
DeallocRefInst(SILDebugLocation DebugLoc, SILValue Operand,
bool canBeOnStack = false)
: UnaryInstructionBase(DebugLoc, Operand) {
SILNode::Bits.DeallocRefInst.OnStack = canBeOnStack;
}

public:
bool canAllocOnStack() const {
return SILNode::Bits.DeallocRefInst.OnStack;
}

void setStackAllocatable(bool OnStack) {
SILNode::Bits.DeallocRefInst.OnStack = OnStack;
}
DeallocRefInst(SILDebugLocation DebugLoc, SILValue Operand)
: UnaryInstructionBase(DebugLoc, Operand) { }
};

/// Deallocate memory for a reference type instance from a failure path of a
Expand Down
4 changes: 0 additions & 4 deletions include/swift/SIL/SILNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,6 @@ class alignas(8) SILNode :
Length : 32
);

SWIFT_INLINE_BITFIELD(DeallocRefInst, DeallocationInst, 1,
OnStack : 1
);

// Ensure that AllocBoxInst bitfield does not overflow.
IBWTO_BITFIELD_EMPTY(AllocBoxInst, AllocationInst);
// Ensure that AllocExistentialBoxInst bitfield does not overflow.
Expand Down
2 changes: 2 additions & 0 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,8 @@ ABSTRACT_INST(TermInst, SILInstruction)
ABSTRACT_INST(DeallocationInst, SILInstruction)
BRIDGED_NON_VALUE_INST(DeallocStackInst, dealloc_stack,
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
BRIDGED_NON_VALUE_INST(DeallocStackRefInst, dealloc_stack_ref,
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
BRIDGED_NON_VALUE_INST(DeallocRefInst, dealloc_ref,
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
NON_VALUE_INST(DeallocPartialRefInst, dealloc_partial_ref,
Expand Down
3 changes: 2 additions & 1 deletion include/swift/SILOptimizer/Utils/ValueLifetime.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ class ValueLifetimeAnalysis {
(hasUsersBeforeDef || bb != getDefValueParentBlock());
}

/// Checks if there is a dealloc_ref inside the value's live range.
/// Checks if there is a dealloc_ref or dealloc_stack_ref inside the
/// value's live range.
bool containsDeallocRef(const FrontierImpl &frontier);

/// For debug dumping.
Expand Down
14 changes: 10 additions & 4 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,9 +831,11 @@ std::string ASTMangler::mangleOpaqueTypeDecl(const OpaqueTypeDecl *decl) {
}

std::string ASTMangler::mangleOpaqueTypeDecl(const ValueDecl *decl) {
DWARFMangling = true;
OptimizeProtocolNames = false;
return mangleDeclAsUSR(decl, MANGLING_PREFIX_STR);

beginMangling();
appendEntity(decl);
return finalize();
}

std::string ASTMangler::mangleGenericSignature(const GenericSignature sig) {
Expand Down Expand Up @@ -1318,7 +1320,10 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
auto opaqueDecl = opaqueType->getDecl();
if (opaqueDecl->getNamingDecl() == forDecl) {
assert(opaqueType->getSubstitutions().isIdentity());
return appendOperator("Qr");
if (opaqueType->getOrdinal() == 0)
return appendOperator("Qr");

return appendOperator("QR", Index(opaqueType->getOrdinal() - 1));
}

// Otherwise, try to substitute it.
Expand Down Expand Up @@ -1358,7 +1363,8 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
addTypeSubstitution(nestedType, sig);
return;
}


// FIXME: Never actually used.
appendType(nestedType->getParent(), sig, forDecl);
appendIdentifier(nestedType->getName().str());
appendOperator("Qa");
Expand Down
4 changes: 3 additions & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2943,7 +2943,9 @@ TypeRepr *ValueDecl::getOpaqueResultTypeRepr() const {

OpaqueTypeDecl *ValueDecl::getOpaqueResultTypeDecl() const {
if (getOpaqueResultTypeRepr() == nullptr) {
if (isa<ModuleDecl>(this))
if (!isa<VarDecl>(this) &&
!isa<FuncDecl>(this) &&
!isa<SubscriptDecl>(this))
return nullptr;
auto file = cast<FileUnit>(getDeclContext()->getModuleScopeContext());
// Don't look up when the decl is from source, otherwise a cycle will happen.
Expand Down
12 changes: 10 additions & 2 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9866,13 +9866,21 @@ void ClangImporter::Implementation::loadAllMembersOfRecordDecl(
llvm::SmallVector<Decl *, 16> members;
for (const clang::Decl *m : clangRecord->decls()) {
auto nd = dyn_cast<clang::NamedDecl>(m);
if (!nd)
continue;

// Currently, we don't import unnamed bitfields.
if (isa<clang::FieldDecl>(m) &&
cast<clang::FieldDecl>(m)->isUnnamedBitfield())
continue;

if (nd && nd == nd->getCanonicalDecl() &&
nd->getDeclContext() == clangRecord &&
// Make sure we always pull in record fields. Everything else had better
// be canonical. Note that this check mostly catches nested C++ types since
// we import nested C struct types by C's usual convention of chucking them
// into the global namespace.
const bool isCanonicalInContext =
(isa<clang::FieldDecl>(nd) || nd == nd->getCanonicalDecl());
if (isCanonicalInContext && nd->getDeclContext() == clangRecord &&
isVisibleClangEntry(nd))
insertMembersAndAlternates(nd, members);
}
Expand Down
6 changes: 6 additions & 0 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,12 @@ NodePointer Demangler::demangleArchetype() {
case 'r': {
return createType(createNode(Node::Kind::OpaqueReturnType));
}
case 'R': {
int ordinal = demangleIndex();
if (ordinal < 0)
return NULL;
return createType(createNode(Node::Kind::OpaqueReturnTypeIndexed, ordinal));
}

case 'x': {
NodePointer T = demangleAssociatedTypeSimple(nullptr);
Expand Down
2 changes: 2 additions & 0 deletions lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ class NodePrinter {
case Node::Kind::OpaqueType:
case Node::Kind::OpaqueTypeDescriptorSymbolicReference:
case Node::Kind::OpaqueReturnType:
case Node::Kind::OpaqueReturnTypeIndexed:
case Node::Kind::OpaqueReturnTypeOf:
case Node::Kind::CanonicalSpecializedGenericMetaclass:
case Node::Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction:
Expand Down Expand Up @@ -2817,6 +2818,7 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
Printer << ")";
return nullptr;
case Node::Kind::OpaqueReturnType:
case Node::Kind::OpaqueReturnTypeIndexed:
Printer << "some";
return nullptr;
case Node::Kind::OpaqueReturnTypeOf:
Expand Down
7 changes: 7 additions & 0 deletions lib/Demangling/OldDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2078,6 +2078,13 @@ class OldDemangler {
// Special mangling for opaque return type.
return Factory.createNode(Node::Kind::OpaqueReturnType);
}
if (Mangled.nextIf('U')) {
// Special mangling for opaque return type.
Node::IndexType ordinal;
if (!demangleIndex(ordinal, depth))
return nullptr;
return Factory.createNode(Node::Kind::OpaqueReturnTypeIndexed, ordinal);
}
return demangleArchetypeType(depth + 1);
}
if (c == 'q') {
Expand Down
5 changes: 5 additions & 0 deletions lib/Demangling/OldRemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2643,6 +2643,11 @@ ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) {
Buffer << "Qu";
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeIndexed(Node *node, unsigned depth) {
Buffer << "QU";
mangleIndex(node->getIndex());
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node,
EntityContext &ctx,
unsigned depth) {
Expand Down
5 changes: 5 additions & 0 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3280,6 +3280,11 @@ ManglingError Remangler::mangleOpaqueReturnType(Node *node, unsigned depth) {
Buffer << "Qr";
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeIndexed(Node *node, unsigned depth) {
Buffer << "QR";
mangleIndex(node->getIndex());
return ManglingError::Success;
}
ManglingError Remangler::mangleOpaqueReturnTypeOf(Node *node, unsigned depth) {
RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1));
Buffer << "QO";
Expand Down
Loading