Message ID | 54DD3FA9.3010609@redhat.com |
---|---|
State | New |
Headers | show |
On Thu, Feb 12, 2015 at 4:04 PM, Richard Henderson <rth@redhat.com> wrote: > On 02/12/2015 03:05 PM, H.J. Lu wrote: >> @@ -6830,9 +6830,15 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate) >> bool resolved_locally = false; >> if (symtab_node *node = symtab_node::get (exp)) >> { >> - /* When not building shared library and weak_dominate is true: >> - weak, common or initialized symbols are resolved locally. */ >> - if ((weak_dominate && !shlib && node->definition) >> + /* When weak_dominate is true and not building shared library or >> + non-default visibility is specified by user: weak, common or >> + initialized symbols are resolved locally. >> + */ >> + if (((!shlib >> + || (DECL_VISIBILITY_SPECIFIED (exp) >> + && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)) >> + && weak_dominate >> + && node->definition) >> || node->in_other_partition >> || resolution_local_p (node->resolution)) >> resolved_locally = true; > > Hum. I don't find that particularly easy to reason with either. > > How about this? I'm about half-way through regression testing on it. > > I re-instated the use of resolution_to_local_definition_p, and attempt to infer > a proper value for that when lto isn't in use. I use this to eliminate only > undef-weak early, rather than non-dominate weak. > > I re-instated the use of the existence of the local definition in the > DECL_VISIBILITY test. But unlike before, I reason that this allows us to > eliminate the second visibility check. We either have an assertion from the > user (SPECIFIED), or we know we have a definition. We no longer rely on the > DECL_EXTERNAL test in the middle eliminating symbols without a definition. > > I shuffled some of the "return false" tests around among themselves, attempting > to put the simplest test first. No change in behavior there. > > (First patch is delta from the 5-patch bundle; second patch is the > composite from trunk, to avoid confusion.) > > I tried the second patch. Results look good on Linux/x86-64. Thanks.
On 02/12/2015 08:14 PM, H.J. Lu wrote:
> I tried the second patch. Results look good on Linux/x86-64.
Thanks. My results concurr. I went ahead and installed the patch as posted.
r~
2015-02-12 H.J. Lu <hongjiu.lu@intel.com>
Richard Henderson <rth@redhat.com>
PR rtl/32219
* cgraphunit.c (cgraph_node::finalize_function): Set definition
before notice_global_symbol.
(varpool_node::finalize_decl): Likewise.
* varasm.c (default_binds_local_p_2): Rename from
default_binds_local_p_1, add weak_dominate argument. Use direct
returns instead of assigning to local variable. Unify varpool and
cgraph paths via symtab_node. Reject undef weak variables before
testing visibility. Reorder tests for simplicity.
(default_binds_local_p): Use default_binds_local_p_2.
(default_binds_local_p_1): Likewise.
(decl_binds_to_current_def_p): Unify varpool and cgraph paths
via symtab_node.
(default_elf_asm_output_external): Emit visibility when specified.
2015-02-12 H.J. Lu <hongjiu.lu@intel.com>
PR rtl/32219
* gcc.dg/visibility-22.c: New test.
* gcc.dg/visibility-23.c: New test.
* gcc.target/i386/pr32219-1.c: New test.
* gcc.target/i386/pr32219-2.c: New test.
* gcc.target/i386/pr32219-3.c: New test.
* gcc.target/i386/pr32219-4.c: New test.
* gcc.target/i386/pr32219-5.c: New test.
* gcc.target/i386/pr32219-6.c: New test.
* gcc.target/i386/pr32219-7.c: New test.
* gcc.target/i386/pr32219-8.c: New test.
* gcc.target/i386/pr64317.c: Expect GOTOFF, not GOT.
On 13/02/15 05:11, Richard Henderson wrote: > On 02/12/2015 08:14 PM, H.J. Lu wrote: >> I tried the second patch. Results look good on Linux/x86-64. > > Thanks. My results concurr. I went ahead and installed the patch as posted. > > > r~ > > > 2015-02-12 H.J. Lu <hongjiu.lu@intel.com> > Richard Henderson <rth@redhat.com> > > PR rtl/32219 > * cgraphunit.c (cgraph_node::finalize_function): Set definition > before notice_global_symbol. > (varpool_node::finalize_decl): Likewise. > * varasm.c (default_binds_local_p_2): Rename from > default_binds_local_p_1, add weak_dominate argument. Use direct > returns instead of assigning to local variable. Unify varpool and > cgraph paths via symtab_node. Reject undef weak variables before > testing visibility. Reorder tests for simplicity. > (default_binds_local_p): Use default_binds_local_p_2. > (default_binds_local_p_1): Likewise. > (decl_binds_to_current_def_p): Unify varpool and cgraph paths > via symtab_node. > (default_elf_asm_output_external): Emit visibility when specified. > > 2015-02-12 H.J. Lu <hongjiu.lu@intel.com> > > PR rtl/32219 > * gcc.dg/visibility-22.c: New test. > * gcc.dg/visibility-23.c: New test. > * gcc.target/i386/pr32219-1.c: New test. > * gcc.target/i386/pr32219-2.c: New test. > * gcc.target/i386/pr32219-3.c: New test. > * gcc.target/i386/pr32219-4.c: New test. > * gcc.target/i386/pr32219-5.c: New test. > * gcc.target/i386/pr32219-6.c: New test. > * gcc.target/i386/pr32219-7.c: New test. > * gcc.target/i386/pr32219-8.c: New test. > * gcc.target/i386/pr64317.c: Expect GOTOFF, not GOT. > Hi all, By changing behaviour of varasm.c:default_binds_local_p, this patch changes behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and through it breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols. As a result, I get regression for gcc.target/arm/long-calls-1.c on arm-none-eabi: FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there is a description for -mlong-calls. This has to be fixed. Kind regards, Alex
On Wed, Feb 18, 2015 at 6:17 AM, Alex Velenko <Alex.Velenko@arm.com> wrote: > On 13/02/15 05:11, Richard Henderson wrote: >> >> On 02/12/2015 08:14 PM, H.J. Lu wrote: >>> >>> I tried the second patch. Results look good on Linux/x86-64. >> >> >> Thanks. My results concurr. I went ahead and installed the patch as >> posted. >> >> >> r~ >> >> >> 2015-02-12 H.J. Lu <hongjiu.lu@intel.com> >> Richard Henderson <rth@redhat.com> >> >> PR rtl/32219 >> * cgraphunit.c (cgraph_node::finalize_function): Set definition >> before notice_global_symbol. >> (varpool_node::finalize_decl): Likewise. >> * varasm.c (default_binds_local_p_2): Rename from >> default_binds_local_p_1, add weak_dominate argument. Use direct >> returns instead of assigning to local variable. Unify varpool >> and >> cgraph paths via symtab_node. Reject undef weak variables before >> testing visibility. Reorder tests for simplicity. >> (default_binds_local_p): Use default_binds_local_p_2. >> (default_binds_local_p_1): Likewise. >> (decl_binds_to_current_def_p): Unify varpool and cgraph paths >> via symtab_node. >> (default_elf_asm_output_external): Emit visibility when >> specified. >> >> 2015-02-12 H.J. Lu <hongjiu.lu@intel.com> >> >> PR rtl/32219 >> * gcc.dg/visibility-22.c: New test. >> * gcc.dg/visibility-23.c: New test. >> * gcc.target/i386/pr32219-1.c: New test. >> * gcc.target/i386/pr32219-2.c: New test. >> * gcc.target/i386/pr32219-3.c: New test. >> * gcc.target/i386/pr32219-4.c: New test. >> * gcc.target/i386/pr32219-5.c: New test. >> * gcc.target/i386/pr32219-6.c: New test. >> * gcc.target/i386/pr32219-7.c: New test. >> * gcc.target/i386/pr32219-8.c: New test. >> * gcc.target/i386/pr64317.c: Expect GOTOFF, not GOT. >> > > Hi all, > By changing behaviour of varasm.c:default_binds_local_p, this patch changes > behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and through it > breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols. > > As a result, I get regression for gcc.target/arm/long-calls-1.c on > arm-none-eabi: > FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n > > In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there > is a description for -mlong-calls. I know nothing about arm. I built a cross compiler and got: [hjl@gnu-tools-1 gcc]$ cat /tmp/z.i const char * __attribute__((long_call)) __attribute__((noinline)) strong_l1 (void) { return "strong_l1"; } const char * call_strong_l1 (void) { return strong_l1 () + 1; } const char * sibcall_strong_l1 (void) { return strong_l1 (); } const char * __attribute__((weak)) __attribute__((long_call)) __attribute__((noinline)) weak_l1 (void) { return "weak_l1"; } const char * call_weak_l1 (void) { return weak_l1 () + 1; } const char * sibcall_weak_l1 (void) { return weak_l1 (); } [hjl@gnu-tools-1 gcc]$ ./xgcc -B./ -S -O2 /tmp/z.i [hjl@gnu-tools-1 gcc]$ grep "b.* strong_l1" z.s .global strong_l1 bl strong_l1 b strong_l1 [hjl@gnu-tools-1 gcc]$ grep "b.* weak_l1" z.s bl weak_l1 bl weak_l1 [hjl@gnu-tools-1 gcc]$ Can someone tell me what is wrong with the output and why?
On 02/18/2015 06:17 AM, Alex Velenko wrote: > By changing behaviour of varasm.c:default_binds_local_p, this patch changes > behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and through it > breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols. > > As a result, I get regression for gcc.target/arm/long-calls-1.c on > arm-none-eabi: > FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n > > In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there > is a description for -mlong-calls. > > This has to be fixed. Please file a bug, for tracking purposes. That said, it looks as if arm_function_in_section_p should be using decl_binds_to_current_def_p instead of targetm.binds_local_p. That will properly reject weak symbols within a given module until we receive extra information from LTO indicating when a weak definition turns out to be the prevailing definition. r~
On 19/02/15 14:16, Richard Henderson wrote: > On 02/18/2015 06:17 AM, Alex Velenko wrote: >> By changing behaviour of varasm.c:default_binds_local_p, this patch changes >> behaviour of gcc/config/arm/arm.c:arm_function_in_section_p and through it >> breaks gcc/config/arm/arm.c:arm_is_long_call_p for weak symbols. >> >> As a result, I get regression for gcc.target/arm/long-calls-1.c on >> arm-none-eabi: >> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l1\n >> FAIL: gcc.target/arm/long-calls-1.c scan-assembler-not \tbl?\tweak_l3\n >> >> In https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there >> is a description for -mlong-calls. >> >> This has to be fixed. > > Please file a bug, for tracking purposes. > > That said, it looks as if arm_function_in_section_p should be using > decl_binds_to_current_def_p instead of targetm.binds_local_p. > > That will properly reject weak symbols within a given module until we receive > extra information from LTO indicating when a weak definition turns out to be > the prevailing definition. > > > r~ > Hi Richard, Thank you for your reply. Here is the bug report. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65121 Your suggestion seem to fix gcc.target/arm/long-calls-1.c, but has to be thoroughly tested. Kind regards, Alex
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 057eedb..942826d 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -442,8 +442,10 @@ cgraph_node::finalize_function (tree decl, bool no_collect) node->local.redefined_extern_inline = true; } - notice_global_symbol (decl); + /* Set definition first before calling notice_global_symbol so that + it is available to notice_global_symbol. */ node->definition = true; + notice_global_symbol (decl); node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; /* With -fkeep-inline-functions we are keeping all inline functions except diff --git a/gcc/varasm.c b/gcc/varasm.c index 9f79416..0211306 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -6828,37 +6828,42 @@ default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate) because dynamic linking might overwrite symbols in shared libraries. */ bool resolved_locally = false; + bool defined_locally = false; if (symtab_node *node = symtab_node::get (exp)) { - /* When not building shared library and weak_dominate is true: - weak, common or initialized symbols are resolved locally. */ - if ((weak_dominate && !shlib && node->definition) - || node->in_other_partition - || resolution_local_p (node->resolution)) + if (node->definition || node->in_other_partition) + { + defined_locally = true; + resolved_locally = (weak_dominate && !shlib); + } + if (resolution_to_local_definition_p (node->resolution)) + defined_locally = resolved_locally = true; + else if (resolution_local_p (node->resolution)) resolved_locally = true; } - /* Undefined (or non-dominant) weak symbols are not defined locally. */ - if (DECL_WEAK (exp) && !resolved_locally) + /* Undefined weak symbols are never defined locally. */ + if (DECL_WEAK (exp) && !defined_locally) return false; - /* A variable is local if the user has said explicitly that it will be. */ - if (DECL_VISIBILITY_SPECIFIED (exp) - && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) + /* A symbol is local if the user has said explicitly that it will be, + or if we have a definition for the symbol. We cannot infer visibility + for undefined symbols. */ + if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT + && (DECL_VISIBILITY_SPECIFIED (exp) || defined_locally)) return true; + /* If PIC, then assume that any global name can be overridden by + symbols resolved from other modules. */ + if (shlib) + return false; + /* Variables defined outside this object might not be local. */ if (DECL_EXTERNAL (exp) && !resolved_locally) return false; - /* If defined in this object and visibility is not default, - must be local. */ - if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) - return true; - - /* If PIC, then assume that any global name can be overridden by - symbols resolved from other modules. */ - if (shlib) + /* Non-dominant weak symbols are not defined locally. */ + if (DECL_WEAK (exp) && !resolved_locally) return false; /* Uninitialized COMMON variable may be unified with symbols