Re: Transparent alias suport part 7 (lto-symtab support)

2015-12-12 Thread H.J. Lu
On Tue, Dec 8, 2015 at 2:30 PM, Jan Hubicka  wrote:
> Hi,
> this patch adds support to lto-symtab.c to prevent merging of certain
> declarations.  The new predicate lto_symtab_merge_p can be used to decide
> about this.   The change is pretty straigforward.  lto_symtab_merge_decls_2
> makes the decisions about what decls to merge and lto_symtab_merge_symbols_1
> does the corresponding symbol merging/creation of transparent aliases.
>
> I re-implemented lto_symtab_prevailing_decl and moved it to inline so the
> merging pass is also considerably faster (it used to do quite expensive
> assembler name hash lookup on every occurenceof the decl).  Merging decisions
> are represented by setting DECL_ABSTRACT_ORIGIN to error_mark_node and
> DECL_CHAIN to the replacement decl.  This is quite arbitrary decision - I 
> needed
> a pointer and flag that is not going to mess with the warnings we output
> during the lto-symtab's operation.
>
> The patch does not disable any of the wrong merging we are hitting.  I will
> dot hat separately and with a testcases.  I only revisited a bit the way
> builtins are handled.
>
> Bootstrapped/regtested x86_64-linux. I am re-running the lto-bootstrap after
> some last minute changes and plan commit once it converges.
>
> Honza
>
> PR ipa/61886
> * lto-streamer.h (lto_symtab_merge_decls, lto_symtab_merge_symbols,
> lto_symtab_prevailing_decl): MOve to lto-symtab.h.
>
> * lto-symtab.c: Include lto-symtab.h.
> (lto_cgraph_replace_node): Do not merge profiles here.
> (lto_symtab_merge_p): New function.
> (lto_symtab_merge_decls_2): Honor lto_symtab_merge_p.
> (lto_symtab_merge_symbols_1): Turn unmerged decls into transparent
> aliases.
> (lto_symtab_merge_symbols): Do not clear node->aux; we no longer use 
> it.
> (lto_symtab_prevailing_decl): Move to lto-symtab.h; rewrite.
> * lto.c: Include lto-symtab.h
> * lto-symtab.h: New.
>

This caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68878


-- 
H.J.


Transparent alias suport part 7 (lto-symtab support)

2015-12-08 Thread Jan Hubicka
Hi,
this patch adds support to lto-symtab.c to prevent merging of certain
declarations.  The new predicate lto_symtab_merge_p can be used to decide
about this.   The change is pretty straigforward.  lto_symtab_merge_decls_2
makes the decisions about what decls to merge and lto_symtab_merge_symbols_1
does the corresponding symbol merging/creation of transparent aliases.

I re-implemented lto_symtab_prevailing_decl and moved it to inline so the
merging pass is also considerably faster (it used to do quite expensive
assembler name hash lookup on every occurenceof the decl).  Merging decisions
are represented by setting DECL_ABSTRACT_ORIGIN to error_mark_node and
DECL_CHAIN to the replacement decl.  This is quite arbitrary decision - I needed
a pointer and flag that is not going to mess with the warnings we output
during the lto-symtab's operation.

The patch does not disable any of the wrong merging we are hitting.  I will
dot hat separately and with a testcases.  I only revisited a bit the way
builtins are handled.

Bootstrapped/regtested x86_64-linux. I am re-running the lto-bootstrap after
some last minute changes and plan commit once it converges.

Honza

PR ipa/61886
* lto-streamer.h (lto_symtab_merge_decls, lto_symtab_merge_symbols,
lto_symtab_prevailing_decl): MOve to lto-symtab.h.

* lto-symtab.c: Include lto-symtab.h.
(lto_cgraph_replace_node): Do not merge profiles here.
(lto_symtab_merge_p): New function.
(lto_symtab_merge_decls_2): Honor lto_symtab_merge_p.
(lto_symtab_merge_symbols_1): Turn unmerged decls into transparent
aliases.
(lto_symtab_merge_symbols): Do not clear node->aux; we no longer use it.
(lto_symtab_prevailing_decl): Move to lto-symtab.h; rewrite.
* lto.c: Include lto-symtab.h
* lto-symtab.h: New.

Index: lto/lto-symtab.c
===
--- lto/lto-symtab.c(revision 231424)
+++ lto/lto-symtab.c(working copy)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.
 #include "ipa-utils.h"
 #include "builtins.h"
 #include "alias.h"
+#include "lto-symtab.h"
 
 /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
all edges and removing the old node.  */
@@ -99,7 +100,6 @@ lto_cgraph_replace_node (struct cgraph_n
   node->instrumented_version = NULL;
 }
 
-  ipa_merge_profiles (prevailing_node, node);
   lto_free_function_in_decl_state_for_node (node);
 
   if (node->decl != prevailing_node->decl)
@@ -503,6 +503,30 @@ lto_symtab_resolve_symbols (symtab_node
   return prevailing;
 }
 
+/* Decide if it is OK to merge DECL into PREVAILING.
+   Because we wrap most of uses of declarations in MEM_REF, we can tolerate
+   some differences but other code may inspect directly the DECL.  */
+
+static bool
+lto_symtab_merge_p (tree prevailing, tree decl)
+{
+  if (TREE_CODE (prevailing) != TREE_CODE (decl))
+return false;
+  if (TREE_CODE (prevailing) == FUNCTION_DECL)
+{
+  if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl))
+   return false;
+  if (DECL_BUILT_IN (prevailing)
+ && (DECL_BUILT_IN_CLASS (prevailing) != DECL_BUILT_IN_CLASS (decl)
+ || DECL_FUNCTION_CODE (prevailing) != DECL_FUNCTION_CODE (decl)))
+   return false;
+}
+  /* There are several other cases where merging can not be done, but until
+ aliasing code is fixed to support aliases it we can not really return
+ false on non-readonly var, yet.  */
+  return true;
+}
+
 /* Merge all decls in the symbol table chain to the prevailing decl and
issue diagnostics about type mismatches.  If DIAGNOSED_P is true
do not issue further diagnostics.*/
@@ -590,6 +614,54 @@ lto_symtab_merge_decls_2 (symtab_node *f
"-fno-strict-aliasing is used");
 
   mismatches.release ();
+  symtab_node *last_prevailing = prevailing, *next;
+  for (e = prevailing->next_sharing_asm_name; e; e = next)
+{
+  next = e->next_sharing_asm_name;
+
+  /* Skip non-LTO symbols and symbols whose declaration we already
+visited.  */
+  if (lto_symtab_prevailing_decl (e->decl) != e->decl
+ || !lto_symtab_symbol_p (e)
+  || e->decl == prevailing->decl)
+   continue;
+
+  symtab_node *this_prevailing;
+  for (this_prevailing = prevailing; ;
+  this_prevailing = this_prevailing->next_sharing_asm_name)
+   {
+ if (lto_symtab_merge_p (this_prevailing->decl, e->decl))
+   break;
+ if (this_prevailing == last_prevailing)
+   {
+ this_prevailing = NULL;
+ break;
+   }
+   }
+
+  if (this_prevailing)
+   lto_symtab_prevail_decl (this_prevailing->decl, e->decl);
+  /* Maintain LRU list: relink the new prevaililng symbol
+just after previaling node in the chain and update