-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8370438: Offer link time optimization support on library level #27976
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
base: master
Are you sure you want to change the base?
Conversation
|
👋 Welcome back mbaesken! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
| BASIC_LDFLAGS_JVM_ONLY="-mno-omit-leaf-frame-pointer -mstack-alignment=16 \ | ||
| -fPIC" | ||
| LDFLAGS_LTO="-flto=auto -fuse-linker-plugin -fno-strict-aliasing" |
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 notice that the compiler args for GCC and Clang are different, but the linker args are the same. Just want to make sure that's intentional.
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.
Yes they are different, this is 'borrowed' from Hotspot flags, see
jdk/make/hotspot/lib/JvmFeatures.gmk
Line 178 in 9625993
| ifeq ($(call isCompiler, gcc), true) |
where we supported LTO for some time.
|
It might be better if we offered this as an option to turn off and on through configure (My personal fork of the JDK has something along the lines of --enable-linktime-opt, can't remember the exact name) rather than making some native code have to use LTO. Additionally I also think this is better done similar to how HotSpot does it instead of adding LTO options as an exported Makefile variable and adding a new parameter to SetupNativeCompilation. |
The PR gives developers working on some lib , where LTO looks promising, the ability to test the feature on the specific lib. |
@mrserb is this what you had in mind ? |
|
I want to remove the changes from |
Webrevs
|
|
For libfontmanager the lib sizes decrease quite a lot on most platforms if LTO is enabled in the build of the lib. (however the freetype lib does not show this decrease in lib size when enabling lto) |
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.
This change on its own doesn't do anything. Do you plan on following up immediately with a set of suggested libs to enable this on? Have you noticed any impact on build performance when enabling this on any JDK libs? I very much doubt any component owner is going to test and apply this on their own. Without that, this is a dead feature and I wouldn't want it to go in.
I wonder if it would be a good idea to add a global on/off switch (configure arg) for this whole thing, I'm really not sure. It kind of depends on what the impact is. If the impact is unknown, then a global on/off switch, default off, would let every distributor evaluate this on their own. That would of course also require that at least some libs have this enabled.
I was suggesting a configure switch too, in my fork I have a UTIL_ARG_ENABLE for the configure option and then in LibCommon.gmk and LauncherCommon.gmk I implemented the options as such: |
There was some interest on the lib-level solution here #22464 (comment) . 'Provide an option for library owners to opt-in, which can be enabled per-library, per-platform and per-compiler after appropriate testing for performance, functionality, and footprint.' |
I see not much difference when looking at the build times of our builds with and without this patch. But this is the time for a whole scratch-build , not for single libs. For single libs with LTO enabled the time might be slower, but because this is just a small part of the (parallel) whole JDK build, it does not matter so much. |
Yes, this looks fine. It might be useful to update the documentation to mention which toolchains are supported (or at least have been tested once). Do we already have this documented somewhere for hotspot? |
We have support for all important toolchains (gcc, clang, MSVC). (when testing the PR on libfontmanager and freetype I had this enabled on all our SAP supported platforms AIX, various Linux, macOS, Windows x86_64). |
When introducing new compiler flags, you need to do one of:
|
I can find a few other libs besides libfontmanager where we see some size reduction (performance improvement will be hard to prove without good benchmarks on lib level). |
The compiler flags are not really 'new' but borrowed from Hotspot LTO.
|
|
@azvegint please review |
For Hotspot / libjvm we have currently |
Just an idea to think about: would it be possible to share the same variable between the JDK and HotSpot to store these parameters? Even in this discussion, it would highlight that these parameters are not new. Or is it not worth the effort? |
For the HS build, we set them directly in the makefile and not in the configure m4 files, see jdk/make/hotspot/lib/JvmFeatures.gmk Line 179 in e4aed95
Might indeed make sense to refactor this. |
It would be a little awkward to refactor only the JVM LTO flags into configure flags while leaving the rest of the JVM feature flags set by the Makefile, just my 2 cents. |
The part in the Makefile would probably stay, but could reuse common flags from configure, e.g. something like this |
Yes, please only define the values once and use the variables in the JVM makefile. |
|
Here are the lib sizes of libsplashscreen without / with lto for our toolchains at SAP (gcc 13.2.0, VS2022, Xcode 15.4) ; so the lib might be a good example to use lto (maybe with an additional configure flag to enable/disable it). |
I adjusted the build flag settings in JvmFeatures.gmk to use the flags set by configure. |
| ifeq ($$($1_LINK_TIME_OPTIMIZATION), true) | ||
| $1_OPT_CFLAGS += $(C_O_FLAG_LTO) | ||
| $1_OPT_CXXFLAGS += $(CXX_O_FLAG_LTO) | ||
| endif |
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 don't think adding the LTO flags to the OPT flags is the right move, but if we are going with that, then this addition of LTO flags should only be done if $$($1_OPTIMIZATION) is set, as otherwise, those flags are already added through $$($2_OPT_CFLAGS). That means, this block should be moved into the else block above, before the endif on line 64.
However, the OPT flags are treated separately through SetupCompilerFlags and SetupCompileFileFlags because it should be possible to override the optimization level on a per file basis. The LTO flags on the other hand, are not possible to override on a per file basis, so we should not be tinkering with those in the SetupCompileFileFlags macro at all. So mixing in the LTO flags with the OPT flags is the wrong move.
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 don't think adding the LTO flags to the OPT flags is the right move
So where should I move it? After all it is link time optimization so it is an optimization related tool feature.
But should I remove it completely from SetupCompileFileFlags because having it in SetupCompilerFlags is sufficient for out task ?
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.
Again, the optimization flags aren't handled as a separate set of variables because they are of the category "optimization". It's because optimization flags are handled on a higher level with an abstraction of "low", "medium", "high" etc, and that abstraction allows for specific file overrides. That's what the *_OPT_C*FLAGS are there to handle. Since the LTO flags are not related to this abstraction, they should not be mixed into these variables, that is just confusing and adding unnecessary complexity.
The LTO flags should just be stacked on to the $1_EXTRA_* flags like any other.
| ifeq ($$($1_LINK_TIME_OPTIMIZATION), true) | ||
| $1_OPT_CFLAGS += $(C_O_FLAG_LTO) | ||
| $1_OPT_CXXFLAGS += $(CXX_O_FLAG_LTO) | ||
| endif |
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.
Again, the optimization flags aren't handled as a separate set of variables because they are of the category "optimization". It's because optimization flags are handled on a higher level with an abstraction of "low", "medium", "high" etc, and that abstraction allows for specific file overrides. That's what the *_OPT_C*FLAGS are there to handle. Since the LTO flags are not related to this abstraction, they should not be mixed into these variables, that is just confusing and adding unnecessary complexity.
The LTO flags should just be stacked on to the $1_EXTRA_* flags like any other.
We currently have support for LTO (link time optimization) for Hotspot/libjvm, that can be enabled as a JVM feature.
But for other JDK native libs, we do not have support for this feature.
LTO and sometimes lead to faster and also in some cases smaller binaries, so support for this might be interesting also for other libs and not only libjvm.
Progress
Issue
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/27976/head:pull/27976$ git checkout pull/27976Update a local copy of the PR:
$ git checkout pull/27976$ git pull https://git.openjdk.org/jdk.git pull/27976/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 27976View PR using the GUI difftool:
$ git pr show -t 27976Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/27976.diff
Using Webrev
Link to Webrev Comment