Closed JeremyGrosser closed 3 years ago
Upon further investigation, enabling Link Time Optimization by adding -flto
to both the compiler and linker flags does indeed inline this without branching.
I think the compiler should inline as soon as you enable some -O2 or -O3 optimization at least.
There is also -gnatn
to enable inlining.
And you can give a hints to the compiler with pragma Inline (Yield);
at the end of the specification for instance.
I think the compiler should inline as soon as you enable some -O2 or -O3 optimization at least. There is also
-gnatn
to enable inlining.And you can give a hints to the compiler with
pragma Inline (Yield);
at the end of the specification for instance.
I already have with Inline
on all of the procedures in the specification, the Ada 2012 reference says this is preferred over the pragma now.
It looks like adding -O3
removes the link register manipulation and -gnatn
gets rid of the branching. I would've expected that with Inline
or -O3
would've implicitly enabled inlining, but apparently not!
The GNAT user guide makes this set of conditions clear here https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gnat_ugn/Inlining-of-Subprograms.html#g_t10f
@JeremyGrosser thanks for the contribution. The builds are failing because of another issue in the scripts (see #388). I'll ask you to rebase once this is fixed.
@JeremyGrosser if you can rebase on the master
branch that would be great :)
Thank you for your contribution @JeremyGrosser, and sorry for the issue with the build script.
Send_Event, Wait_For_Event, Wait_For_Interrupt, and Yield are defined as "hint instructions" in the ARMv6-M Architecture Reference Manual. This package just conveniently wraps them up as procedures, very similar to the Memory_Barriers package in the same directory.
When testing this package, I discovered that GNAT's
Inline
is really just a suggestion. Unless-fomit-frame-pointer
is added to the compiler flags, five additional instructions are added to each of these calls to save and restore the link register. Here is the disassembled output of Wait_For_Interrupt annotated with source.Even with
-fomit-frame-pointer
, this function still requires abl
branch with link to thewfi
instruction, followed by abx lr
afterward.Is there any aspect or pragma that can be used to cause GNAT to truly inline these instructions without branching or manipulating the stack?