diff options
author | Andi Kleen <ak@linux.intel.com> | 2014-09-24 03:29:24 +0000 |
---|---|---|
committer | Andi Kleen <ak@gcc.gnu.org> | 2014-09-24 03:29:24 +0000 |
commit | 7861b6489dd7777b1b8829fd8726079f133eb34c (patch) | |
tree | 73e70259b9d2f956939310c8f0e194397eda7e4b /gcc/cgraphunit.c | |
parent | 2f4a54f2d91538336797b9a5401c83e6f9831f0b (diff) | |
download | gcc-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.c | 47 |
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 (); } |