Skip to content
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

Specialize #1725

Merged
merged 2 commits into from
Mar 18, 2016
Merged

Specialize #1725

merged 2 commits into from
Mar 18, 2016

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Mar 17, 2016

Introduces an @_specialize(...) function attribute.

An internal @_specialize function attribute allows developers to force
full specialization by listing concrete type names corresponding to the
function's generic signature. A function's generic signature is a
concatenation of its generic context and the function's own generic
type parameters.

  struct S<T> {
    var x: T
    @_specialize(Int, Float)
    mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
      x = t
      return (u, x)
    }
  }

  // Substitutes: <T, U> with <Int, Float> producing:
  // S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)

@_specialize currently acts as a hint to the optimizer, which
generates type checks and code to dispatch to the specialized routine
without affecting the signature of the generic function. The
intention is to support efforts at evaluating the performance of
specialized code. The performance impact is not guaranteed and is
likely to change with the optimizer. This attribute should only be
used in conjunction with rigorous performance analysis. Eventually,
a similar attribute could be defined in the language, allowing it to be
exposed as part of a function's API. That would allow direct dispatch
to specialized code without type checks, even across modules.

In the future, we can build on this work in several ways:

  • cross module dispatch directly to specialized code
  • dynamic dispatch directly to specialized code
  • automated specialization based on broader hints
  • partial specialization
  • and so on...

@swift-ci Please test

@atrick
Copy link
Contributor Author

atrick commented Mar 17, 2016

@swift-ci Please test

@swiftix
Copy link
Contributor

swiftix commented Mar 18, 2016

👍

@@ -713,6 +713,35 @@ the virtual dispatch, inline calls when appropriate, and eliminate the overhead
of the generic system. Such optimizations can be performed based on heuristics,
user direction, or profile-guided optimization.

An internal @_specialize function attribute allows devlopers to force
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: devlopers

This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.

This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.

The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.

This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.

e.g.

  struct S<T> {
    var x: T
    @_specialize(Int, Float)
    mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
      x = t
      return (u, x)
    }
  }
  // Substitutes: <T, U> with <Int, Float> producing:
  // S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)
@swiftix
Copy link
Contributor

swiftix commented Mar 18, 2016

@atrick Are you planning to add a benchmark for this feature? I think it would make a lot of sense.

And, BTW, does this feature generate specializations even at -Onone? If it does and it is intended then the tests should check that specializations are produced both for -Onone and -O

@atrick
Copy link
Contributor Author

atrick commented Mar 18, 2016

@swiftix Yes, I'm planning to add benchmarks. The one that I have is nontrivial to integrate because it involves modules.

I did not tie any of the test cases to the -O or -Onone pipeline. The pass currently runs at -O and I don't have any plans to change -Onone.

@nadavrot
Copy link
Contributor

@swift-ci Please test

This pass finds generic functions with @_specialized attributes and
generates specialized code for the attribute's concrete types. It
inserts type checks and guarded dispatch at the beginning of the
generic function for each specialization. Since we don't currently
expose this attribute as API and don't specialize vtables and witness
tables yet, the only way to reach the specialized code is by calling
the generic function which performs the guarded dispatch.

In the future, we can build on this work in several ways:
- cross module dispatch directly to specialized code
- dynamic dispatch directly to specialized code
- automated specialization based on less specific hints
- partial specialization
- and so on...

I reorganized and refactored the optimizer's generic utilities to
support direct function specialization as opposed to apply
specialization.
@atrick
Copy link
Contributor Author

atrick commented Mar 18, 2016

@swift-ci Please test

atrick added a commit that referenced this pull request Mar 18, 2016
@atrick atrick merged commit e2c43cf into swiftlang:master Mar 18, 2016
atrick added a commit that referenced this pull request Mar 19, 2016
Temporarily reverting @_specialize because stdlib unit tests are
failing on an internal branch during deserialization.

This reverts commit e2c43cf, reversing
changes made to 9078011.
atrick added a commit that referenced this pull request Mar 22, 2016
Reapply "Merge pull request #1725 from atrick/specialize"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants