aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/lto/ChangeLog7
-rw-r--r--gcc/lto/lto-symtab.c17
-rw-r--r--gcc/lto/lto.c1
3 files changed, 25 insertions, 0 deletions
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 56dcfa8..8d3c83f 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,5 +1,12 @@
2015-08-31 Richard Biener <rguenther@suse.de>
+ * lto.c (compare_tree_sccs_1): Compare DECL_ABSTRACT_ORIGIN.
+ * lto-symtab.c (lto_symtab_merge): Merge DECL_POSSIBLY_INLINED flag.
+ (lto_symtab_prevailing_decl): Do not replace a decl that didn't
+ participate in merging with something else.
+
+2015-08-31 Richard Biener <rguenther@suse.de>
+
* lto-symtab.c (lto_symtab_prevailing_decl): Remove redundant
test, do not replace a non-builtin with a builtin.
* lto.c (compare_tree_sccs_1): Do not merge things we stream
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index d50a1ab..c77ae947 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -312,6 +312,11 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
if (TREE_CODE (decl) == FUNCTION_DECL)
{
+ /* Merge decl state in both directions, we may still end up using
+ the new decl. */
+ DECL_POSSIBLY_INLINED (prevailing_decl) |= DECL_POSSIBLY_INLINED (decl);
+ DECL_POSSIBLY_INLINED (decl) |= DECL_POSSIBLY_INLINED (prevailing_decl);
+
if (warn_type_compatibility_p (TREE_TYPE (prevailing_decl),
TREE_TYPE (decl)))
return false;
@@ -798,6 +803,18 @@ lto_symtab_prevailing_decl (tree decl)
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_ABSTRACT_P (decl))
return decl;
+ /* When decl did not participate in symbol resolution leave it alone.
+ This can happen when we streamed the decl as abstract origin
+ from the block tree of inlining a partially inlined function.
+ If all, the split function and the original function end up
+ optimized away early we do not put the abstract origin into the
+ ltrans boundary and we'll end up ICEing in
+ dwarf2out.c:gen_inlined_subroutine_die because we eventually
+ replace a decl with DECL_POSSIBLY_INLINED set with one without. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && ! cgraph_node::get (decl))
+ return decl;
+
/* Ensure DECL_ASSEMBLER_NAME will not set assembler name. */
gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index b4287a3..4bb0aaf 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1305,6 +1305,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_tree_edges (DECL_SIZE (t1), DECL_SIZE (t2));
compare_tree_edges (DECL_SIZE_UNIT (t1), DECL_SIZE_UNIT (t2));
compare_tree_edges (DECL_ATTRIBUTES (t1), DECL_ATTRIBUTES (t2));
+ compare_tree_edges (DECL_ABSTRACT_ORIGIN (t1), DECL_ABSTRACT_ORIGIN (t2));
if ((code == VAR_DECL
|| code == PARM_DECL)
&& DECL_HAS_VALUE_EXPR_P (t1))