aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraphunit.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2014-09-24 03:29:24 +0000
committerAndi Kleen <ak@gcc.gnu.org>2014-09-24 03:29:24 +0000
commit7861b6489dd7777b1b8829fd8726079f133eb34c (patch)
tree73e70259b9d2f956939310c8f0e194397eda7e4b /gcc/cgraphunit.c
parent2f4a54f2d91538336797b9a5401c83e6f9831f0b (diff)
downloadgcc-7861b6489dd7777b1b8829fd8726079f133eb34c.zip
gcc-7861b6489dd7777b1b8829fd8726079f133eb34c.tar.gz
gcc-7861b6489dd7777b1b8829fd8726079f133eb34c.tar.bz2
Add an no_reorder attribute for LTO
Some projects need to prevent reordering of specific top level declarations with LTO, in particular declarations defining init calls. The only way to do that with LTO was to use -fno-toplevel-reorder, which stops reordering for all declarations and makes LTO partitioning less efficient. This patch adds a new no_reorder attribute that stops reordering only for the marked declaration. The program can then only mark e.g. the initcalls and leave all the other declarations alone. The patch does: - Adds the new no_reorder attribute for the C family. - Initializes a new no_reorder flag in the symtab_nodes in the function visibility flag. - Maintains the no_reorder flag when creating new nodes. - Changes the partition code to always keep a separate sorted queue of ordered nodes and flush them in order with the other nodes. This is used by all nodes with -fno-toplevel-reorder, and only the marked ones without it. Parts of the old -fno-toplevel-reorder code paths are reused. - Adds various checks throughout the tree to make no_reorder marked functions behave the same as with -fno-toplevel-reorder - Changes the LTO streamer to serialize the no_reorder attribute. gcc/c-family/: 2014-09-23 Andi Kleen <ak@linux.intel.com> * c-common.c (handle_no_reorder_attribute): New function. (c_common_attribute_table): Add no_reorder attribute. gcc/: 2014-09-23 Andi Kleen <ak@linux.intel.com> * cgraph.h (symtab_node): Add no_reorder attribute. (symbol_table::output_asm_statements): Remove. * cgraphclones.c (cgraph_node::create_clone): Copy no_reorder. (cgraph_node::create_version_clone): Dito. (symbol_table::output_asm_statements): Remove. * trans-mem.c (ipa_tm_create_version_alias): Dito. * cgraphunit.c (varpool_node::finalize_decl): Check no_reorder. (output_in_order): Add no_reorder flag. Only handle no_reorder nodes when set. (symbol_table::compile): Add separate pass for no_reorder nodes. (process_common_attributes): Set no_reorder flag in symtab node. Add node argument. (process_function_and_variable_attributes): Pass symtab nodes to process_common_attributes. * doc/extend.texi (no_reorder): Document no_reorder attribute. * lto-cgraph.c (lto_output_node): Serialize no_reorder. (lto_output_varpool_node): Dito. (input_overwrite_node): Dito. (input_varpool_node): Dito. * varpool.c (varpool_node::add): Set no_reorder attribute. (symbol_table::remove_unreferenced_decls): Handle no_reorder. (symbol_table::output_variables): Dito. * symtab.c (symtab_node::dump_base): Print no_reorder. gcc/lto/: 2014-09-23 Andi Kleen <ak@linux.intel.com> * lto-partition.c (node_cmp): Update comment. (varpool_node_cmp): Use symtab_node for comparison. (add_sorted_nodes): New function. (lto_balanced_map): Change to keep ordered queue of ordered node. Handle no_reorder attribute. From-SVN: r215537
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r--gcc/cgraphunit.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 3e3b8d2..b854e4b 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -545,22 +545,6 @@ cgraph_node::add_new_function (tree fndecl, bool lowered)
DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
}
-/* Output all asm statements we have stored up to be output. */
-
-void
-symbol_table::output_asm_statements (void)
-{
- asm_node *can;
-
- if (seen_error ())
- return;
-
- for (can = first_asm_symbol (); can; can = can->next)
- assemble_asm (can->asm_str);
-
- clear_asm_symbols ();
-}
-
/* Analyze the function scheduled to be output. */
void
cgraph_node::analyze (void)
@@ -657,7 +641,7 @@ symbol_table::process_same_body_aliases (void)
/* Process attributes common for vars and functions. */
static void
-process_common_attributes (tree decl)
+process_common_attributes (symtab_node *node, tree decl)
{
tree weakref = lookup_attribute ("weakref", DECL_ATTRIBUTES (decl));
@@ -670,6 +654,9 @@ process_common_attributes (tree decl)
DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
DECL_ATTRIBUTES (decl));
}
+
+ if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
+ node->no_reorder = 1;
}
/* Look for externally_visible and used attributes and mark cgraph nodes
@@ -734,7 +721,7 @@ process_function_and_variable_attributes (cgraph_node *first,
warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
"always_inline function might not be inlinable");
- process_common_attributes (decl);
+ process_common_attributes (node, decl);
}
for (vnode = symtab->first_variable (); vnode != first_var;
vnode = symtab->next_variable (vnode))
@@ -763,7 +750,7 @@ process_function_and_variable_attributes (cgraph_node *first,
DECL_ATTRIBUTES (decl) = remove_attribute ("weakref",
DECL_ATTRIBUTES (decl));
}
- process_common_attributes (decl);
+ process_common_attributes (vnode, decl);
}
}
@@ -785,8 +772,10 @@ varpool_node::finalize_decl (tree decl)
if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
/* Traditionally we do not eliminate static variables when not
optimizing and when not doing toplevel reoder. */
- || (!flag_toplevel_reorder && !DECL_COMDAT (node->decl)
- && !DECL_ARTIFICIAL (node->decl)))
+ || node->no_reorder
+ || ((!flag_toplevel_reorder
+ && !DECL_COMDAT (node->decl)
+ && !DECL_ARTIFICIAL (node->decl))))
node->force_output = true;
if (symtab->state == CONSTRUCTION
@@ -1922,10 +1911,11 @@ struct cgraph_order_sort
according to their order fields, which is the order in which they
appeared in the file. This implements -fno-toplevel-reorder. In
this mode we may output functions and variables which don't really
- need to be output. */
+ need to be output.
+ When NO_REORDER is true only do this for symbols marked no reorder. */
static void
-output_in_order (void)
+output_in_order (bool no_reorder)
{
int max;
cgraph_order_sort *nodes;
@@ -1940,6 +1930,8 @@ output_in_order (void)
{
if (pf->process && !pf->thunk.thunk_p && !pf->alias)
{
+ if (no_reorder && !pf->no_reorder)
+ continue;
i = pf->order;
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
nodes[i].kind = ORDER_FUNCTION;
@@ -1950,6 +1942,8 @@ output_in_order (void)
FOR_EACH_DEFINED_VARIABLE (pv)
if (!DECL_EXTERNAL (pv->decl))
{
+ if (no_reorder && !pv->no_reorder)
+ continue;
i = pv->order;
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
nodes[i].kind = ORDER_VAR;
@@ -2203,11 +2197,12 @@ symbol_table::compile (void)
state = EXPANSION;
if (!flag_toplevel_reorder)
- output_in_order ();
+ output_in_order (false);
else
{
- output_asm_statements ();
-
+ /* Output first asm statements and anything ordered. The process
+ flag is cleared for these nodes, so we skip them later. */
+ output_in_order (true);
expand_all_functions ();
output_variables ();
}