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

Enable IPO/LTO builds #14198

Merged
merged 10 commits into from Feb 8, 2024
Merged

Enable IPO/LTO builds #14198

merged 10 commits into from Feb 8, 2024

Conversation

okias
Copy link
Contributor

@okias okias commented Jan 1, 2024

Enabling IPO/LTO leads to faster loading times, better performance, more efficient cache usage, and a reduction in binaries size.

Cons: Release build compilation takes longer and consumes more energy (thou disabling it for CI builds makes sense).

Only DEBUG build default setting is OFF, otherwise it's ON by default.

$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

# binary sizes:
         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%

Different version of abandoned #13192

TODO:

  • disable ENABLE_LTO for CI builds.

@okias

This comment was marked as outdated.

@Desour Desour added @ Build CMake, build scripts, official builds, compiler and linker errors Performance labels Jan 1, 2024
@Desour
Copy link
Member

Desour commented Jan 1, 2024

Not sure, but I guess the ODR violation might be there because irrlichtmt is compiled with -fno-rtti, so the rtti is included in minetest's translation units' vtables but in not irrlichtmt ones'.
Idk why we use -fno-rtti, we probably shouldn't.

@okias
Copy link
Contributor Author

okias commented Jan 1, 2024

Idk why we use -fno-rtti, we probably shouldn't.

The value of using LTO vs using -fno-rtti on Irrlicht only is not worth it, so yes. Dropping -no-rtti make sense there.

PR removing -fno-rtti from Irrlicht minetest/irrlicht#268

@lhofhansl
Copy link
Contributor

Nice.
I don't see any runtime performance improvements, but the executables are smaller as expected.

@okias okias force-pushed the enable-lto branch 3 times, most recently from 68264f3 to 6334b42 Compare January 6, 2024 23:53
@okias
Copy link
Contributor Author

okias commented Jan 7, 2024

For now, I have to skip WIN32, because it has random weird failures (like wchar, wstring 4 vs 2 bytes, and other stuff), but if anyone wants to play with it, maybe will be enabling the LTO option too there.

@okias okias marked this pull request as ready for review January 7, 2024 00:29
Copy link
Member

@Desour Desour left a comment

Choose a reason for hiding this comment

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

I'd like to be able to enable LTO for non-Release builds too, e.g. just for getting more warnings, and also for RelWithDebInfo.
Can we have an option which just has a different default depending on the build type?

src/client/particles.cpp Outdated Show resolved Hide resolved
@Desour Desour added the Action / change needed Code still needs changes (PR) / more information requested (Issues) label Jan 22, 2024
@Desour Desour self-assigned this Jan 22, 2024
@Desour
Copy link
Member

Desour commented Jan 27, 2024

Right now, LTO is always default ON. Only exception is Debug build where it's default off.

Correct me if I'm wrong, but isn't CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE only used by cmake if build type is Release?
How can I check whether an executable was built with LTO?

@okias
Copy link
Contributor Author

okias commented Jan 28, 2024

Correct me if I'm wrong, but isn't CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE only used by cmake if build type is Release? How can I check whether an executable was built with LTO?

Thanks, fixed.

Generally the size difference should tell you in 99.99% cases.

Copy link
Member

@Desour Desour left a comment

Choose a reason for hiding this comment

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

  • New build option needs documentation in doc/compiling/README.md.
  • I'm getting another warning in nodedef.cpp:737. (At least after a trivial rebase.)
  • The default value is debatable. On my machine it takes about 2min with RelWithDebInfo and mold linker.

CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
src/gui/guiTable.cpp Outdated Show resolved Hide resolved
src/script/lua_api/l_server.cpp Outdated Show resolved Hide resolved
Test case:
```
$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%
```

Signed-off-by: David Heidelberg <david@ixit.cz>
Take care about possible allocation of too large array (not likely to
happen in real life (TM)).
```
/home/okias/projects/minetest/src/gui/guiTable.cpp:239:45: warning: argument 1 value ‘18446744073709551615’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
  239 |         TempRow *rows = new TempRow[rowcount];
      |                                             ^
```

Signed-off-by: David Heidelberg <david@ixit.cz>
Compiler is afraid that variables will be uninitialized, but when is
code around, he seems to be happy.

Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
In CI, linking takes extra time and rarely causes regressions.

Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
@okias okias requested a review from Desour February 7, 2024 08:30
@okias
Copy link
Contributor Author

okias commented Feb 7, 2024

  • New build option needs documentation in doc/compiling/README.md.

Done.

  • I'm getting another warning in nodedef.cpp:737. (At least after a trivial rebase.)

Initialized.

  • The default value is debatable. On my machine it takes about 2min with RelWithDebInfo and mold linker.

Sure, sure, thou for release it's always "right thing to do", for other builds I would say it's for consideration depending on the machine, energy cost and patience 😉 😆

Copy link
Member

@Desour Desour left a comment

Choose a reason for hiding this comment

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

Thanks!

