[PATCH] RISC-V: Optimize lui and auipc relaxations for undefweak symbols
Nelson Chu
nelson.chu@sifive.com
Thu Sep 19 10:37:00 GMT 2019
*Dear Jim,*
> The ChangeLog entries seem out of order, relax_func_t says Likewise and
comes
> after _bfd_riscv_relax_section, but doesn't have the same changes. Also,
> you are adding a field to structs not a variable, and a parameter to
functions.
*OK I will fix the wrong comment :)*
> In _bfd_riscv_relax_section you are checking
> h->root.type == bfd_link_hash_undefweak
> I think you may need to use
> UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
> instead. The issue is that when creating a shared library, an undef weak
> may not be defined at link time, but might be defined at run time, so the
> user has an option to force it to zero at link time or do a run-time check
> via -z [no]dynamic-undefined-weak. Thus we have to check visibility and
> the user supplied option in addition to bfd_link_hash_undefweak. This is
> stuff I have limited understanding of, so I'm not sure of the details, but
> if undefined weak can still lead to a run-time symbol lookup, then we
can't
> force the value to zero at link-time, so this optimization is wrong in
that
> case. This should be checked with shared library builds. I don't know if
> there are any linker tests for this.
*At first I thought that toolchain will use GOT and PLT if creating a
shared library.Therefore, there is no harm without checking the above case
I thought.But you are right, there may have some exceptions, and caution is
the parent of safety :)*
#define UNDEFWEAK_NO_DYNAMIC_RELOC(INFO, H) \
((H)->root.type == bfd_link_hash_undefweak \
&& (ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \
|| (INFO)->dynamic_undefined_weak == 0))
*Another problem is that, the value of `dynamic_undefined_weak` is always
be -1 forthe ld/testsuite/ld-riscv-elf/weakref32 testsuite with static
linking, and then theundefweak optimization is disabled if we use the macro
UNDEFWEAK_NO_DYNAMIC_RELOCto check.Maybe I missed something?*
> Did you test with a C target? I see you converting instructions to use
x0,
> but I don't see you converting instructions into compressed form. This
> should be possible in the LO12I case, since it can be a c.li X,0. The
LO12S
> case is probably more complicated, but also less important. Doing this
saves
> another 2 bytes per undefined weak reference.
*OK I will do the further optimization with another patches.*
>By the way, the SEC_MERGE and SEC_CODE checks should no longer be necessary
>in theory since Optimitech added the missing _bfd_merged_section_offset
call.
>We just haven't gotten around to trying to remove them yet. I suspect the
>undefined_weak check here is unnecessary, since a undefined symbol can't be
>in a merge or code section.
> Trying to build on Ubuntu 18.04 with mainline, I get an error
> ../../binutils-gdb/bfd/elfnn-riscv.c: In function
‘_bfd_riscv_relax_section’:
> ../../binutils-gdb/bfd/elfnn-riscv.c:4148:12: error: ‘symval’ may be used
unini\
> tialized in this function [-Werror=maybe-uninitialized]
> if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> max_alignment, reserve_size, again,
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> &pcgp_relocs, undefined_weak))
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> I had to set symval to 0 in the undefined_weak if statement.
>
> Also, you are adding a lot of if statement checks for undefined_weak, but
> there is no harm in executing this code since the relaxation functions
don't
> use any of these variables when undefined_weak is true, so it doesn't
matter
> if we set them before calling the relaxation function. Also, since
> undefined_weak is rare, it is probably faster to not have the checks,
because
> it is only rarely that we waste time computing stuff we won't use. As
opposed
> to always checking a variable value that will almost always be false.
*Indeed I add too much unnecessary checking with 'undefined_weak'...*
*I should set the 'symval' and 'sym_sec' for undefined weak symbol, just
like other*
*normal cases, since we already have the flag 'undefined_weak' and the
value of*
*'symval' and 'sym_sec' are not important.*
*Therefore, I can remove the most unnecessary checking if the 'symval' and
'sym_sec'*
*are set for the undefined weak symbols.*
else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
&& (relax_func == _bfd_riscv_relax_lui
|| relax_func == _bfd_riscv_relax_pc))
{
/* For the lui and auipc relaxations, since the symbol
value of an undefined weak symbol is always be zero,
we can optimize the patterns into a single LI/MV/ADDI
instruction. */
undefined_weak = TRUE;
symval = h->root.u.def.value;
sym_sec = h->root.u.def.section;
}
else if (h->root.u.def.section->output_section == NULL
|| (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak))
continue;
else
{
symval = h->root.u.def.value;
sym_sec = h->root.u.def.section;
}
*Thank you very much!*
*I will send the modified patch ASAP :)*
*Thanks*
*Best Regards*
*Nelson*
<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
不含病毒。www.avast.com
<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
More information about the Binutils
mailing list