Skip to content

Commit 7853ba0

Browse files
Merge pull request #84178 from aschwaighofer/inline_always
Add experimental feature `@inline(always)`
2 parents d6e9975 + 3447bd1 commit 7853ba0

File tree

99 files changed

+1127
-248
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+1127
-248
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AllocBoxToStack.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,8 @@ private extension ApplySite {
504504
{
505505
if self is FullApplySite,
506506
// If the function is inlined later, there is no point in specializing it.
507-
!callee.shouldOptimize || callee.inlineStrategy == .always
507+
!callee.shouldOptimize || callee.inlineStrategy == .heuristicAlways ||
508+
callee.inlineStrategy == .always
508509
{
509510
return nil
510511
}

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,9 @@ private func shouldInline(apply: FullApplySite, callee: Function, alreadyInlined
302302
return false
303303
}
304304

305-
if apply.parentFunction.isGlobalInitOnceFunction && callee.inlineStrategy == .always {
305+
if apply.parentFunction.isGlobalInitOnceFunction && (
306+
callee.inlineStrategy == .heuristicAlways ||
307+
callee.inlineStrategy == .always) {
306308
// Some arithmetic operations, like integer conversions, are not transparent but `inline(__always)`.
307309
// Force inlining them in global initializers so that it's possible to statically initialize the global.
308310
return true

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,13 +316,15 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
316316
public enum InlineStrategy {
317317
case automatic
318318
case never
319+
case heuristicAlways
319320
case always
320321
}
321322

322323
public var inlineStrategy: InlineStrategy {
323324
switch bridged.getInlineStrategy() {
324325
case .InlineDefault: return .automatic
325326
case .NoInline: return .never
327+
case .HeuristicAlwaysInline: return .heuristicAlways
326328
case .AlwaysInline: return .always
327329
default:
328330
fatalError()

include/swift/AST/AttrKind.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ llvm::StringRef getAccessLevelSpelling(AccessLevel value);
7979

8080
enum class ENUM_EXTENSIBILITY_ATTR(closed) InlineKind : uint8_t {
8181
Never SWIFT_NAME("never") = 0,
82-
Always SWIFT_NAME("always") = 1,
82+
AlwaysUnderscored SWIFT_NAME("alwaysUnderscored") = 1,
83+
Always SWIFT_NAME("always") = 2,
8384
Last_InlineKind = Always
8485
};
8586

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3094,6 +3094,10 @@ class ValueDecl : public Decl {
30943094
/// \c \@usableFromInline, \c \@inlinalbe, and \c \@_alwaysEmitIntoClient
30953095
bool isUsableFromInline() const;
30963096

3097+
// Returns \c true if this value decl is marked with an attribute that implies
3098+
// \c \@inlinable semantics: either \c \@inlinable or \c \@inline(always)
3099+
bool hasAttributeWithInlinableSemantics() const;
3100+
30973101
/// Returns \c true if this declaration is *not* intended to be used directly
30983102
/// by application developers despite the visibility.
30993103
bool shouldHideFromEditor() const;

include/swift/AST/DiagnosticsSIL.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,10 @@ ERROR(circular_transparent,none,
448448
NOTE(note_while_inlining,none,
449449
"while inlining here", ())
450450

451+
// '@inline(always)' diagnostics
452+
ERROR(circular_inlineAlways,none,
453+
"inlining '@inline(always)' functions forms circular loop", ())
454+
451455
// Pre-specializations
452456
ERROR(cannot_prespecialize,none,
453457
"Cannot pre-specialize %0", (StringRef))

include/swift/AST/DiagnosticsSema.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8924,5 +8924,16 @@ ERROR(invalid_redecl_of_file_isolation,none,
89248924
NOTE(invalid_redecl_of_file_isolation_prev,none,
89258925
"default isolation was previously declared here", ())
89268926

8927+
//===----------------------------------------------------------------------===//
8928+
// MARK: `@inline(always)` attribute
8929+
//===----------------------------------------------------------------------===//
8930+
ERROR(attr_inline_always_experimental,none,
8931+
"'@inline(always)' is an experimental feature", ())
8932+
ERROR(attr_inline_always_requires_inlinable,none,
8933+
"'@inline(always)' on public or package declarations must be used "
8934+
"together with '@inlinable'", ())
8935+
ERROR(attr_inline_always_no_usable_from_inline,none,
8936+
"cannot use '@inline(always)' together with '@usableFromInline'", ())
8937+
89278938
#define UNDEFINE_DIAGNOSTIC_MACROS
89288939
#include "DefineDiagnosticMacros.h"

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ struct PrintOptions {
403403
/// Suppress @_lifetime attribute and emit @lifetime instead.
404404
bool SuppressLifetimes = false;
405405

406+
/// Suppress @inline(always) attribute and emit @inline(__always) instead.
407+
bool SuppressInlineAlways = false;
408+
406409
/// Whether to print the \c{/*not inherited*/} comment on factory initializers.
407410
bool PrintFactoryInitializerComment = true;
408411

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ EXPERIMENTAL_FEATURE(ImportMacroAliases, true)
550550
/// Enable borrow/mutate accessors
551551
EXPERIMENTAL_FEATURE(BorrowAndMutateAccessors, false)
552552

553+
/// Allow use of @inline(always) attribute
554+
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(InlineAlways, false)
555+
553556
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
554557
#undef EXPERIMENTAL_FEATURE
555558
#undef UPCOMING_FEATURE

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ struct BridgedFunction {
470470
enum class InlineStrategy {
471471
InlineDefault,
472472
NoInline,
473+
HeuristicAlwaysInline,
473474
AlwaysInline
474475
};
475476

0 commit comments

Comments
 (0)