-
Notifications
You must be signed in to change notification settings - Fork 951
Compile packages independently, link using LTO #2870
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
Comments
Precise globals require a whole program optimization pass that is hard to support when building packages separately. This patch removes support for these globals by converting the last use (Linux) to use linker-defined symbols instead. For details, see: #2870
This shrinks transform.Optimize() a little bit, working towards the goal of #2870. I ran the smoke tests and there is no practical downside: one test got smaller (??) and one had a different .hex hash, but other than that there was no difference. This should also make TinyGo a liiitle bit faster but it's probably not even measurable.
This shrinks transform.Optimize() a little bit, working towards the goal of #2870. I ran the smoke tests and there is no practical downside: one test got smaller (??) and one had a different .hex hash, but other than that there was no difference. This should also make TinyGo a liiitle bit faster but it's probably not even measurable.
This shrinks transform.Optimize() a little bit, working towards the goal of #2870. I ran the smoke tests and there is no practical downside: one test got smaller (??) and one had a different .hex hash, but other than that there was no difference. This should also make TinyGo a liiitle bit faster but it's probably not even measurable.
Precise globals require a whole program optimization pass that is hard to support when building packages separately. This patch removes support for these globals by converting the last use (Linux) to use linker-defined symbols instead. For details, see: #2870
Another important issue is |
@niaow yes. We currently run interp once per package and then again for the whole program. I imagine an initial implementation of this feature would be opt-in and only run interp per package (not for the whole program) which should work in practice with some increase in binary size. We can then look into improving this. |
ThinLTO is now supported on all architectures/platforms! 🎉 |
The reflect refactor is in 🎉 |
We use ThinLTO for linking, but we use it in a way that doesn't give most of its benefits: we merge all the bitcode files into a single LLVM module and run some optimizations on it before linking. Therefore, this works more like a traditional "full" LTO link rather than a true thin link. This commit adds a new experimental -lto=thin option to do a true ThinLTO link. The main benefit is that linking will be a lot faster, especially for large programs consisting of many packages. At the moment, it only works for programs that don't do interface type asserts and don't call interface methods. It also probably won't work on WebAssembly and baremetal systems. But it's part of a larger goal towards a truly incremental build system: #2870 Once interface type asserts and method calls are converted to a vtable-like implementation, most programs should just work on linux/darwin/windows.
Managed to run some test programs with a new The next hurdle is refactoring interface type asserts and interface method calls, which is something that will likely be necessary for full reflect support anyway (to implement things like |
We use ThinLTO for linking, but we use it in a way that doesn't give most of its benefits: we merge all the bitcode files into a single LLVM module and run some optimizations on it before linking. Therefore, this works more like a traditional "full" LTO link rather than a true thin link. This commit adds a new experimental -lto=thin option to do a true ThinLTO link. The main benefit is that linking will be a lot faster, especially for large programs consisting of many packages. At the moment, it only works for programs that don't do interface type asserts and don't call interface methods. It also probably won't work on WebAssembly and baremetal systems. But it's part of a larger goal towards a truly incremental build system: #2870 Once interface type asserts and method calls are converted to a vtable-like implementation, most programs should just work on linux/darwin/windows.
We use ThinLTO for linking, but we use it in a way that doesn't give most of its benefits: we merge all the bitcode files into a single LLVM module and run some optimizations on it before linking. Therefore, this works more like a traditional "full" LTO link rather than a true thin link. This commit adds a new experimental -lto=thin option to do a true ThinLTO link. The main benefit is that linking will be a lot faster, especially for large programs consisting of many packages. At the moment, it only works for programs that don't do interface type asserts and don't call interface methods. It also probably won't work on WebAssembly and baremetal systems. But it's part of a larger goal towards a truly incremental build system: #2870 Once interface type asserts and method calls are converted to a vtable-like implementation, most programs should just work on linux/darwin/windows.
We use ThinLTO for linking, but we use it in a way that doesn't give most of its benefits: we merge all the bitcode files into a single LLVM module and run some optimizations on it before linking. Therefore, this works more like a traditional "full" LTO link rather than a true thin link. This commit adds a new experimental -lto=thin option to do a true ThinLTO link. The main benefit is that linking will be a lot faster, especially for large programs consisting of many packages. At the moment, it only works for programs that don't do interface type asserts and don't call interface methods. It also probably won't work on WebAssembly and baremetal systems. But it's part of a larger goal towards a truly incremental build system: #2870 Once interface type asserts and method calls are converted to a vtable-like implementation, most programs should just work on linux/darwin/windows.
After #285, I'd like to move one step further: by compiling packages entirely separately and doing optimizations across packages using ThinLTO (or, optionally, full LTO if desired). The main benefit is that compilation should be a lot faster. Both with a cold cache (by parallelizing codegen) and with small changes to the source code (by reusing most packages). We should be able to get close to the speed of the
go
toolchain: TinyGo is currently a lot slower.How we currently compile packages is as follows:
What I'd like to see:
This means there is no phase in which all IR is combined into one big module, which avoids the serial step that currently takes up most of the compile time.
This is no small task. We currently rely heavily on merging all packages together to perform some (required) optimization passes. These will need to be changed in some way to work well with LTO, by modifying them or replacing them with something else:
AddGlobalsBitmap
pass to be able to scan global variables in the GC mark phase. It should be possible to convert this to simply scanning the.data
/.bss
sections everywhere (see Use ThinLTO on Windows #2867, darwin: scan globals by reading MachO header #2869 for example).MakeGCStackSlots
pass. We need to make this pass run per package. In the future, the WebAssembly GC would be an alternative.LowerReflect
. I've been working on a replacement in Refactor reflect package #2640 but it's going to cost something. In return, the compiler itself becomes easier to understand and new reflect features are easier to add.LowerInterfaces
. We probably need to switch to vtable style interfaces. The optimizations that we currently do might be replaced by LLVM support for whole program devirtualization for C++.LowerInterrupts
. This is done late so that unused interrupts can be optimized away. I'm not sure how to do this efficiently in any other way other than at this stage.Of course, the resulting binaries should remain small. It's hard to avoid a slight increase, but hopefully the benefits of a simpler compiler and (much) faster compile times outweigh the downsides.
The text was updated successfully, but these errors were encountered: