Re: [PATCH 02/17] x86, lto: Mark all top level asm statements as .text
From: Andi Kleen
Date: Wed Mar 27 2019 - 11:45:25 EST
> Why on earth is this needed for LTO?
>
> From the GCC manual:
>
> "This attribute, attached to a global variable or function, nullifies the
> effect of the -fw hole-program command-line option, so the object remains
> visible outside the current compilation unit."
>
> Neither the variable nor the data generated are global anymore. This data
> is only used inside this compilation unit and I don't see why LTO needs a
> reference outside of it. If so, then I really want to understand WHY
> exactly.
The LTO code generation doesn't compile file by file, but reorders
all the functions and other top level statements into "partitions".
The partitions are ordered by call graph so that inlining and some
other optimizations work efficiently
Then it finally runs multiple copies of the gcc code generator that
generate code from these partitions, each generating an own assembler file.
The top level assembler is not part of the call graph that drives
the partitioning.
So it can happen (in fact it's likely) that the top level assembler
statement ends up in a different partition and final assembler file
than the other functions in the same source file.
The repartitioning handles all symbols that are visible to C
automatically.
But for top level asm() referencing C symbols gcc doesn't know what
it is referenced.
Normally in non LTO it just works because everything ends up
in the same assembler file and the assembler can resolve the static label.
But that won't work if it's in a different assembler file,
as in LTO.
Fixing it would probably require adding some new syntax to top
level asm to declare symbols it referenced, so that gcc understands
the references.
But if we make it __visible and global it works too because
the linker resolves it. That's simple enough, although can be a bit
unexpected.
More information on LTO internals:
https://gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html#LTO-Overview
-Andi