Skip to content

Implement method type specialisation #630

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

Closed
wants to merge 37 commits into from

Conversation

AlexSikia
Copy link

This implements method type specialization.

@DarkDimius Please review (and of course let me know if I should do anything differently with the pull request!)
Thanks

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't be part of PR.

@DarkDimius
Copy link
Contributor

Alex, a lot of your commits do reformatting of already existing code for not good reason(I guess your IDE has different formatting options), could you please update your commits to not do this, as this affects git history.

Also, you have committed files that are specific to your IDE(I guess that's Intellij) that shouldn't be part of PR.

Neither should there be anything in out/ folder.

@AlexSikia AlexSikia force-pushed the add/Type-specialisation branch 6 times, most recently from 5132ba1 to 7b75837 Compare June 4, 2015 08:49
@DarkDimius
Copy link
Contributor

Junit failed in GenBCode, as output directory does not exist..
out/.keep should be kept.

@DarkDimius
Copy link
Contributor

Great to see all the tests pass 👍

PS: this PR only contains method specialization, it does not handle classes or fields.

sym.name != nme.isInstanceOf_ &&
!(sym is Flags.JavaDefined) &&
!sym.isConstructor &&
!sym.name.toString.contains("Function2")
Copy link
Contributor

Choose a reason for hiding this comment

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

why?

@AlexSikia AlexSikia changed the title Implement type specialisation Implement method type specialisation Jun 4, 2015
@VladUreche
Copy link
Contributor

How did you guys fix the transitivity issue?

@DarkDimius
Copy link
Contributor

As a last transformation step, in all places where expected type propagation starts, casts are introduced.

This isn't a solution, this is a hacky-workaround. I do not see a good solution besides #592.

@@ -326,6 +326,7 @@ class Definitions {
lazy val TransientAnnot = ctx.requiredClass("scala.transient")
lazy val NativeAnnot = ctx.requiredClass("scala.native")
lazy val ScalaStrictFPAnnot = ctx.requiredClass("scala.annotation.strictfp")
lazy val specializedAnnot = ctx.requiredClass("scala.specialized")
Copy link
Contributor

Choose a reason for hiding this comment

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

capital S

@DarkDimius
Copy link
Contributor

trait Spec {
 def plus[@specialized T](a: T, b:T)(ev: Numeric[T]): T = plus(b, a)(ev)
}

Generates specialized versions, but does not dispatch to them in recursive call.

@VladUreche
Copy link
Contributor

@DarkDimius @AlexSikia doesn't casting introduce boxes in the backend?
This is something that affects miniboxing reflection: https://github.com/miniboxing/miniboxing-plugin/blob/wip/components/runtime/src/scala/MbReflection.scala#L132-L138

@DarkDimius
Copy link
Contributor

@VladUreche the problems we've been seeing here mostly have to do with type arguments of enclosing scope, that are bounded by specialized types defined in inner scope. This happens infrequently in real code, and when it happens, it's mostly in higher kinded types, ie casts will be erased.

Examples can be found here: https://github.com/AlexSikia/dotty/blob/add/Type-specialisation/tests/pos/specialization/this_specialization.scala

But yes, it could potentially introduce boxing, and this could keep some calls not being dispatched to specialized versions.

@AlexSikia AlexSikia force-pushed the add/Type-specialisation branch from 7aed2e7 to ac75f1c Compare June 8, 2015 23:33
def generateSpecializedSymbols(instantiations: List[Type], names: List[String], poly: PolyType, decl: Symbol)
(implicit ctx: Context): List[Symbol] = {
val newSym =
ctx.newSymbol(decl.owner, (decl.name + "$mc" + names.mkString + "$sp").toTermName,
Copy link
Member

Choose a reason for hiding this comment

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

If I understand the name mangling of specialization correctly, this should be (decl.name + "$m" + names.mkString + "c$sp").
m means method and c means class, for example if there's a specialized Int method in a specialized Int class, the signature will contain $mIcI$sp.

Copy link
Author

Choose a reason for hiding this comment

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

Ah, good point; thanks for finding that.

@DarkDimius
Copy link
Contributor

needs to be rebased over current master.

smarter added a commit to smarter/dotty that referenced this pull request Jul 4, 2015
VCInline is split into two phases:
- VCInlineMethods (before Erasure) replaces value class method calls
  by calls to extension methods
- VCInlineEqAndField (after Erasure) handles == and the underlying field
  of a value class, as VCInline did before.

This should not affect anything currently, but in the future we will have
phases before Erasure that mangle names (like TypeSpecializer, see scala#630),
being able to put these phases after VCInlineMethods means that
VCInlineMethods does not need to know anything about how these phases
mangle names, this reduces the coupling between phases. The trade-off is
that VCInlineMethods needs to deal with type parameters whereas VCInline
didn't.
smarter added a commit to smarter/dotty that referenced this pull request Jul 5, 2015
VCInline is split into two phases:
- VCInlineMethods (before Erasure) replaces value class method calls
  by calls to extension methods
- VCInlineEqAndField (after Erasure) handles == and the underlying field
  of a value class, as VCInline did before.

This should not affect anything currently, but in the future we will have
phases before Erasure that mangle names (like TypeSpecializer, see scala#630),
being able to put these phases after VCInlineMethods means that
VCInlineMethods does not need to know anything about how these phases
mangle names, this reduces the coupling between phases. The trade-off is
that VCInlineMethods needs to deal with type parameters and multiple
parameter lists whereas VCInline didn't.
smarter added a commit to smarter/dotty that referenced this pull request Jul 5, 2015
VCInline is split into two phases:
- VCInlineMethods (before Erasure) replaces value class method calls
  by calls to extension methods
- VCInlineEqAndField (after Erasure) handles == and the underlying field
  of a value class, as VCInline did before.

This should not affect anything currently, but in the future we will have
phases before Erasure that mangle names (like TypeSpecializer, see scala#630),
being able to put these phases after VCInlineMethods means that
VCInlineMethods does not need to know anything about how these phases
mangle names, this reduces the coupling between phases. The trade-off is
that VCInlineMethods needs to deal with type parameters and multiple
parameter lists whereas VCInline didn't.
smarter added a commit to smarter/dotty that referenced this pull request Jul 6, 2015
VCInline is split into two phases:
- VCInlineMethods (before Erasure) replaces value class method calls
  by calls to extension methods
- VCInlineEqAndField (after Erasure) handles == and the underlying field
  of a value class, as VCInline did before.

This should not affect anything currently, but in the future we will have
phases before Erasure that mangle names (like TypeSpecializer, see scala#630),
being able to put these phases after VCInlineMethods means that
VCInlineMethods does not need to know anything about how these phases
mangle names, this reduces the coupling between phases. The trade-off is
that VCInlineMethods needs to deal with type parameters and multiple
parameter lists whereas VCInline didn't.
@DarkDimius
Copy link
Contributor

@AlexSikia, This PR has been around for quite some time. Let's do a push and get this in?

AlexSikia and others added 18 commits August 21, 2015 12:47
Fixes dispatching of specialised methods to recursive calls. Also takes
care of mutually recursive calls.
Adds a few tests for recursive specialisation, and `@specialized`
annotations with parameter `AnyRef` or
`Specializable.specializable_group`
Detecting annotations on `Specializable` groups or `AnyRef` was flawed
Name mangling was incorrect previously. Now uses the `specializedFor`
method in `NameOps`.
Conflicts:
	src/dotty/tools/dotc/core/NameOps.scala

Conflicts:
	src/dotty/tools/dotc/core/NameOps.scala
`until` argument of `mergeArgs(...)` was passed the value of `argTypes.length` (only
types which are used for instantiation) by `args(...)`, and therefore did not account
for remaining generics.
Only type params directly preceded by an `@specialized` annotation will
be specialised.
Changes type from `StringSetting` to `IntSetting`.
Value x passed to the setting is the maximum number of parameters to
specialize. Any method with type parameters will see the x first (or
all if there are not enough) of them specialized.

Conflicts:
	src/dotty/tools/dotc/config/ScalaSettings.scala
Makes for a more complete handling of different elements
Widening the type of the function is necessary before checking for
parameterlessness of the methods.
@AlexSikia AlexSikia force-pushed the add/Type-specialisation branch 4 times, most recently from 154e6de to 852ae7e Compare August 21, 2015 12:23
Refines names of variables and refactors small (outdated) parts of the
code.
@AlexSikia AlexSikia force-pushed the add/Type-specialisation branch from 852ae7e to 417fc96 Compare August 21, 2015 12:25
@smarter
Copy link
Member

smarter commented Aug 21, 2015

Commit AlexSikia@07e9ae1 should be removed from this pull request, it's just an accidental revert of 10ea712 .

@odersky
Copy link
Contributor

odersky commented Feb 17, 2016

Superseded by new work

@odersky odersky closed this Feb 17, 2016
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.

6 participants