public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* symtab cleanups 3/17: fix alias visibility logic
@ 2013-06-03 14:07 Jan Hubicka
  2013-06-05  8:16 ` Andreas Schwab
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Hubicka @ 2013-06-03 14:07 UTC (permalink / raw)
  To: gcc-patches

Hi,
GCC's alias support follows how C level alias attributes work: function
bodies/variable initializers are associated with particular symbols and other
aliases are separate symbol referring to the one they are aliasing.

In ELF implementation and by my understanding of BFD also everywher else
the aliases are just symbols pointing to the same place as the symbol they
are aliasing.

This has different semanting WRT interposing.  In GCC vision, when you interpose
the alias target, the alias itself is retargetted to new destination. In ELF
implementation this does not happen and it is used common for the internal
aliases within shared libraries.

This patch makes GCC to follow ELF semantic in the visibility code and inlining.
Other IPA passes needs further updating and so does the lto-symtab code where
interposition is implemented in the wrong way.

Bootstrapped/regtested x86_64-linux and ppc64-linux, will commit it shortly.

Honza

	* gcc.dg/tree-ssa/attr-alias.c: New testcase.

	* ipa-inline.c (update_caller_keys): Fix availability test.
	(update_callee_keys): Likewise.
	* symtab.c (symtab_alias_ultimate_target): Make availaiblity logic
	to follow ELF standard.
Index: testsuite/gcc.dg/tree-ssa/attr-alias.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/attr-alias.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/attr-alias.c	(revision 0)
***************
*** 0 ****
--- 1,29 ----
+ /* { dg-do compile } */
+ /* { dg-require-alias "" } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ void abort (void);
+ __attribute__ ((weak))
+ int test() 
+ {
+    return 0;
+ }
+ static int test2() __attribute__ ((alias("test")));
+ static int test3() __attribute__ ((weakref)) __attribute__ ((alias("test2")));
+ static int test4() __attribute__ ((weakref)) __attribute__ ((alias("test")));
+ main()
+ {
+   test();
+   test2();
+   test3();
+   test4();
+ }
+ 
+ /* calls to test1 and test2 can be inlined and optmized away. Calls
+    to test and test4 are overwritable.  */
+ 
+ /* { dg-final { scan-tree-dump-times "test (" 2 "optimized" } } */
+ /* { dg-final { scan-tree-dump-times "test4 (" 1 "optimized" } } */
+ /* { dg-final { scan-tree-dump-not "test1 (" "optimized" } } */
+ /* { dg-final { scan-tree-dump-not "test2 (" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
+ 
Index: ipa-inline.c
===================================================================
*** ipa-inline.c	(revision 199591)
--- ipa-inline.c	(working copy)
*************** update_caller_keys (fibheap_t heap, stru
*** 1101,1107 ****
    struct ipa_ref *ref;
  
    if ((!node->symbol.alias && !inline_summary (node)->inlinable)
-       || cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE
        || node->global.inlined_to)
      return;
    if (!bitmap_set_bit (updated_nodes, node->uid))
--- 1101,1106 ----
*************** update_callee_keys (fibheap_t heap, stru
*** 1162,1168 ****
  	if (e->inline_failed
  	    && (callee = cgraph_function_or_thunk_node (e->callee, &avail))
  	    && inline_summary (callee)->inlinable
! 	    && cgraph_function_body_availability (callee) >= AVAIL_AVAILABLE
  	    && !bitmap_bit_p (updated_nodes, callee->uid))
  	  {
  	    if (can_inline_edge_p (e, false)
--- 1161,1167 ----
  	if (e->inline_failed
  	    && (callee = cgraph_function_or_thunk_node (e->callee, &avail))
  	    && inline_summary (callee)->inlinable
! 	    && avail >= AVAIL_AVAILABLE
  	    && !bitmap_bit_p (updated_nodes, callee->uid))
  	  {
  	    if (can_inline_edge_p (e, false)
Index: symtab.c
===================================================================
*** symtab.c	(revision 199591)
--- symtab.c	(working copy)
*************** symtab_node_availability (symtab_node no
*** 834,852 ****
  symtab_node
  symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
  {
    if (availability)
!     *availability = symtab_node_availability (node);
    while (node)
      {
        if (node->symbol.alias && node->symbol.analyzed)
  	node = symtab_alias_target (node);
        else
! 	return node;
!       if (node && availability)
  	{
  	  enum availability a = symtab_node_availability (node);
  	  if (a < *availability)
  	    *availability = a;
  	}
      }
    if (availability)
--- 834,897 ----
  symtab_node
  symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
  {
+   bool weakref_p = false;
+ 
+   if (!node->symbol.alias)
+     {
+       if (availability)
+         *availability = symtab_node_availability (node);
+       return node;
+     }
+ 
+   /* To determine visibility of the target, we follow ELF semantic of aliases.
+      Here alias is an alternative assembler name of a given definition. Its
+      availablity prevails the availablity of its target (i.e. static alias of
+      weak definition is available.
+ 
+      Weakref is a different animal (and not part of ELF per se). It is just
+      alternative name of a given symbol used within one complation unit
+      and is translated prior hitting the object file.  It inherits the
+      visibility of its target (i.e. weakref of non-overwritable definition
+      is non-overwritable, while weakref of weak definition is weak).
+ 
+      If we ever get into supporting targets with different semantics, a target
+      hook will be needed here.  */
+ 
    if (availability)
!     {
!       weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
!       if (!weakref_p)
!         *availability = symtab_node_availability (node);
!       else
! 	*availability = AVAIL_LOCAL;
!     }
    while (node)
      {
        if (node->symbol.alias && node->symbol.analyzed)
  	node = symtab_alias_target (node);
        else
! 	{
! 	  if (!availability)
! 	    ;
! 	  else if (node->symbol.analyzed)
! 	    {
! 	      if (weakref_p)
! 		{
! 		  enum availability a = symtab_node_availability (node);
! 		  if (a < *availability)
! 		    *availability = a;
! 		}
! 	    }
! 	  else
! 	    *availability = AVAIL_NOT_AVAILABLE;
! 	  return node;
! 	}
!       if (node && availability && weakref_p)
  	{
  	  enum availability a = symtab_node_availability (node);
  	  if (a < *availability)
  	    *availability = a;
+           weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
  	}
      }
    if (availability)

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: symtab cleanups 3/17: fix alias visibility logic
  2013-06-03 14:07 symtab cleanups 3/17: fix alias visibility logic Jan Hubicka
@ 2013-06-05  8:16 ` Andreas Schwab
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Schwab @ 2013-06-05  8:16 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

Jan Hubicka <hubicka@ucw.cz> writes:

> 	* gcc.dg/tree-ssa/attr-alias.c: New testcase.

I've removed the duplicated contents.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-06-05  8:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-03 14:07 symtab cleanups 3/17: fix alias visibility logic Jan Hubicka
2013-06-05  8:16 ` Andreas Schwab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).