Skip to content

Add @_inlineable attribute #5570

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 2 commits into from
Nov 2, 2016
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
8 changes: 6 additions & 2 deletions include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ SIMPLE_DECL_ATTR(prefix , Prefix , OnFunc | OnOperator | DeclModifier, 24)
SIMPLE_DECL_ATTR(postfix, Postfix, OnFunc | OnOperator | DeclModifier, 25)

SIMPLE_DECL_ATTR(_transparent, Transparent,
OnFunc|OnConstructor|OnVar|OnExtension|UserInaccessible, 26)
OnFunc|OnConstructor|OnVar|UserInaccessible, 26)
SIMPLE_DECL_ATTR(requires_stored_property_inits, RequiresStoredPropertyInits,
OnClass, 27)
DECL_ATTR(autoclosure, AutoClosure, OnParam, 28)
Expand All @@ -164,9 +164,13 @@ SIMPLE_DECL_ATTR(nonobjc, NonObjC,
SIMPLE_DECL_ATTR(_fixed_layout, FixedLayout,
OnVar | OnClass | OnStruct | OnEnum | UserInaccessible, 31)

SIMPLE_DECL_ATTR(_inlineable, Inlineable,
OnVar | OnSubscript | OnFunc | OnConstructor | OnDestructor |
UserInaccessible, 32)

DECL_ATTR(_specialize, Specialize,
OnConstructor | OnFunc | AllowMultipleAttributes | LongAttribute
| UserInaccessible, 32)
| UserInaccessible, 33)

// Non-serialized attributes.

Expand Down
15 changes: 10 additions & 5 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,10 +733,6 @@ class alignas(1 << DeclAlignInBits) Decl {

bool walk(ASTWalker &walker);

/// \brief Should this declaration be treated as if annotated with transparent
/// attribute.
bool isTransparent() const;

/// \brief Return whether this declaration has been determined invalid.
bool isInvalid() const { return DeclBits.Invalid; }

Expand Down Expand Up @@ -3784,6 +3780,10 @@ class AbstractStorageDecl : public ValueDecl {
}
public:

/// \brief Should this declaration be treated as if annotated with transparent
/// attribute.
bool isTransparent() const;

/// \brief Determine whether this storage is a static member, if it
/// is a member. Currently only variables can be static.
inline bool isStatic() const; // defined in this header
Expand Down Expand Up @@ -4595,8 +4595,13 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
}

void setGenericParams(GenericParamList *GenericParams);

public:

/// \brief Should this declaration be treated as if annotated with transparent
/// attribute.
bool isTransparent() const;

void setGenericSignature(GenericSignature *GenericSig) {
assert(!this->GenericSig && "already have signature?");
this->GenericSig = GenericSig;
Expand Down
2 changes: 0 additions & 2 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -930,8 +930,6 @@ ERROR(static_functions_not_mutating,none,

ERROR(transparent_stored_property,none,
"@_transparent cannot be applied to stored properties", ())
ERROR(transparent_on_invalid_extension,none,
"@_transparent is only supported on struct and enum extensions", ())
ERROR(transparent_in_protocols_not_supported,none,
"@_transparent is not supported on declarations within protocols", ())
ERROR(transparent_in_classes_not_supported,none,
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 @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
/// in source control, you should also update the comment to briefly
/// 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.
const uint16_t VERSION_MINOR = 281; // Last change: complete witnesses
const uint16_t VERSION_MINOR = 282; // Last change: @_inlineable

using DeclID = PointerEmbeddedInt<unsigned, 31>;
using DeclIDField = BCFixed<31>;
Expand Down
14 changes: 5 additions & 9 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,19 +348,15 @@ case DeclKind::ID: return cast<ID##Decl>(this)->getLoc();
llvm_unreachable("Unknown decl kind");
}

bool Decl::isTransparent() const {
bool AbstractStorageDecl::isTransparent() const {
return getAttrs().hasAttribute<TransparentAttr>();
}

bool AbstractFunctionDecl::isTransparent() const {
// Check if the declaration had the attribute.
if (getAttrs().hasAttribute<TransparentAttr>())
return true;

// Check if this is a function declaration which is within a transparent
// extension.
if (const AbstractFunctionDecl *FD = dyn_cast<AbstractFunctionDecl>(this)) {
if (const ExtensionDecl *ED = dyn_cast<ExtensionDecl>(FD->getParent()))
if (ED->isTransparent())
return true;
}

// If this is an accessor, check if the transparent attribute was set
// on the value decl.
if (const FuncDecl *FD = dyn_cast<FuncDecl>(this)) {
Expand Down
20 changes: 15 additions & 5 deletions lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,21 +503,31 @@ bool DeclContext::isValidGenericContext() const {
/// are used.
ResilienceExpansion DeclContext::getResilienceExpansion() const {
for (const auto *dc = this; dc->isLocalContext(); dc = dc->getParent()) {
if (auto *func = dyn_cast<AbstractFunctionDecl>(dc)) {
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(dc)) {
// If the function is not externally visible, we will not be serializing
// its body.
if (!func->getDeclContext()->isLocalContext() &&
func->getEffectiveAccess() < Accessibility::Public)
if (!AFD->getDeclContext()->isLocalContext() &&
AFD->getEffectiveAccess() < Accessibility::Public)
break;

// Bodies of public transparent and always-inline functions are
// serialized, so use conservative access patterns.
if (func->isTransparent())
if (AFD->isTransparent())
return ResilienceExpansion::Minimal;

if (auto attr = func->getAttrs().getAttribute<InlineAttr>())
if (AFD->getAttrs().hasAttribute<InlineableAttr>())
return ResilienceExpansion::Minimal;

if (auto attr = AFD->getAttrs().getAttribute<InlineAttr>())
if (attr->getKind() == InlineKind::Always)
return ResilienceExpansion::Minimal;

// If a property or subscript is @_fragile, the accessors are
// @_fragile also.
if (auto FD = dyn_cast<FuncDecl>(AFD))
if (auto *ASD = FD->getAccessorStorageDecl())
if (ASD->getAttrs().getAttribute<InlineableAttr>())
return ResilienceExpansion::Minimal;
}
}

Expand Down
10 changes: 9 additions & 1 deletion lib/SIL/SILDeclRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,15 @@ bool SILDeclRef::isTransparent() const {
if (hasAutoClosureExpr())
return true;

return hasDecl() ? getDecl()->isTransparent() : false;
if (hasDecl()) {
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(getDecl()))
return AFD->isTransparent();

if (auto *ASD = dyn_cast<AbstractStorageDecl>(getDecl()))
return ASD->isTransparent();
}

return false;
}

/// \brief True if the function should have its body serialized.
Expand Down
19 changes: 6 additions & 13 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
IGNORED_ATTR(FixedLayout)
IGNORED_ATTR(Infix)
IGNORED_ATTR(Inline)
IGNORED_ATTR(Inlineable)
IGNORED_ATTR(NSApplicationMain)
IGNORED_ATTR(NSCopying)
IGNORED_ATTR(NonObjC)
Expand Down Expand Up @@ -219,15 +220,6 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
} // end anonymous namespace

void AttributeEarlyChecker::visitTransparentAttr(TransparentAttr *attr) {
if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
CanType ExtendedTy = ED->getExtendedType()->getCanonicalType();
const NominalTypeDecl *ExtendedNominal = ExtendedTy->getAnyNominal();
// Only Struct and Enum extensions can be transparent.
if (!isa<StructDecl>(ExtendedNominal) && !isa<EnumDecl>(ExtendedNominal))
return diagnoseAndRemoveAttr(attr,diag::transparent_on_invalid_extension);
return;
}

DeclContext *Ctx = D->getDeclContext();
// Protocol declarations cannot be transparent.
if (isa<ProtocolDecl>(Ctx))
Expand Down Expand Up @@ -697,18 +689,18 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {

IGNORED_ATTR(AutoClosure)
IGNORED_ATTR(Alignment)
IGNORED_ATTR(SILGenName)
IGNORED_ATTR(Convenience)
IGNORED_ATTR(Dynamic)
IGNORED_ATTR(Effects)
IGNORED_ATTR(Exported)
IGNORED_ATTR(Convenience)
IGNORED_ATTR(FixedLayout)
IGNORED_ATTR(GKInspectable)
IGNORED_ATTR(IBDesignable)
IGNORED_ATTR(IBInspectable)
IGNORED_ATTR(IBOutlet) // checked early.
IGNORED_ATTR(Indirect)
IGNORED_ATTR(Inline)
IGNORED_ATTR(Effects)
IGNORED_ATTR(FixedLayout)
IGNORED_ATTR(Inlineable)
IGNORED_ATTR(Lazy) // checked early.
IGNORED_ATTR(LLDBDebuggerFunction)
IGNORED_ATTR(Mutating)
Expand All @@ -725,6 +717,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
IGNORED_ATTR(Override)
IGNORED_ATTR(RawDocComment)
IGNORED_ATTR(Semantics)
IGNORED_ATTR(SILGenName)
IGNORED_ATTR(Transparent)
IGNORED_ATTR(SynthesizedProtocol)
IGNORED_ATTR(RequiresStoredPropertyInits)
Expand Down
1 change: 1 addition & 0 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5864,6 +5864,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
UNINTERESTING_ATTR(IBOutlet)
UNINTERESTING_ATTR(Indirect)
UNINTERESTING_ATTR(Inline)
UNINTERESTING_ATTR(Inlineable)
UNINTERESTING_ATTR(Effects)
UNINTERESTING_ATTR(FixedLayout)
UNINTERESTING_ATTR(Lazy)
Expand Down
Loading