Am 24.01.25 um 12:59 schrieb Georg-Johann Lay:
Am 24.01.25 um 08:18 schrieb Richard Biener:
On Thu, Jan 23, 2025 at 4:53 PM Georg-Johann Lay <a...@gjlay.de> wrote:
Am 23.01.25 um 14:58 schrieb Richard Biener:
On Thu, Jan 23, 2025 at 2:23 PM Georg-Johann Lay <a...@gjlay.de> wrote:
Hi, this is Ping #2 for a patch from 2024.
It adds a new target hook that allows to output
assembly code for a VAR_DECL in a custom way.
The default action is an obvious no-op,
i.e. assemble_variable() behaves like before.
I tried to understand the AVR part of the series - there I fail to see
what exactly special handling "io" and friends requires and how
that was made work with the TLS noswitch section.
I do not think the sentence the middle-end doesn't allow custom
NOSWITCH sections is correct (it would be a matter of exporting
get_noswitch_section), but I also don't exactly see how
"io" and friends require a NOSWITCH.
A noswitch section is one way to go.
However, there is no way to attach a noswitch section to a VAR_DECL.
Hmm, I don't know varasm.cc by heart either but there's the
select_section
hook invoked by get_variable_section () which looks like it could do the
trick.
No.
That hook only returns a section *name*, not a section object.
So you cannot return an unnamed section, which by definition, don't
have a section name.
Notice that only unnamed and noswitch sections have the .callback
property for custom output. named sections don't provide such
a callback, and varasm assumes that objects in named sections
look like printed by assemble_variable().
What also doesn't work is to store such VAR_DECL's for later
output (e.g. output in targetm.asm.file_end) in
targetm.encode_section_info, and set TREE_ASM_WRITTEN (decl) = 1
in targetm.encode_section_info.
The reason why this doesn't work is that declarations may have
more than one VAR_DECL, and that varasm.cc doesn't check for
TREE_ASM_WRITTEN after the call to targetm.encode_section_info.
Plus, letting encode_section_info cache respective VAR_DECLs for
later output doesn't work, because when you set TREE_ASM_WRITTEN
in encode_section_info, then you will run into this ICE:
varpool_node::assemble_decl (void)
{
...
gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
&& VAR_P (decl)
&& !DECL_HAS_VALUE_EXPR_P (decl));
So that won't work either.
Johann
But as for IO and friends - you say those are just
.global
x = Y
and thus always DECL_EXTERN? Aka in no actual section?
No. These attributes are intended for special function regs (SFRs).
There is no need to allocate memory for SFRs. For example, you
can access an SFR by means of
#define SFR (*(uint8_t volatile*) 0x12)
SFR = 123;
and the compile will use the IN instruction, which requires that
the address is known at compile time.
When the address is not known at compile time, the compiler would
use an LDS instruction, which is less optimal.
Now when the address is already known at link time, we can still
use IN when we
__attribute__((io)) volatile uint8_t sfr;
sfr = 123;
in which case there will be an IN instruction with an appropriate
RELOC.
The IO attribute also allows to specify the address, i.e.
__attribute__((io(0x12))) volatile uint8_t sfr;
sfr = 123;
and in that case, the symbol sfr is defined by the compiler as
.global sfr ; optional
.weak sfr ; optional
sfr = 0x12
So they are some kind of alias for a specific address (eventually
determined by the linker)?
It address can be determined at link time, but these attributes
also allow an optional address, so that the value of the symbol is
known at compile time. In the latter case, the compiler would
define the symbol, but there is no hook to output a definition
in that form.
That is, if it's not allocated I wonder why we end up doing
assemble_variable at all (IIRC refs to externs are output differently).
Since we don't allocate memory for SFRs. They already exist.
Johann
noswitch sections are selected by flags like DECL_COMMON or
DECL_INITIAL and command line options like -f[no-]common and
-f[no-]data-sections.
In the case of tls_comm_section, the section isn't attached to
a decl, but by means of flags like:
set_decl_section_name (decl, (const char *) nullptr);
set_decl_tls_model (decl, (tls_model) 2);
Anyway, all the noswitch stuff was only a hack since it was
the only way to do in in the backend alone.
A proper implementation of the feature required some changes in
varasm, and a hook like proposed seems a clear and sound approach.
The implementation of the new hook is basically a complete override
of assemble_variable which IMO is bad style at least. The missing
So what's a better approach? Hookizing assemble_variable altogether,
and putting the current assemble_variable code into the hook default?
Johann
requirements for "io" and friends should instead be made available
by other means (for example more targeted hooks).
That said, I can see how the patch works and doesn't affect anything
besides AVR.
Richard.
This hook is needed in the avr backend to properly implement
some variable attributes. The avr part has already been approved.
The patch is bootstrapped, and it tests without new regressions.
Ok for trunk?
Johann
--
Original submission
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673459.html
Ping #1
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673459.html
avr part and approval
https://gcc.gnu.org/pipermail/gcc-patches/2024-December/672051.html
https://gcc.gnu.org/pipermail/gcc-patches/2024-December/672084.html
--
Add new target hook TARGET_ASM_VARIABLE.
This patch adds a new target hook that allows the backend to asm
output
a variable definition in its own way. This hook is needed because
varasm.cc imposes a very restrictive layout for all variable
definitions
which will be basically ELF style (on ELF targets as least). To date,
there is no way for a backend to output a variable definition in a
different way.
This hook is required by the avr backend when it outputs
definitions
for variables defined with the "io", "io_low" or "address"
attribute that
don't follow ELF style. These attributes are basically symbol
definitions
of the form
.global var_io
var_io = 32
with some additional assertions.
gcc/
* target.def (TARGET_ASM_OUT) <variable>: Add new DEFHOOK.
* targhooks.cc (default_asm_out_variable): New function.
* targhooks.h (default_asm_out_variable): New prototype.
* doc/tm.texi.in (TARGET_ASM_VARIABLE): Place hook
documentation.
* doc/tm.texi: Rebuild.
* varasm.cc (assemble_variable): Call
targetm.asm_out.variable
in order to allow the backend to output a variable
definition
in its own style.