Skip to content

Commit f7578d2

Browse files
LTO documentation
1 parent 5b2e1f8 commit f7578d2

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Link Time Optimization
2+
3+
Link Time Optimization (LTO) is a program memory usage optimization mechanism performed by compiler at link time. At compile time compiler creates special intermediate represention of all translation units and then optimize them as a single unit at link time resulting in much better optimization comparing to non-LTO builds.
4+
5+
## Using LTO in Mbed OS
6+
7+
In Mbed OS build system LTO is implemented as an optional profile extension placed in `tools\profiles\extensions\lto.json`. When enabled, build profile is amended with LTO flags. LTO perform heavy memory optimizations what breaks debugging, so it's not recommended to enable it in debug/develop profiles.
8+
9+
To enable LTO retype `--profile` option with LTO file path `tools\profiles\extensions\lto.json`
10+
11+
<span class="notes">**Note**: For profile extensions you have to put full path relative to the project's root folder.</span>
12+
13+
To enable LTO together with `release` profile for MbedOS example :
14+
```
15+
mbed compile -t TOOLCHAIN -m TARGET --profile release --profile mbed-os/tools/profiles/extensions/lto.json
16+
```
17+
18+
Example LTO profile memory savings for [mbed-os-example-blinky](https://github.com/ARMmbed/mbed-os-example-blinky)
19+
20+
|Build type|Total Static RAM memory (data + bss)|Total Flash memory (text + data)|
21+
| --- | --- | --- |
22+
| GCC_ARM - release - no LTO | 12096 B | 44628 B |
23+
| GCC_ARM - release - LTO | 11800 B | 41088 B |
24+
|***saved memory***|296 B|3540 B|
25+
| ARM - release - no LTO | 205949 B | 35496 B |
26+
| ARM - release - LTO | 205737 B | 31514 B |
27+
|***saved memory***|296 B|‭3982‬ B|
28+
29+
LTO profile build results for [mbed-cloud-client-example](https://github.com/ARMmbed/mbed-cloud-client-example)
30+
31+
|Build type|Total Static RAM memory (data + bss)|Total Flash memory (text + data)|
32+
| --- | --- | --- |
33+
| GCC_ARM - release - no LTO | 59760 B | 389637 B |
34+
| GCC_ARM - release - LTO | 59432 B | 354167 B |
35+
|***saved memory***| 328 B | ‭35470‬ B|
36+
| ARM - release - no LTO | 253683 B | 353849 B |
37+
| ARM - release - LTO | 252734 B | 322503 B |
38+
|***saved memory***| 949 B | ‭31346‬ B|
39+
40+
41+
<span class="notes">**Note**: In LTO builds compiler produce bytecode/bitcode instead of regular object code. And it's hard to analyse this output by object code analysis tools.</span>
42+
43+
## Limitations
44+
45+
- LTO slows down build process.
46+
- It’s very hard to control memory placement when using LTO.
47+
- LTO perform heavy memory optimizations what breaks debugging.
48+
- In LTO builds compiler produce bytecode/bitcode instead of regular object code. And it's hard to analyse this output with object code analysis tools.
49+
- LTO could causes increases to the stack space needed due to cross-object inlining.
50+
51+
### ARM
52+
53+
- No bitcode libraries: armlink only supports bitcode objects on the command line. It does not support bitcode objects coming from libraries. armlink gives an error message if it encounters a file containing bitcode while loading from a library.
54+
- Partial Linking is not supported with LTO as it only works with elf objects not bitcode files.
55+
- Arm recommends that link time optimization is only performed on code and data that does not require precise placement in the scatter file, with general input section selectors such as *(+RO) and .ANY(+RO) used to select sections generated by link time optimization. It is not possible to match bitcode in .llvmbc sections by name in a scatter file.
56+
- Bitcode objects are not guaranteed to be compatible across compiler versions. This means that you should ensure all your bitcode files are built using the same version of the compiler when linking with LTO.
57+
58+
### IAR
59+
60+
- There is no LTO available for IAR compiler.
61+
62+
### GCC_ARM
63+
64+
- The minimal required version of the `GCC_ARM` is now the GNU Arm Embedded Toolchain Version 9-2019-q4-major. Earlier `GCC_ARM` versions can cause various issues when the `-flto` flag is used, e.g. a platform specific error during the final link stage on Windows hosts with GCC8
65+
- The `noinline` attribute has to be used for every function that must be placed into a specific section (specified with a `section(".section_name")` attribute). In general, when a function is considered for inlining, the `section` attribute is always ignored. However, with the link-time optimizer enabled, the chances for inlining are much higher because the inliner works across multiple translation units. As a result, the output sections' sizes change compared to a non-lto build. This may lead to a `section ".section_name" will not fit in region "region_name"` type errors.
66+
- There is a bug in all gcc versions causing that LTO removes C functions declared as weak in assembler (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83967 https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966). MbedOS build system provides fix for this. In case of exporting MbedOS project to other buildsystem the problem will emerge. This can be fixed by changing the order of object files in the linker command. Objects providing the weak symbols and compiled from assembly must be listed before the objects providing the strong symbols.

0 commit comments

Comments
 (0)