(Didn't test on anything other than linux x86-64 gcc mold.)

@Desour Desour added One approval ✅ ◻️ and removed Action / change needed Code still needs changes (PR) / more information requested (Issues) labels Feb 7, 2024
@okias okias requested a review from grorp February 7, 2024 12:08
@okias okias changed the title Enable IPO/LTO for production builds Enable IPO/LTO builds Feb 7, 2024
@appgurueu
Copy link
Contributor

Tested on linux x86-64 gcc as well, played a bit of CTF as a "smoke test". I got the following warning when building:

lto-wrapper: warning: using serial compilation of 126 LTRANS jobs

but this seems to be a non-issue.

One minor annoyance: set writes to the cache. So after building a release build (cmake . -DCMAKE_BUILD_TYPE=Release), IPO will be enabled even if I switch to a debug build (cmake . -DCMAKE_BUILD_TYPE=Debug) and vice versa; I have to explicitly set or unset it to get rid of this behavior. It might be better if we could store "explicitly enabled, explicitly disabled, or absent" (basically an "optional bool") in the cache somehow, though I'm not sure how that would be best mapped to CMake. I don't think this is a big issue though, since (1) other flags do the same, (2) a clean build doesn't have the problem anyways, (3) worst case, a debug build accidentally uses LTO, making it slightly slower.

@okias
Copy link
Contributor Author

okias commented Feb 8, 2024

@appgurueu I could drop the CACHE for the option, anyway I agree it's not big deal :D

@appgurueu appgurueu merged commit eb52a14 into minetest:master Feb 8, 2024
13 checks passed
@okias okias deleted the enable-lto branch February 9, 2024 12:55
@sfan5
Copy link
Member

sfan5 commented Feb 12, 2024

I wanted to to note that the errors with LTO you saw on win32:

/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZTv0_n24_N15ClientScriptingD1Ev]+0x0): multiple definition of `ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZThn8_N15ClientScriptingD1Ev]+0x0): first defined here
/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZTv0_n24_N15ClientScriptingD1Ev]+0x0): multiple definition of `virtual thunk to ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZThn8_N15ClientScriptingD1Ev]+0x0): first defined here
/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZTv0_n24_N15ClientScriptingD1Ev]+0x0): multiple definition of `non-virtual thunk to ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZThn8_N15ClientScriptingD1Ev]+0x0): first defined here
/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZTv0_n24_N15ClientScriptingD1Ev]+0x0): multiple definition of `non-virtual thunk to ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD1Ev[_ZThn8_N15ClientScriptingD1Ev]+0x0): first defined here
/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZTv0_n24_N15ClientScriptingD0Ev]+0x0): multiple definition of `ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZThn8_N15ClientScriptingD0Ev]+0x0): first defined here
/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZTv0_n24_N15ClientScriptingD0Ev]+0x0): multiple definition of `virtual thunk to ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZThn8_N15ClientScriptingD0Ev]+0x0): first defined here
/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZTv0_n24_N15ClientScriptingD0Ev]+0x0): multiple definition of `non-virtual thunk to ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZThn8_N15ClientScriptingD0Ev]+0x0): first defined here
/usr/x86_64-w64-mingw32/bin/ld: scripting_client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZTv0_n24_N15ClientScriptingD0Ev]+0x0): multiple definition of `non-virtual thunk to ClientScripting::~ClientScripting()'; client.cpp.obj (symbol from plugin):(.gnu.linkonce.t._ZN15ClientScriptingD0Ev[_ZThn8_N15ClientScriptingD0Ev]+0x0): first defined here
[...]

might be a bug in GCC as someone has reported here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94156

grorp pushed a commit to grorp/minetest that referenced this pull request Apr 15, 2024
Test case:

```
$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%
```

Also fixes various compiler warnings resulting from compilation using LTO.

---------

Signed-off-by: David Heidelberg <david@ixit.cz>
grorp pushed a commit to grorp/minetest that referenced this pull request Apr 15, 2024
Test case:

```
$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%
```

Also fixes various compiler warnings resulting from compilation using LTO.

---------

Signed-off-by: David Heidelberg <david@ixit.cz>
grorp pushed a commit to grorp/minetest that referenced this pull request Apr 15, 2024
Test case:

```
$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%
```

Also fixes various compiler warnings resulting from compilation using LTO.

---------

Signed-off-by: David Heidelberg <david@ixit.cz>
grorp pushed a commit to grorp/minetest that referenced this pull request Apr 15, 2024
Test case:

```
$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%
```

Also fixes various compiler warnings resulting from compilation using LTO.

---------

Signed-off-by: David Heidelberg <david@ixit.cz>
grorp pushed a commit to grorp/minetest that referenced this pull request Apr 21, 2024
Test case:

```
$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%
```

Also fixes various compiler warnings resulting from compilation using LTO.

---------

Signed-off-by: David Heidelberg <david@ixit.cz>
grorp pushed a commit that referenced this pull request May 6, 2024
Test case:

```
$ cmake . -DRUN_IN_PLACE=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_SERVER=TRUE -DENABLE_TOUCH=FALSE

         minetest minetestserver
W/o LTO:      13M           7.3M
W/  LTO:      11M           5.9M
difference:   15%            19%
```

Also fixes various compiler warnings resulting from compilation using LTO.

---------

Signed-off-by: David Heidelberg <david@ixit.cz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@ Build CMake, build scripts, official builds, compiler and linker errors Performance >= Two approvals ✅ ✅
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants