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
New setting -opt-inline-from
to control where to inline from
#5964
Conversation
Feedback welcome! Todo
|
Minor nice to have: use this new glob matcher for |
Typo in commit message of c616fcb |
The proposed matcher makes it possible to inadvertently inline from in |
I don't see what you mean here, if you say |
I must have misunderstood: "slices of qualified class names: List, scala.collection.List, collection.mutable, etc" |
Oh, that's just defining what's valid syntax |
One thing I don't like is that the description of the new setting is the longest, so it will wrap if the terminal windows is not very wide..
|
We could hide the full description of the pattern behind
|
yeah, that will require some work on the settings infra, |
"-opt-inline-from", | ||
"patterns", | ||
"Classfile name patterns from which to allow inlining. ** = anything, * = package or class name, ! to exclude. Example: scala.**:!scala.Predef$:corp.*.util.*:corp.**.*Util*", | ||
"") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could be a MultiStringSetting
to allow multiple -opt-inline-from
entries on the command line to aggregate.
scaladoc -implicits-hide
is an example of a similar part of the settings UI that goes that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to do it either way, but I don't see a big advantage of switching to MultiStringSetting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the use case is to make it easy to use some base set of compiler options (e.g shared between all subprojects), and then append an extra option for some specific subproject:
scalacOptions in sub1 += List("-opt-inline-from", "...")
Without MultiStringSetting
, I beleive you'd need to perform a more complicated merge:
scalacOptions = {
val i = scalacOptions.value.indexOf("-opt-inline-from"
if (i < 0) scalacOptions.value ++ List("-opt-inline-from", "...")
else scalacOptions.value.patch(i, Nil, 2) ++ List("-opt-inline-from", scalacOptions.value(i + 1) + ",...")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, that's a good point, I'll change it. The potentially confusing thing about a MultiStringSetting
is that if you're using it in the last position and not in "colonated" mode, it consumes the source files. For example:
➜ sandbox git:(inline-from) ✗ scaladoc -implicits-hide Foo Bar Test.scala
>> shows usage
➜ sandbox git:(inline-from) ✗ scaladoc -implicits-hide Foo Bar -d . Test.scala
>> runs scaladoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's annoying. If you know about it, you can use --
to end the opton section and move into source files.
% scaladoc -implicits-hide foo bar -- /tmp/test.scala
And the help text also guides you towards the :
.
-implicits-hide:<implicit(s)> Hide the members inherited by the given comma separated, fully qualified implicit conversions. Add dot (.) to include default conversions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I tried a single -
as separator, but that didn't work. I'll make sure the help text recommends the colonated mode.
Introduce the optimizer level `-opt:l:inline` and a new setting `-opt-inline-from` to control what classes we inline from. `-opt:l:classpath` and `-opt:l:project` continue to work in the same way, with a deprecation warning.
Allows StringSetting to be helping.
|
Jardiff: I created a locker from 0c51534 (the current tip of this PR). Then:
Result here: a number of methods from the rt.jar that are no longer inlined, for example I also compiled lib+reflect+compiler with For curiosity, here's a histogram of inlined methods: https://gist.github.com/lrytz/6f689a78e497e7ebed966be0bcb0a36f |
FYI, I'm working on better automation for this sort of analysis |
I think this is ready now. |
@@ -254,7 +254,7 @@ trait ScalaSettings extends AbsScalaSettings | |||
|
|||
private val inlineChoices = List(lMethod, inline) | |||
val lInline = Choice("l:inline", | |||
"Enable cross-method optimizations: " + inlineChoices.mkString("", ",", "."), | |||
"Enable cross-method optimizations (note: inlining requires -opt-inlnie-from): " + inlineChoices.mkString("", ",", "."), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo here.
Just checking: do we inline unconditionally from sources in the current run, even without -opt-inlnie-from
?
Pros: a convenient default without needing
Cons: instable results depending on separate compilation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... I'd prefer the stability over convenience, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, and that's the current implementation. We could bring back the functionality of -opt:l:project
with a special pattern in -opt-inline-from:...:<sources>:...
Allows passing the setting multiple times, which might be useful for multi-project builds
Move jvm-specific settings from scalaModuleSettings to a new scalaModuleSettingsJVM setting. This means that JVM projects in scala modules now have to add bot `scalaModuleSettings` and `scalaModuleSettingsJVM`. Adding sbt-osgi settings in a scala-js project caused the published jar to be empty (scala/scala-parser-combinators#119). Upgrades sbt-osgi to the latest version. Also anticipates the new optimizer settings in 2.12.3 (scala/scala#5964).
Move jvm-specific settings from scalaModuleSettings to a new scalaModuleSettingsJVM setting. This means that JVM projects in scala modules now have to add bot `scalaModuleSettings` and `scalaModuleSettingsJVM`. Adding sbt-osgi settings in a scala-js project caused the published jar to be empty (scala/scala-parser-combinators#119). Upgrades sbt-osgi to the latest version. Also anticipates the new optimizer settings in 2.12.3 (scala/scala#5964).
Move jvm-specific settings from scalaModuleSettings to a new scalaModuleSettingsJVM setting. This means that JVM projects in scala modules now have to add bot `scalaModuleSettings` and `scalaModuleSettingsJVM`. Adding sbt-osgi settings in a scala-js project caused the published jar to be empty (scala/scala-parser-combinators#119). Upgrades sbt-osgi to the latest version. Also anticipates the new optimizer settings in 2.12.3 (scala/scala#5964).
The scalac doc shows |
Patterns are separated by |
Deprecates
-opt:l:classpath
and-opt:l:project
, introduces-opt:l:inline
which enables cross-method optimizations. The inliner will only inline code from classes listed in-opt-inline-from
, which is empty by default. So specifying only-opt:l:inline
actually doesn't enable any inlining.Proposed syntax for
-opt-inline-from
:List
,scala.collection.List
,collection.mutable
, etc*
: longest match of identifier parts (not.
)**
: longest match of anything<sources>
: allows inlining from classes being compiled in the current compilation run (implemented in a follow-up PR -opt-inline-from:<sources> to allow inlining from compilation units #5989)!
to make a rule excludingExamples
*
scala.*
scala.package$
)**
scala.collection.**
com.corp.**.util.*
**.Util
_root_.Util
**.*Util*
There's a special case to make
.**.
match.
, soa.**.b.C
matchesa.b.C
. Similarly,**.A
matchesA
.Note that we're talking about classfile names here, so a nested class
foo.C#D
would befoo.C$D
, a module class isscala.Predef$
.More examples:
scalac -opt:l:inline -opt-inline-from:scala.**:com.corp.**
: white-listing is recommended, becausert.jar
is not easy (and also platform-dependent)! The following is just a start, there are many more packages:**:!java.**:!javax.**:!jdk.**:!apple.**:!com.apple.**:!com.oracle.**:!com.sun.**:...
**:!foo.**:foo.util.**
: the last matching rule counts.Fixes scala/scala-dev#148