* [lto][patch] Update cgraph with the symbol resolution information
@ 2008-10-22 14:47 Rafael Espindola
2008-10-22 15:01 ` Diego Novillo
0 siblings, 1 reply; 2+ messages in thread
From: Rafael Espindola @ 2008-10-22 14:47 UTC (permalink / raw)
To: gcc-patches; +Cc: Diego Novillo
[-- Attachment #1: Type: text/plain, Size: 1053 bytes --]
With this patch it is possible to have two .o with functions with the
same name and select among them by editing the resolution file passed
to lto1.
There is a remaining issue with extern inline functions. This can be
fixed by running the inliner during lgen (cc1/cc1plus). I am working
on that.
2008-10-07 Rafael Espindola <espindola@google.com>
* Make-lang.in (lto/lto-lang.o): Update dependencies.
* lto-lang.c: Include lto/common.h and lto-tree-in.h.
(input_overwrite_node): Don't call cgraph_mark_needed_node.
(input_node): Just read the node. Don't update it to reflect that
another node for the same decl might have been read.
(input_edge): Don't create an edge if the caller has been preempted.
Make sure the callee is the prevailing decl.
(input_cgraph_1): Remove nodes corresponding to preempted decls.
* lto.c (lto_main): Read the cgraph before calling lto_fixup_decls.
Cheers,
--
Rafael Avila de Espindola
Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: cgraph.patch --]
[-- Type: text/x-diff; name=cgraph.patch, Size: 8563 bytes --]
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index 1678926..d6f45e7 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -91,7 +91,8 @@ LTO_TREE_H = lto/lto-tree.h $(PLUGIN_API_H)
lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \
flags.h $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(SYSTEM_H) \
$(TM_H) $(LTO_TREE_H) $(LTO_H) $(GIMPLE_H) \
- gtype-lto.h gt-lto-lto-lang.h except.h libfuncs.h
+ gtype-lto.h gt-lto-lto-lang.h except.h libfuncs.h lto/common.h \
+ lto-tree-in.h
lto/lto.o: lto/lto.c $(CONFIG_H) $(CGRAPH_H) coretypes.h \
$(GGC_H) opts.h $(SYSTEM_H) toplev.h $(TM_H) $(LTO_H) langhooks.h \
$(LTO_TREE_H) dwarf2out.h tree-ssa-operands.h gt-lto-lto.h \
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 7dfcdc2..c2026d7 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -38,6 +38,8 @@ Boston, MA 02110-1301, USA. */
#include "libfuncs.h"
#include "except.h"
#include "cgraph.h"
+#include "lto/common.h"
+#include "lto-tree-in.h"
static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
static tree handle_const_attribute (tree *, tree, tree, int, bool *);
@@ -1099,8 +1101,6 @@ input_overwrite_node (struct lto_file_decl_data* file_data,
node->needed = lto_get_flag (&flags);
node->analyzed = node->local.finalized;
node->lowered = node->local.finalized;
- if (cgraph_decide_is_function_needed (node))
- cgraph_mark_needed_node (node);
}
/* Read a node from input_block IB. TAG is the node's tag just read.
@@ -1120,14 +1120,13 @@ input_node (struct lto_file_decl_data* file_data,
int self_insns = 0;
unsigned decl_index;
bool clone_p;
- bool overwrite_p = false;
int estimated_stack_size = 0;
int stack_frame_offset = 0;
int ref = LCC_NOT_FOUND;
int insns = 0;
int estimated_growth = 0;
bool inlined = false;
-
+
LTO_DEBUG_TOKEN ("clone_p");
clone_p = lto_input_uleb128 (ib);
@@ -1175,50 +1174,21 @@ input_node (struct lto_file_decl_data* file_data,
inlined = lto_input_uleb128 (ib);
}
- switch (tag)
- {
- case LTO_cgraph_avail_node:
- /* We cannot have two avail functions that are the same. */
- gcc_assert (((enum LTO_cgraph_tags)(node->aux))
- != LTO_cgraph_avail_node);
- overwrite_p = true;
- break;
-
- case LTO_cgraph_unavail_node:
- /* We only overwrite the node if this is a brand new node. */
- if (!node->aux)
- overwrite_p = true;
- break;
-
- case LTO_cgraph_overwritable_node:
- /* FIXME lto: This code is written to take the last
- overwrittable version. I do not speak linker but if the
- linker supposed to take the first one, then we need to
- change the test. */
- if (((enum LTO_cgraph_tags)(node->aux)) != LTO_cgraph_avail_node)
- overwrite_p = true;
- break;
-
- default:
- gcc_unreachable ();
- }
+ gcc_assert (!node->aux);
- if (overwrite_p)
+ input_overwrite_node (file_data, node, tag, flags, stack_size,
+ self_insns);
+ if (flag_ltrans)
{
- input_overwrite_node (file_data, node, tag, flags, stack_size,
- self_insns);
- if (flag_ltrans)
- {
- node->global.estimated_stack_size = estimated_stack_size;
- node->global.stack_frame_offset = stack_frame_offset;
- node->global.insns = insns;
- if (ref != LCC_NOT_FOUND)
- node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
- else
- node->global.inlined_to = NULL;
- node->global.estimated_growth = estimated_growth;
- node->global.inlined = inlined;
- }
+ node->global.estimated_stack_size = estimated_stack_size;
+ node->global.stack_frame_offset = stack_frame_offset;
+ node->global.insns = insns;
+ if (ref != LCC_NOT_FOUND)
+ node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
+ else
+ node->global.inlined_to = NULL;
+ node->global.estimated_growth = estimated_growth;
+ node->global.inlined = inlined;
}
return node;
@@ -1238,15 +1208,29 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
unsigned int nest;
cgraph_inline_failed_t inline_failed;
unsigned HOST_WIDEST_INT flags;
+ tree prevailing;
+ enum ld_plugin_symbol_resolution caller_resolution;
LTO_DEBUG_TOKEN ("caller");
caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
gcc_assert (caller);
+ gcc_assert (caller->decl);
LTO_DEBUG_TOKEN ("callee");
callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
gcc_assert (callee);
-
+ gcc_assert (callee->decl);
+
+ caller_resolution = lto_symtab_get_resolution (caller->decl);
+
+ /* FIXME lto: The following assert would currently fail since for bodies
+ of extern inline functions. */
+
+/* gcc_assert (caller_resolution == LDPR_PREVAILING_DEF */
+/* || caller_resolution == LDPR_PREVAILING_DEF_IRONLY */
+/* || caller_resolution == LDPR_PREEMPTED_REG */
+/* || caller_resolution == LDPR_PREEMPTED_IR); */
+
LTO_DEBUG_TOKEN ("stmt");
stmt_id = lto_input_uleb128 (ib);
LTO_DEBUG_TOKEN ("inline_failed");
@@ -1259,7 +1243,35 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
nest = lto_input_uleb128 (ib);
LTO_DEBUG_TOKEN ("flags");
flags = lto_input_uleb128 (ib);
-
+
+ /* If the caller was preempted, don't create the edge. */
+ if (caller_resolution == LDPR_PREEMPTED_REG
+ || caller_resolution == LDPR_PREEMPTED_IR)
+ return;
+
+ /* Make sure the callee is the prevailing decl. */
+ prevailing = lto_symtab_prevailing_decl (callee->decl);
+
+ /* FIXME lto: remove this once extern inline in handled in lgen. */
+ if (caller_resolution != LDPR_PREVAILING_DEF
+ && caller_resolution != LDPR_PREVAILING_DEF_IRONLY
+ && caller_resolution != LDPR_PREEMPTED_REG
+ && caller_resolution != LDPR_PREEMPTED_IR)
+ {
+ /* If we have a extern inline, make sure it is the prevailing. */
+ gcc_assert (prevailing == callee->decl);
+ }
+
+ if (prevailing != callee->decl)
+ {
+ /* We cannot replace a clone! */
+ gcc_assert (callee == cgraph_node (callee->decl));
+
+
+ callee = cgraph_node (prevailing);
+ gcc_assert (callee);
+ }
+
edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
edge->lto_stmt_uid = stmt_id;
edge->inline_failed = inline_failed;
@@ -1278,7 +1290,9 @@ input_cgraph_1 (struct lto_file_decl_data* file_data,
{
enum LTO_cgraph_tags tag;
VEC(cgraph_node_ptr, heap) *nodes = NULL;
+ VEC(cgraph_node_ptr, heap) *del_list = NULL;
struct cgraph_node *node;
+ unsigned i;
tag = lto_input_uleb128 (ib);
while (tag)
@@ -1290,6 +1304,8 @@ input_cgraph_1 (struct lto_file_decl_data* file_data,
else
{
node = input_node (file_data, ib, tag, nodes);
+ gcc_assert (node);
+ gcc_assert (node->decl);
VEC_safe_push (cgraph_node_ptr, heap, nodes, node);
}
@@ -1297,7 +1313,23 @@ input_cgraph_1 (struct lto_file_decl_data* file_data,
tag = lto_input_uleb128 (ib);
}
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ tree prevailing = lto_symtab_prevailing_decl (node->decl);
+
+ if (prevailing != node->decl)
+ VEC_safe_push (cgraph_node_ptr, heap, del_list, node);
+ }
+
+ for (i = 0; VEC_iterate (cgraph_node_ptr, del_list, i, node); i++)
+ cgraph_remove_node (node);
+
+ for (node = cgraph_nodes; node; node = node->next)
+ if (cgraph_decide_is_function_needed (node))
+ cgraph_mark_needed_node (node);
+
VEC_free (cgraph_node_ptr, heap, nodes);
+ VEC_free (cgraph_node_ptr, heap, del_list);
}
/* Input and merge the cgraph from each of the .o files passed to
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index bc097de..370dc6d 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1026,12 +1026,14 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
all_file_decl_data[j] = NULL;
- lto_fixup_decls (all_file_decl_data);
-
/* Set the hooks so that all of the ipa passes can read in their data. */
lto_set_in_hooks (all_file_decl_data, get_section_data,
free_section_data);
+ ipa_read_summaries ();
+
+ lto_fixup_decls (all_file_decl_data);
+
/* FIXME!!! This loop needs to be changed to use the pass manager to
call the ipa passes directly. */
for (i = 0; i < j; i++)
@@ -1041,8 +1043,6 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
lto_materialize_constructors_and_inits (file_data);
}
- ipa_read_summaries ();
-
if (flag_wpa)
lto_1_to_1_map ();
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [lto][patch] Update cgraph with the symbol resolution information
2008-10-22 14:47 [lto][patch] Update cgraph with the symbol resolution information Rafael Espindola
@ 2008-10-22 15:01 ` Diego Novillo
0 siblings, 0 replies; 2+ messages in thread
From: Diego Novillo @ 2008-10-22 15:01 UTC (permalink / raw)
To: Rafael Espindola; +Cc: gcc-patches
On Wed, Oct 22, 2008 at 09:49, Rafael Espindola <espindola@google.com> wrote:
> 2008-10-07 Rafael Espindola <espindola@google.com>
>
> * Make-lang.in (lto/lto-lang.o): Update dependencies.
> * lto-lang.c: Include lto/common.h and lto-tree-in.h.
> (input_overwrite_node): Don't call cgraph_mark_needed_node.
> (input_node): Just read the node. Don't update it to reflect that
> another node for the same decl might have been read.
> (input_edge): Don't create an edge if the caller has been preempted.
> Make sure the callee is the prevailing decl.
> (input_cgraph_1): Remove nodes corresponding to preempted decls.
> * lto.c (lto_main): Read the cgraph before calling lto_fixup_decls.
OK.
Diego.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-10-22 14:04 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-22 14:47 [lto][patch] Update cgraph with the symbol resolution information Rafael Espindola
2008-10-22 15:01 ` Diego Novillo
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).