* Re: Chromium: LTO
[not found] <54DE7CE2.8040202@suse.cz>
@ 2015-02-14 18:44 ` Jan Hubicka
2015-02-15 19:23 ` Trevor Saunders
0 siblings, 1 reply; 3+ messages in thread
From: Jan Hubicka @ 2015-02-14 18:44 UTC (permalink / raw)
To: Martin Liška, gcc-patches; +Cc: hubicka >> Jan Hubicka
Hi,
Maritn has notced that we spend a lot of time in simple cgraph/varpool predicates. The patch bellow
reorganizes inlines so the fast paths get fast.
> perf report:
>
> 18.79% lto1-wpa lto1 [.] do_estimate_growth_1(cgraph_node*, void*)
> 12.48% lto1-wpa lto1 [.] cgraph_node::can_remove_if_no_direct_calls_and_refs_p()
> 5.86% lto1-wpa lto1 [.] symtab_node::used_from_object_file_p_worker(symtab_node*)
> 5.69% lto1-wpa lto1 [.] cgraph_node::call_for_symbol_and_aliases(bool (*)(cgraph_node*, void*), void*, bool)
> 5.01% lto1-wpa-stream lto1 [.] streamer_tree_cache_lookup(streamer_tree_cache_d*, tree_node*, unsigned int*)
> 4.84% lto1-wpa lto1 [.] cgraph_node::call_for_symbol_thunks_and_aliases(bool (*)(cgraph_node*, void*), void*, bool, bool)
> 2.44% lto1-wpa lto1 [.] inflate_fast
> 2.10% lto1-wpa-stream lto1 [.] DFS::DFS_write_tree(output_block*, DFS::sccs*, tree_node*, bool, bool, bool)
> 2.03% lto1-wpa-stream lto1 [.] linemap_lookup(line_maps*, unsigned int)
> 1.30% lto1-wpa-stream [kernel.kallsyms] [k] isolate_migratepages_range
> 1.27% lto1-wpa lto1 [.] symtab_node::iterate_direct_aliases(unsigned int, ipa_ref*&)
> 1.21% lto1-wpa-stream lto1 [.] DFS::DFS_write_tree_body(output_block*, tree_node*, DFS::sccs*, bool, bool)
> 1.19% lto1-wpa-stream lto1 [.] streamer_write_uhwi_stream(lto_output_stream*, unsigned long)
> 0.85% lto1-wpa lto1 [.] compare_tree_sccs_1(tree_node*, tree_node*, tree_node***)
> 0.83% lto1-wpa lto1 [.] streamer_read_uhwi(lto_input_block*)
> 0.74% lto1-wpa-stream lto1 [.] streamer_tree_cache_insert_1(streamer_tree_cache_d*, tree_node*, unsigned int, unsigned int*, bool)
> 0.72% lto1-wpa lto1 [.] ht_lookup_with_hash(ht*, unsigned char const*, unsigned long, unsigned int, ht_lookup_option)
> 0.70% lto1-wpa-stream [kernel.kallsyms] [k] compaction_alloc
> 0.68% lto1-wpa lto1 [.] unify_scc(streamer_tree_cache_d*, unsigned int, unsigned int, unsigned int, unsigned int)
> 0.66% lto1-wpa-stream lto1 [.] lto_output_tree(output_block*, tree_node*, bool, bool)
> 0.66% lto1-wpa-stream libc-2.19.so [.] _int_malloc
> 0.66% lto1-wpa-stream lto1 [.] hash_table<hash_map<tree_node*, unsigned int, default_hashmap_traits>::hash_entry, xcallocator, true>::expand()
> 0.62% lto1-wpa-stream lto1 [.] streamer_write_tree_bitfields(output_block*, tree_node*)
> 0.61% lto1-wpa lto1 [.] streamer_read_tree_bitfields(lto_input_block*, data_in*, tree_node*)
> 0.53% lto1-wpa lto1 [.] lto_cgraph_replace_node(cgraph_node*, cgraph_node*)
> 0.49% lto1-wpa [kernel.kallsyms] [k] copy_pte_range
Bootstrapped/regtested x86_64-linux, comitted.
Honza
* ipa-chkp.c: Use iterate_direct_aliases.
* symtab.c (resolution_used_from_other_file_p): Move inline.
(symtab_node::create_reference): Fix formating.
(symtab_node::has_aliases_p): Move inline; use iterate_direct_aliases.
(symtab_node::iterate_reference): Move inline.
(symtab_node::iterate_referring): Move inline.
(symtab_node::iterate_direct_aliases): Move inline.
(symtab_node::used_from_object_file_p_worker): Inline into ...
(symtab_node::used_from_object_file_p): ... this one; move inline.
(symtab_node::call_for_symbol_and_aliases): Move inline;
use iterate_direct_aliases.
(symtab_node::call_for_symbol_and_aliases_1): New method.
(cgraph_node::call_for_symbol_and_aliases): Move inline;
use iterate_direct_aliases.
(cgraph_node::call_for_symbol_and_aliases_1): New method.
(varpool_node::call_for_node_and_aliases): Rename to ...
(varpool_node::call_for_symbol_and_aliases): ... this one; Move inline;
use iterate_direct_aliases.
(varpool_node::call_for_symbol_and_aliases_1): New method.
* ipa.c (ipa_single_use): Use iterate_direct_aliases.
(ipa_discover_readonly_nonaddressable_var): Update.
* ipa-devirt.c: Fix formating.
* cgraph.c (cgraph_node::can_remove_if_no_direct_calls_and_refs_p):
Move inline.
(cgraph_node::call_for_symbol_and_aliases): Move inline.
(cgraph_node::call_for_symbol_and_aliases_1): New function..
* cgraph.h (used_from_object_file_p_worker): Remove.
(resolution_used_from_other_file_p): Move inline.
(symtab_node::has_aliases_p): Move inline; use iterate_direct_aliases.
(symtab_node::iterate_reference): Move inline.
(symtab_node::iterate_referring): Move inline.
(symtab_node::iterate_direct_aliases): Move inline.
(symtab_node::used_from_object_file_p_worker): Inline into ...
(symtab_node::used_from_object_file_p): Move inline.
* tree-emutls.c (ipa_lower_emutls): Update.
* varpool.c (varpool_node::call_for_symbol_and_aliases_1): New method.
(varpool_node::call_for_node_and_aliases): Remove.
Index: tree-emutls.c
===================================================================
--- tree-emutls.c (revision 220606)
+++ tree-emutls.c (working copy)
@@ -787,7 +787,7 @@ ipa_lower_emutls (void)
if (var->alias && !var->analyzed)
any_aliases = true;
else if (!var->alias)
- var->call_for_node_and_aliases (create_emultls_var, &ctor_body, true);
+ var->call_for_symbol_and_aliases (create_emultls_var, &ctor_body, true);
}
/* If there were any aliases, then frob the alias_pairs vector. */
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c (revision 220606)
+++ ipa-devirt.c (working copy)
@@ -1710,7 +1710,6 @@ referenced_from_vtable_p (struct cgraph_
return true;
for (i = 0; node->iterate_referring (i, ref); i++)
-
if ((ref->use == IPA_REF_ALIAS
&& referenced_from_vtable_p (dyn_cast<cgraph_node *> (ref->referring)))
|| (ref->use == IPA_REF_ADDR
Index: ipa-chkp.c
===================================================================
--- ipa-chkp.c (revision 220606)
+++ ipa-chkp.c (working copy)
@@ -534,14 +534,13 @@ chkp_maybe_create_clone (tree fndecl)
symtab->call_cgraph_insertion_hooks (clone);
/* Clone all aliases. */
- for (i = 0; node->iterate_referring (i, ref); i++)
- if (ref->use == IPA_REF_ALIAS)
- {
- struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
- struct cgraph_node *chkp_alias
- = chkp_maybe_create_clone (alias->decl);
- chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
- }
+ for (i = 0; node->iterate_direct_aliases (i, ref); i++)
+ {
+ struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+ struct cgraph_node *chkp_alias
+ = chkp_maybe_create_clone (alias->decl);
+ chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
+ }
/* Clone all thunks. */
for (e = node->callers; e; e = e->next_caller)
Index: symtab.c
===================================================================
--- symtab.c (revision 220630)
+++ symtab.c (working copy)
@@ -313,18 +313,6 @@ symbol_table::change_decl_assembler_name
}
}
-/* Return true when RESOLUTION indicate that linker will use
- the symbol from non-LTO object files. */
-
-bool
-resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
-{
- return (resolution == LDPR_PREVAILING_DEF
- || resolution == LDPR_PREEMPTED_REG
- || resolution == LDPR_RESOLVED_EXEC
- || resolution == LDPR_RESOLVED_DYN);
-}
-
/* Hash sections by their names. */
hashval_t
@@ -527,18 +515,18 @@ symtab_node::create_reference (symtab_no
/* IPA_REF_ALIAS is always inserted at the beginning of the list. */
if(use_type == IPA_REF_ALIAS)
- {
- list2->referring.safe_insert (0, ref);
- ref->referred_index = 0;
-
- for (unsigned int i = 1; i < list2->referring.length (); i++)
- list2->referring[i]->referred_index = i;
- }
+ {
+ list2->referring.safe_insert (0, ref);
+ ref->referred_index = 0;
+
+ for (unsigned int i = 1; i < list2->referring.length (); i++)
+ list2->referring[i]->referred_index = i;
+ }
else
- {
- list2->referring.safe_push (ref);
- ref->referred_index = list2->referring.length () - 1;
- }
+ {
+ list2->referring.safe_push (ref);
+ ref->referred_index = list2->referring.length () - 1;
+ }
ref->referring = this;
ref->referred = referred_node;
@@ -743,52 +731,6 @@ symtab_node::dump_referring (FILE *file)
fprintf (file, "\n");
}
-/* Return true if list contains an alias. */
-bool
-symtab_node::has_aliases_p (void)
-{
- ipa_ref *ref = NULL;
- int i;
-
- for (i = 0; iterate_referring (i, ref); i++)
- if (ref->use == IPA_REF_ALIAS)
- return true;
- return false;
-}
-
-/* Iterates I-th reference in the list, REF is also set. */
-
-ipa_ref *
-symtab_node::iterate_reference (unsigned i, ipa_ref *&ref)
-{
- vec_safe_iterate (ref_list.references, i, &ref);
-
- return ref;
-}
-
-/* Iterates I-th referring item in the list, REF is also set. */
-
-ipa_ref *
-symtab_node::iterate_referring (unsigned i, ipa_ref *&ref)
-{
- ref_list.referring.iterate (i, &ref);
-
- return ref;
-}
-
-/* Iterates I-th referring alias item in the list, REF is also set. */
-
-ipa_ref *
-symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
-{
- ref_list.referring.iterate (i, &ref);
-
- if (ref && ref->use != IPA_REF_ALIAS)
- return NULL;
-
- return ref;
-}
-
static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
/* Dump base fields of symtab nodes to F. Not to be used directly. */
@@ -1196,29 +1138,6 @@ symtab_node::verify_symtab_nodes (void)
}
}
-/* Return true when NODE is known to be used from other (non-LTO)
- object file. Known only when doing LTO via linker plugin. */
-
-bool
-symtab_node::used_from_object_file_p_worker (symtab_node *node)
-{
- if (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl))
- return false;
- if (resolution_used_from_other_file_p (node->resolution))
- return true;
- return false;
-}
-
-
-/* Return true when symtab_node is known to be used from other (non-LTO)
- object file. Known only when doing LTO via linker plugin. */
-
-bool
-symtab_node::used_from_object_file_p (void)
-{
- return symtab_node::used_from_object_file_p_worker (this);
-}
-
/* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
but other code such as notice_global_symbol generates rtl. */
@@ -1260,20 +1179,13 @@ symtab_node::make_decl_local (void)
/* Walk the alias chain to return the symbol NODE is alias of.
If NODE is not an alias, return NODE.
- When AVAILABILITY is non-NULL, get minimal availability in the chain. */
+ Assumes NODE is known to be alias. */
symtab_node *
-symtab_node::ultimate_alias_target (enum availability *availability)
+symtab_node::ultimate_alias_target_1 (enum availability *availability)
{
bool weakref_p = false;
- if (!alias)
- {
- if (availability)
- *availability = get_availability ();
- return this;
- }
-
/* To determine visibility of the target, we follow ELF semantic of aliases.
Here alias is an alternative assembler name of a given definition. Its
availability prevails the availability of its target (i.e. static alias of
@@ -1453,16 +1365,6 @@ symtab_node::get_init_priority ()
return h ? h->init : DEFAULT_INIT_PRIORITY;
}
-/* Return availability of NODE. */
-enum availability symtab_node::get_availability (void)
-{
- if (is_a <cgraph_node *> (this))
- return dyn_cast <cgraph_node *> (this)->get_availability ();
- else
- return dyn_cast <varpool_node *> (this)->get_availability ();;
-}
-
-
/* Return the finalization priority. */
priority_type
@@ -1608,33 +1510,6 @@ symtab_node::resolve_alias (symtab_node
return true;
}
-/* Call calback on symtab node and aliases associated to this node.
- When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
- skipped. */
-
-bool
-symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
- void *),
- void *data, bool include_overwritable)
-{
- int i;
- ipa_ref *ref;
-
- if (callback (this, data))
- return true;
- for (i = 0; iterate_referring (i, ref); i++)
- if (ref->use == IPA_REF_ALIAS)
- {
- symtab_node *alias = ref->referring;
- if (include_overwritable
- || alias->get_availability () > AVAIL_INTERPOSABLE)
- if (alias->call_for_symbol_and_aliases (callback, data,
- include_overwritable))
- return true;
- }
- return false;
-}
-
/* Worker searching noninterposable alias. */
bool
@@ -1961,3 +1836,24 @@ symtab_node::equal_address_to (symtab_no
return 2;
}
+
+/* Worker for call_for_symbol_and_aliases. */
+
+bool
+symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *,
+ void *),
+ void *data,
+ bool include_overwritable)
+{
+ ipa_ref *ref;
+ FOR_EACH_ALIAS (this, ref)
+ {
+ symtab_node *alias = ref->referring;
+ if (include_overwritable
+ || alias->get_availability () > AVAIL_INTERPOSABLE)
+ if (alias->call_for_symbol_and_aliases (callback, data,
+ include_overwritable))
+ return true;
+ }
+ return false;
+}
Index: ipa.c
===================================================================
--- ipa.c (revision 220630)
+++ ipa.c (working copy)
@@ -808,8 +808,8 @@ ipa_discover_readonly_nonaddressable_var
{
if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
fprintf (dump_file, " %s (non-addressable)", vnode->name ());
- vnode->call_for_node_and_aliases (clear_addressable_bit, NULL,
- true);
+ vnode->call_for_symbol_and_aliases (clear_addressable_bit, NULL,
+ true);
}
if (!address_taken && !written
/* Making variable in explicit section readonly can cause section
@@ -819,14 +819,14 @@ ipa_discover_readonly_nonaddressable_var
{
if (!TREE_READONLY (vnode->decl) && dump_file)
fprintf (dump_file, " %s (read-only)", vnode->name ());
- vnode->call_for_node_and_aliases (set_readonly_bit, NULL, true);
+ vnode->call_for_symbol_and_aliases (set_readonly_bit, NULL, true);
}
if (!vnode->writeonly && !read && !address_taken && written)
{
if (dump_file)
fprintf (dump_file, " %s (write-only)", vnode->name ());
- vnode->call_for_node_and_aliases (set_writeonly_bit, &remove_p,
- true);
+ vnode->call_for_symbol_and_aliases (set_writeonly_bit, &remove_p,
+ true);
}
}
if (dump_file)
@@ -1343,9 +1343,8 @@ ipa_single_use (void)
single_user_map.put (var, user);
/* Enqueue all aliases for re-processing. */
- for (i = 0; var->iterate_referring (i, ref); i++)
- if (ref->use == IPA_REF_ALIAS
- && !ref->referring->aux)
+ for (i = 0; var->iterate_direct_aliases (i, ref); i++)
+ if (!ref->referring->aux)
{
ref->referring->aux = first;
first = dyn_cast <varpool_node *> (ref->referring);
Index: cgraph.c
===================================================================
--- cgraph.c (revision 220608)
+++ cgraph.c (working copy)
@@ -2215,33 +2215,6 @@ cgraph_node::call_for_symbol_thunks_and_
return false;
}
-/* Call callback on function and aliases associated to the function.
- When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
- skipped. */
-
-bool
-cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
- void *),
- void *data,
- bool include_overwritable)
-{
- ipa_ref *ref;
-
- if (callback (this, data))
- return true;
-
- FOR_EACH_ALIAS (this, ref)
- {
- cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
- if (include_overwritable
- || alias->get_availability () > AVAIL_INTERPOSABLE)
- if (alias->call_for_symbol_and_aliases (callback, data,
- include_overwritable))
- return true;
- }
- return false;
-}
-
/* Worker to bring NODE local. */
bool
@@ -2430,37 +2403,6 @@ cgraph_edge::maybe_hot_p (void)
return true;
}
-/* Return true when function can be removed from callgraph
- if all direct calls are eliminated. */
-
-bool
-cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
-{
- gcc_assert (!global.inlined_to);
- /* Instrumentation clones should not be removed before
- instrumentation happens. New callers may appear after
- instrumentation. */
- if (instrumentation_clone
- && !chkp_function_instrumented_p (decl))
- return false;
- /* Extern inlines can always go, we will use the external definition. */
- if (DECL_EXTERNAL (decl))
- return true;
- /* When function is needed, we can not remove it. */
- if (force_output || used_from_other_partition)
- return false;
- if (DECL_STATIC_CONSTRUCTOR (decl)
- || DECL_STATIC_DESTRUCTOR (decl))
- return false;
- /* Only COMDAT functions can be removed if externally visible. */
- if (externally_visible
- && (!DECL_COMDAT (decl)
- || forced_by_abi
- || used_from_object_file_p ()))
- return false;
- return true;
-}
-
/* Worker for cgraph_can_remove_if_no_direct_calls_p. */
static bool
@@ -3363,4 +3305,24 @@ cgraph_c_finalize (void)
version_info_node = NULL;
}
+/* A wroker for call_for_symbol_and_aliases. */
+
+bool
+cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
+ void *),
+ void *data,
+ bool include_overwritable)
+{
+ ipa_ref *ref;
+ FOR_EACH_ALIAS (this, ref)
+ {
+ cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
+ if (include_overwritable
+ || alias->get_availability () > AVAIL_INTERPOSABLE)
+ if (alias->call_for_symbol_and_aliases (callback, data,
+ include_overwritable))
+ return true;
+ }
+ return false;
+}
#include "gt-cgraph.h"
Index: cgraph.h
===================================================================
--- cgraph.h (revision 220608)
+++ cgraph.h (working copy)
@@ -377,10 +377,6 @@ public:
/* Verify symbol table for internal consistency. */
static DEBUG_FUNCTION void verify_symtab_nodes (void);
- /* Return true when NODE is known to be used from other (non-LTO)
- object file. Known only when doing LTO via linker plugin. */
- static bool used_from_object_file_p_worker (symtab_node *node);
-
/* Type of the symbol. */
ENUM_BITFIELD (symtab_type) type : 8;
@@ -523,6 +519,10 @@ protected:
allocated structure is returned. */
struct symbol_priority_map *priority_info (void);
+ /* Worker for call_for_symbol_and_aliases_1. */
+ bool call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *, void *),
+ void *data,
+ bool include_overwrite);
private:
/* Worker for set_section. */
static bool set_section (symtab_node *n, void *s);
@@ -532,6 +532,9 @@ private:
/* Worker searching noninterposable alias. */
static bool noninterposable_alias (symtab_node *node, void *data);
+
+ /* Worker for ultimate_alias_target. */
+ symtab_node *ultimate_alias_target_1 (enum availability *avail = NULL);
};
/* Walk all aliases for NODE. */
@@ -1291,6 +1294,12 @@ public:
unsigned nonfreeing_fn : 1;
/* True if there was multiple COMDAT bodies merged by lto-symtab. */
unsigned merged : 1;
+
+private:
+ /* Worker for call_for_symbol_and_aliases. */
+ bool call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
+ void *),
+ void *data, bool include_overwritable);
};
/* A cgraph node set is a collection of cgraph nodes. A cgraph node
@@ -1670,9 +1679,9 @@ public:
/* Call calback on varpool symbol and aliases associated to varpool symbol.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */
- bool call_for_node_and_aliases (bool (*callback) (varpool_node *, void *),
- void *data,
- bool include_overwritable);
+ bool call_for_symbol_and_aliases (bool (*callback) (varpool_node *, void *),
+ void *data,
+ bool include_overwritable);
/* Return true when variable should be considered externally visible. */
bool externally_visible_p (void);
@@ -1747,6 +1756,11 @@ public:
private:
/* Assemble thunks and aliases associated to varpool node. */
void assemble_aliases (void);
+
+ /* Worker for call_for_node_and_aliases. */
+ bool call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *, void *),
+ void *data,
+ bool include_overwritable);
};
/* Every top level asm statement is put into a asm_node. */
@@ -2181,7 +2195,6 @@ bool cgraph_function_possibly_inlined_p
const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t);
-bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution);
extern bool gimple_check_call_matching_types (gimple, tree, bool);
/* In cgraphunit.c */
@@ -2209,6 +2222,9 @@ bool ipa_discover_readonly_nonaddressabl
/* In varpool.c */
tree ctor_for_folding (tree);
+/* In tree-chkp.c */
+extern bool chkp_function_instrumented_p (tree fndecl);
+
/* Return true when the symbol is real symbol, i.e. it is not inline clone
or abstract function kept for debug info purposes only. */
inline bool
@@ -2270,6 +2286,7 @@ symtab_node::get_alias_target (void)
}
/* Return next reachable static symbol with initializer after the node. */
+
inline symtab_node *
symtab_node::next_defined_symbol (void)
{
@@ -2282,6 +2299,78 @@ symtab_node::next_defined_symbol (void)
return NULL;
}
+/* Iterates I-th reference in the list, REF is also set. */
+
+inline ipa_ref *
+symtab_node::iterate_reference (unsigned i, ipa_ref *&ref)
+{
+ vec_safe_iterate (ref_list.references, i, &ref);
+
+ return ref;
+}
+
+/* Iterates I-th referring item in the list, REF is also set. */
+
+inline ipa_ref *
+symtab_node::iterate_referring (unsigned i, ipa_ref *&ref)
+{
+ ref_list.referring.iterate (i, &ref);
+
+ return ref;
+}
+
+/* Iterates I-th referring alias item in the list, REF is also set. */
+
+inline ipa_ref *
+symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
+{
+ ref_list.referring.iterate (i, &ref);
+
+ if (ref && ref->use != IPA_REF_ALIAS)
+ return NULL;
+
+ return ref;
+}
+
+/* Return true if list contains an alias. */
+
+inline bool
+symtab_node::has_aliases_p (void)
+{
+ ipa_ref *ref = NULL;
+ int i;
+
+ for (i = 0; iterate_direct_aliases (i, ref); i++)
+ if (ref->use == IPA_REF_ALIAS)
+ return true;
+ return false;
+}
+
+/* Return true when RESOLUTION indicate that linker will use
+ the symbol from non-LTO object files. */
+
+inline bool
+resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
+{
+ return (resolution == LDPR_PREVAILING_DEF
+ || resolution == LDPR_PREEMPTED_REG
+ || resolution == LDPR_RESOLVED_EXEC
+ || resolution == LDPR_RESOLVED_DYN);
+}
+
+/* Return true when symtab_node is known to be used from other (non-LTO)
+ object file. Known only when doing LTO via linker plugin. */
+
+inline bool
+symtab_node::used_from_object_file_p (void)
+{
+ if (!TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
+ return false;
+ if (resolution_used_from_other_file_p (resolution))
+ return true;
+ return false;
+}
+
/* Return varpool node for given symbol and check it is a function. */
inline varpool_node *
@@ -2644,6 +2733,37 @@ cgraph_node::only_called_directly_or_ali
&& !externally_visible);
}
+/* Return true when function can be removed from callgraph
+ if all direct calls are eliminated. */
+
+inline bool
+cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
+{
+ gcc_checking_assert (!global.inlined_to);
+ /* Instrumentation clones should not be removed before
+ instrumentation happens. New callers may appear after
+ instrumentation. */
+ if (instrumentation_clone
+ && !chkp_function_instrumented_p (decl))
+ return false;
+ /* Extern inlines can always go, we will use the external definition. */
+ if (DECL_EXTERNAL (decl))
+ return true;
+ /* When function is needed, we can not remove it. */
+ if (force_output || used_from_other_partition)
+ return false;
+ if (DECL_STATIC_CONSTRUCTOR (decl)
+ || DECL_STATIC_DESTRUCTOR (decl))
+ return false;
+ /* Only COMDAT functions can be removed if externally visible. */
+ if (externally_visible
+ && (!DECL_COMDAT (decl)
+ || forced_by_abi
+ || used_from_object_file_p ()))
+ return false;
+ return true;
+}
+
/* Return true when variable can be removed from variable pool
if all direct calls are eliminated. */
@@ -2699,6 +2819,23 @@ varpool_node::get_alias_target (void)
return dyn_cast <varpool_node *> (symtab_node::get_alias_target ());
}
+/* Walk the alias chain to return the symbol NODE is alias of.
+ If NODE is not an alias, return NODE.
+ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
+
+inline symtab_node *
+symtab_node::ultimate_alias_target (enum availability *availability)
+{
+ if (!alias)
+ {
+ if (availability)
+ *availability = get_availability ();
+ return this;
+ }
+
+ return ultimate_alias_target_1 (availability);
+}
+
/* Given function symbol, walk the alias chain to return the function node
is alias of. Do not walk through thunks.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
@@ -2706,8 +2843,8 @@ varpool_node::get_alias_target (void)
inline cgraph_node *
cgraph_node::ultimate_alias_target (enum availability *availability)
{
- cgraph_node *n = dyn_cast <cgraph_node *> (symtab_node::ultimate_alias_target
- (availability));
+ cgraph_node *n = dyn_cast <cgraph_node *>
+ (symtab_node::ultimate_alias_target (availability));
if (!n && availability)
*availability = AVAIL_NOT_AVAILABLE;
return n;
@@ -2756,6 +2893,7 @@ cgraph_edge::redirect_callee (cgraph_nod
}
/* Return true when the edge represents a direct recursion. */
+
inline bool
cgraph_edge::recursive_p (void)
{
@@ -2813,7 +2951,11 @@ cgraph_node::optimize_for_size_p (void)
return false;
}
-inline symtab_node * symtab_node::get_create (tree node)
+/* Return symtab_node for NODE or create one if it is not present
+ in symtab. */
+
+inline symtab_node *
+symtab_node::get_create (tree node)
{
if (TREE_CODE (node) == VAR_DECL)
return varpool_node::get_create (node);
@@ -2821,6 +2963,76 @@ inline symtab_node * symtab_node::get_cr
return cgraph_node::get_create (node);
}
+/* Return availability of NODE. */
+
+inline enum availability
+symtab_node::get_availability (void)
+{
+ if (is_a <cgraph_node *> (this))
+ return dyn_cast <cgraph_node *> (this)->get_availability ();
+ else
+ return dyn_cast <varpool_node *> (this)->get_availability ();;
+}
+
+/* Call calback on symtab node and aliases associated to this node.
+ When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+ skipped. */
+
+inline bool
+symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
+ void *),
+ void *data,
+ bool include_overwritable)
+{
+ ipa_ref *ref;
+
+ if (callback (this, data))
+ return true;
+ if (iterate_direct_aliases (0, ref))
+ return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
+ return false;
+}
+
+/* Call callback on function and aliases associated to the function.
+ When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+ skipped. */
+
+inline bool
+cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
+ void *),
+ void *data,
+ bool include_overwritable)
+{
+ ipa_ref *ref;
+
+ if (callback (this, data))
+ return true;
+ if (iterate_direct_aliases (0, ref))
+ return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
+
+ return false;
+}
+
+/* Call calback on varpool symbol and aliases associated to varpool symbol.
+ When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+ skipped. */
+
+inline bool
+varpool_node::call_for_symbol_and_aliases (bool (*callback) (varpool_node *,
+ void *),
+ void *data,
+ bool include_overwritable)
+{
+ ipa_ref *ref;
+
+ if (callback (this, data))
+ return true;
+ if (iterate_direct_aliases (0, ref))
+ return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
+
+ return false;
+}
+
/* Build polymorphic call context for indirect call E. */
inline
Index: varpool.c
===================================================================
--- varpool.c (revision 220606)
+++ varpool.c (working copy)
@@ -817,28 +817,23 @@ varpool_node::create_extra_name_alias (t
return alias_node;
}
-/* Call calback on varpool symbol and aliases associated to varpool symbol.
- When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
- skipped. */
+/* Worker for call_for_symbol_and_aliases. */
bool
-varpool_node::call_for_node_and_aliases (bool (*callback) (varpool_node *,
- void *),
- void *data,
- bool include_overwritable)
+varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
+ void *),
+ void *data,
+ bool include_overwritable)
{
ipa_ref *ref;
- if (callback (this, data))
- return true;
-
FOR_EACH_ALIAS (this, ref)
{
varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
if (include_overwritable
|| alias->get_availability () > AVAIL_INTERPOSABLE)
- if (alias->call_for_node_and_aliases (callback, data,
- include_overwritable))
+ if (alias->call_for_symbol_and_aliases (callback, data,
+ include_overwritable))
return true;
}
return false;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Chromium: LTO
2015-02-14 18:44 ` Chromium: LTO Jan Hubicka
@ 2015-02-15 19:23 ` Trevor Saunders
2015-02-15 22:33 ` Jan Hubicka
0 siblings, 1 reply; 3+ messages in thread
From: Trevor Saunders @ 2015-02-15 19:23 UTC (permalink / raw)
To: Jan Hubicka; +Cc: Martin Liška, gcc-patches
Hi,
> +symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
> +{
> + ref_list.referring.iterate (i, &ref);
> +
> + if (ref && ref->use != IPA_REF_ALIAS)
> + return NULL;
> +
> + return ref;
> +}
it seems a little weird the out arg can return a non alias, and so if
you only want to look at aliases you have to check the return value.
> +
> +/* Return true if list contains an alias. */
> +
> +inline bool
> +symtab_node::has_aliases_p (void)
> +{
> + ipa_ref *ref = NULL;
> + int i;
> +
> + for (i = 0; iterate_direct_aliases (i, ref); i++)
> + if (ref->use == IPA_REF_ALIAS)
> + return true;
> + return false;
> +}
can it ever be true there is an alias in the list but it isn't the first
thing? the function above suggests not.
> +symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
> + void *),
> + void *data,
> + bool include_overwritable)
> +{
> + ipa_ref *ref;
> +
> + if (callback (this, data))
> + return true;
> + if (iterate_direct_aliases (0, ref))
wouldn't has_aliases_p be a little more clear?
Trev
On Sat, Feb 14, 2015 at 07:44:40PM +0100, Jan Hubicka wrote:
> Hi,
> Maritn has notced that we spend a lot of time in simple cgraph/varpool predicates. The patch bellow
> reorganizes inlines so the fast paths get fast.
> > perf report:
> >
> > 18.79% lto1-wpa lto1 [.] do_estimate_growth_1(cgraph_node*, void*)
> > 12.48% lto1-wpa lto1 [.] cgraph_node::can_remove_if_no_direct_calls_and_refs_p()
> > 5.86% lto1-wpa lto1 [.] symtab_node::used_from_object_file_p_worker(symtab_node*)
> > 5.69% lto1-wpa lto1 [.] cgraph_node::call_for_symbol_and_aliases(bool (*)(cgraph_node*, void*), void*, bool)
> > 5.01% lto1-wpa-stream lto1 [.] streamer_tree_cache_lookup(streamer_tree_cache_d*, tree_node*, unsigned int*)
> > 4.84% lto1-wpa lto1 [.] cgraph_node::call_for_symbol_thunks_and_aliases(bool (*)(cgraph_node*, void*), void*, bool, bool)
> > 2.44% lto1-wpa lto1 [.] inflate_fast
> > 2.10% lto1-wpa-stream lto1 [.] DFS::DFS_write_tree(output_block*, DFS::sccs*, tree_node*, bool, bool, bool)
> > 2.03% lto1-wpa-stream lto1 [.] linemap_lookup(line_maps*, unsigned int)
> > 1.30% lto1-wpa-stream [kernel.kallsyms] [k] isolate_migratepages_range
> > 1.27% lto1-wpa lto1 [.] symtab_node::iterate_direct_aliases(unsigned int, ipa_ref*&)
> > 1.21% lto1-wpa-stream lto1 [.] DFS::DFS_write_tree_body(output_block*, tree_node*, DFS::sccs*, bool, bool)
> > 1.19% lto1-wpa-stream lto1 [.] streamer_write_uhwi_stream(lto_output_stream*, unsigned long)
> > 0.85% lto1-wpa lto1 [.] compare_tree_sccs_1(tree_node*, tree_node*, tree_node***)
> > 0.83% lto1-wpa lto1 [.] streamer_read_uhwi(lto_input_block*)
> > 0.74% lto1-wpa-stream lto1 [.] streamer_tree_cache_insert_1(streamer_tree_cache_d*, tree_node*, unsigned int, unsigned int*, bool)
> > 0.72% lto1-wpa lto1 [.] ht_lookup_with_hash(ht*, unsigned char const*, unsigned long, unsigned int, ht_lookup_option)
> > 0.70% lto1-wpa-stream [kernel.kallsyms] [k] compaction_alloc
> > 0.68% lto1-wpa lto1 [.] unify_scc(streamer_tree_cache_d*, unsigned int, unsigned int, unsigned int, unsigned int)
> > 0.66% lto1-wpa-stream lto1 [.] lto_output_tree(output_block*, tree_node*, bool, bool)
> > 0.66% lto1-wpa-stream libc-2.19.so [.] _int_malloc
> > 0.66% lto1-wpa-stream lto1 [.] hash_table<hash_map<tree_node*, unsigned int, default_hashmap_traits>::hash_entry, xcallocator, true>::expand()
> > 0.62% lto1-wpa-stream lto1 [.] streamer_write_tree_bitfields(output_block*, tree_node*)
> > 0.61% lto1-wpa lto1 [.] streamer_read_tree_bitfields(lto_input_block*, data_in*, tree_node*)
> > 0.53% lto1-wpa lto1 [.] lto_cgraph_replace_node(cgraph_node*, cgraph_node*)
> > 0.49% lto1-wpa [kernel.kallsyms] [k] copy_pte_range
>
> Bootstrapped/regtested x86_64-linux, comitted.
>
> Honza
>
> * ipa-chkp.c: Use iterate_direct_aliases.
> * symtab.c (resolution_used_from_other_file_p): Move inline.
> (symtab_node::create_reference): Fix formating.
> (symtab_node::has_aliases_p): Move inline; use iterate_direct_aliases.
> (symtab_node::iterate_reference): Move inline.
> (symtab_node::iterate_referring): Move inline.
> (symtab_node::iterate_direct_aliases): Move inline.
> (symtab_node::used_from_object_file_p_worker): Inline into ...
> (symtab_node::used_from_object_file_p): ... this one; move inline.
> (symtab_node::call_for_symbol_and_aliases): Move inline;
> use iterate_direct_aliases.
> (symtab_node::call_for_symbol_and_aliases_1): New method.
> (cgraph_node::call_for_symbol_and_aliases): Move inline;
> use iterate_direct_aliases.
> (cgraph_node::call_for_symbol_and_aliases_1): New method.
> (varpool_node::call_for_node_and_aliases): Rename to ...
> (varpool_node::call_for_symbol_and_aliases): ... this one; Move inline;
> use iterate_direct_aliases.
> (varpool_node::call_for_symbol_and_aliases_1): New method.
> * ipa.c (ipa_single_use): Use iterate_direct_aliases.
> (ipa_discover_readonly_nonaddressable_var): Update.
> * ipa-devirt.c: Fix formating.
> * cgraph.c (cgraph_node::can_remove_if_no_direct_calls_and_refs_p):
> Move inline.
> (cgraph_node::call_for_symbol_and_aliases): Move inline.
> (cgraph_node::call_for_symbol_and_aliases_1): New function..
> * cgraph.h (used_from_object_file_p_worker): Remove.
> (resolution_used_from_other_file_p): Move inline.
> (symtab_node::has_aliases_p): Move inline; use iterate_direct_aliases.
> (symtab_node::iterate_reference): Move inline.
> (symtab_node::iterate_referring): Move inline.
> (symtab_node::iterate_direct_aliases): Move inline.
> (symtab_node::used_from_object_file_p_worker): Inline into ...
> (symtab_node::used_from_object_file_p): Move inline.
> * tree-emutls.c (ipa_lower_emutls): Update.
> * varpool.c (varpool_node::call_for_symbol_and_aliases_1): New method.
> (varpool_node::call_for_node_and_aliases): Remove.
> Index: tree-emutls.c
> ===================================================================
> --- tree-emutls.c (revision 220606)
> +++ tree-emutls.c (working copy)
> @@ -787,7 +787,7 @@ ipa_lower_emutls (void)
> if (var->alias && !var->analyzed)
> any_aliases = true;
> else if (!var->alias)
> - var->call_for_node_and_aliases (create_emultls_var, &ctor_body, true);
> + var->call_for_symbol_and_aliases (create_emultls_var, &ctor_body, true);
> }
>
> /* If there were any aliases, then frob the alias_pairs vector. */
> Index: ipa-devirt.c
> ===================================================================
> --- ipa-devirt.c (revision 220606)
> +++ ipa-devirt.c (working copy)
> @@ -1710,7 +1710,6 @@ referenced_from_vtable_p (struct cgraph_
> return true;
>
> for (i = 0; node->iterate_referring (i, ref); i++)
> -
> if ((ref->use == IPA_REF_ALIAS
> && referenced_from_vtable_p (dyn_cast<cgraph_node *> (ref->referring)))
> || (ref->use == IPA_REF_ADDR
> Index: ipa-chkp.c
> ===================================================================
> --- ipa-chkp.c (revision 220606)
> +++ ipa-chkp.c (working copy)
> @@ -534,14 +534,13 @@ chkp_maybe_create_clone (tree fndecl)
> symtab->call_cgraph_insertion_hooks (clone);
>
> /* Clone all aliases. */
> - for (i = 0; node->iterate_referring (i, ref); i++)
> - if (ref->use == IPA_REF_ALIAS)
> - {
> - struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
> - struct cgraph_node *chkp_alias
> - = chkp_maybe_create_clone (alias->decl);
> - chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
> - }
> + for (i = 0; node->iterate_direct_aliases (i, ref); i++)
> + {
> + struct cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
> + struct cgraph_node *chkp_alias
> + = chkp_maybe_create_clone (alias->decl);
> + chkp_alias->create_reference (clone, IPA_REF_ALIAS, NULL);
> + }
>
> /* Clone all thunks. */
> for (e = node->callers; e; e = e->next_caller)
> Index: symtab.c
> ===================================================================
> --- symtab.c (revision 220630)
> +++ symtab.c (working copy)
> @@ -313,18 +313,6 @@ symbol_table::change_decl_assembler_name
> }
> }
>
> -/* Return true when RESOLUTION indicate that linker will use
> - the symbol from non-LTO object files. */
> -
> -bool
> -resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
> -{
> - return (resolution == LDPR_PREVAILING_DEF
> - || resolution == LDPR_PREEMPTED_REG
> - || resolution == LDPR_RESOLVED_EXEC
> - || resolution == LDPR_RESOLVED_DYN);
> -}
> -
> /* Hash sections by their names. */
>
> hashval_t
> @@ -527,18 +515,18 @@ symtab_node::create_reference (symtab_no
>
> /* IPA_REF_ALIAS is always inserted at the beginning of the list. */
> if(use_type == IPA_REF_ALIAS)
> - {
> - list2->referring.safe_insert (0, ref);
> - ref->referred_index = 0;
> -
> - for (unsigned int i = 1; i < list2->referring.length (); i++)
> - list2->referring[i]->referred_index = i;
> - }
> + {
> + list2->referring.safe_insert (0, ref);
> + ref->referred_index = 0;
> +
> + for (unsigned int i = 1; i < list2->referring.length (); i++)
> + list2->referring[i]->referred_index = i;
> + }
> else
> - {
> - list2->referring.safe_push (ref);
> - ref->referred_index = list2->referring.length () - 1;
> - }
> + {
> + list2->referring.safe_push (ref);
> + ref->referred_index = list2->referring.length () - 1;
> + }
>
> ref->referring = this;
> ref->referred = referred_node;
> @@ -743,52 +731,6 @@ symtab_node::dump_referring (FILE *file)
> fprintf (file, "\n");
> }
>
> -/* Return true if list contains an alias. */
> -bool
> -symtab_node::has_aliases_p (void)
> -{
> - ipa_ref *ref = NULL;
> - int i;
> -
> - for (i = 0; iterate_referring (i, ref); i++)
> - if (ref->use == IPA_REF_ALIAS)
> - return true;
> - return false;
> -}
> -
> -/* Iterates I-th reference in the list, REF is also set. */
> -
> -ipa_ref *
> -symtab_node::iterate_reference (unsigned i, ipa_ref *&ref)
> -{
> - vec_safe_iterate (ref_list.references, i, &ref);
> -
> - return ref;
> -}
> -
> -/* Iterates I-th referring item in the list, REF is also set. */
> -
> -ipa_ref *
> -symtab_node::iterate_referring (unsigned i, ipa_ref *&ref)
> -{
> - ref_list.referring.iterate (i, &ref);
> -
> - return ref;
> -}
> -
> -/* Iterates I-th referring alias item in the list, REF is also set. */
> -
> -ipa_ref *
> -symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
> -{
> - ref_list.referring.iterate (i, &ref);
> -
> - if (ref && ref->use != IPA_REF_ALIAS)
> - return NULL;
> -
> - return ref;
> -}
> -
> static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
>
> /* Dump base fields of symtab nodes to F. Not to be used directly. */
> @@ -1196,29 +1138,6 @@ symtab_node::verify_symtab_nodes (void)
> }
> }
>
> -/* Return true when NODE is known to be used from other (non-LTO)
> - object file. Known only when doing LTO via linker plugin. */
> -
> -bool
> -symtab_node::used_from_object_file_p_worker (symtab_node *node)
> -{
> - if (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl))
> - return false;
> - if (resolution_used_from_other_file_p (node->resolution))
> - return true;
> - return false;
> -}
> -
> -
> -/* Return true when symtab_node is known to be used from other (non-LTO)
> - object file. Known only when doing LTO via linker plugin. */
> -
> -bool
> -symtab_node::used_from_object_file_p (void)
> -{
> - return symtab_node::used_from_object_file_p_worker (this);
> -}
> -
> /* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
> but other code such as notice_global_symbol generates rtl. */
>
> @@ -1260,20 +1179,13 @@ symtab_node::make_decl_local (void)
>
> /* Walk the alias chain to return the symbol NODE is alias of.
> If NODE is not an alias, return NODE.
> - When AVAILABILITY is non-NULL, get minimal availability in the chain. */
> + Assumes NODE is known to be alias. */
>
> symtab_node *
> -symtab_node::ultimate_alias_target (enum availability *availability)
> +symtab_node::ultimate_alias_target_1 (enum availability *availability)
> {
> bool weakref_p = false;
>
> - if (!alias)
> - {
> - if (availability)
> - *availability = get_availability ();
> - return this;
> - }
> -
> /* To determine visibility of the target, we follow ELF semantic of aliases.
> Here alias is an alternative assembler name of a given definition. Its
> availability prevails the availability of its target (i.e. static alias of
> @@ -1453,16 +1365,6 @@ symtab_node::get_init_priority ()
> return h ? h->init : DEFAULT_INIT_PRIORITY;
> }
>
> -/* Return availability of NODE. */
> -enum availability symtab_node::get_availability (void)
> -{
> - if (is_a <cgraph_node *> (this))
> - return dyn_cast <cgraph_node *> (this)->get_availability ();
> - else
> - return dyn_cast <varpool_node *> (this)->get_availability ();;
> -}
> -
> -
> /* Return the finalization priority. */
>
> priority_type
> @@ -1608,33 +1510,6 @@ symtab_node::resolve_alias (symtab_node
> return true;
> }
>
> -/* Call calback on symtab node and aliases associated to this node.
> - When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
> - skipped. */
> -
> -bool
> -symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
> - void *),
> - void *data, bool include_overwritable)
> -{
> - int i;
> - ipa_ref *ref;
> -
> - if (callback (this, data))
> - return true;
> - for (i = 0; iterate_referring (i, ref); i++)
> - if (ref->use == IPA_REF_ALIAS)
> - {
> - symtab_node *alias = ref->referring;
> - if (include_overwritable
> - || alias->get_availability () > AVAIL_INTERPOSABLE)
> - if (alias->call_for_symbol_and_aliases (callback, data,
> - include_overwritable))
> - return true;
> - }
> - return false;
> -}
> -
> /* Worker searching noninterposable alias. */
>
> bool
> @@ -1961,3 +1836,24 @@ symtab_node::equal_address_to (symtab_no
>
> return 2;
> }
> +
> +/* Worker for call_for_symbol_and_aliases. */
> +
> +bool
> +symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *,
> + void *),
> + void *data,
> + bool include_overwritable)
> +{
> + ipa_ref *ref;
> + FOR_EACH_ALIAS (this, ref)
> + {
> + symtab_node *alias = ref->referring;
> + if (include_overwritable
> + || alias->get_availability () > AVAIL_INTERPOSABLE)
> + if (alias->call_for_symbol_and_aliases (callback, data,
> + include_overwritable))
> + return true;
> + }
> + return false;
> +}
> Index: ipa.c
> ===================================================================
> --- ipa.c (revision 220630)
> +++ ipa.c (working copy)
> @@ -808,8 +808,8 @@ ipa_discover_readonly_nonaddressable_var
> {
> if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
> fprintf (dump_file, " %s (non-addressable)", vnode->name ());
> - vnode->call_for_node_and_aliases (clear_addressable_bit, NULL,
> - true);
> + vnode->call_for_symbol_and_aliases (clear_addressable_bit, NULL,
> + true);
> }
> if (!address_taken && !written
> /* Making variable in explicit section readonly can cause section
> @@ -819,14 +819,14 @@ ipa_discover_readonly_nonaddressable_var
> {
> if (!TREE_READONLY (vnode->decl) && dump_file)
> fprintf (dump_file, " %s (read-only)", vnode->name ());
> - vnode->call_for_node_and_aliases (set_readonly_bit, NULL, true);
> + vnode->call_for_symbol_and_aliases (set_readonly_bit, NULL, true);
> }
> if (!vnode->writeonly && !read && !address_taken && written)
> {
> if (dump_file)
> fprintf (dump_file, " %s (write-only)", vnode->name ());
> - vnode->call_for_node_and_aliases (set_writeonly_bit, &remove_p,
> - true);
> + vnode->call_for_symbol_and_aliases (set_writeonly_bit, &remove_p,
> + true);
> }
> }
> if (dump_file)
> @@ -1343,9 +1343,8 @@ ipa_single_use (void)
> single_user_map.put (var, user);
>
> /* Enqueue all aliases for re-processing. */
> - for (i = 0; var->iterate_referring (i, ref); i++)
> - if (ref->use == IPA_REF_ALIAS
> - && !ref->referring->aux)
> + for (i = 0; var->iterate_direct_aliases (i, ref); i++)
> + if (!ref->referring->aux)
> {
> ref->referring->aux = first;
> first = dyn_cast <varpool_node *> (ref->referring);
> Index: cgraph.c
> ===================================================================
> --- cgraph.c (revision 220608)
> +++ cgraph.c (working copy)
> @@ -2215,33 +2215,6 @@ cgraph_node::call_for_symbol_thunks_and_
> return false;
> }
>
> -/* Call callback on function and aliases associated to the function.
> - When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
> - skipped. */
> -
> -bool
> -cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
> - void *),
> - void *data,
> - bool include_overwritable)
> -{
> - ipa_ref *ref;
> -
> - if (callback (this, data))
> - return true;
> -
> - FOR_EACH_ALIAS (this, ref)
> - {
> - cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
> - if (include_overwritable
> - || alias->get_availability () > AVAIL_INTERPOSABLE)
> - if (alias->call_for_symbol_and_aliases (callback, data,
> - include_overwritable))
> - return true;
> - }
> - return false;
> -}
> -
> /* Worker to bring NODE local. */
>
> bool
> @@ -2430,37 +2403,6 @@ cgraph_edge::maybe_hot_p (void)
> return true;
> }
>
> -/* Return true when function can be removed from callgraph
> - if all direct calls are eliminated. */
> -
> -bool
> -cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
> -{
> - gcc_assert (!global.inlined_to);
> - /* Instrumentation clones should not be removed before
> - instrumentation happens. New callers may appear after
> - instrumentation. */
> - if (instrumentation_clone
> - && !chkp_function_instrumented_p (decl))
> - return false;
> - /* Extern inlines can always go, we will use the external definition. */
> - if (DECL_EXTERNAL (decl))
> - return true;
> - /* When function is needed, we can not remove it. */
> - if (force_output || used_from_other_partition)
> - return false;
> - if (DECL_STATIC_CONSTRUCTOR (decl)
> - || DECL_STATIC_DESTRUCTOR (decl))
> - return false;
> - /* Only COMDAT functions can be removed if externally visible. */
> - if (externally_visible
> - && (!DECL_COMDAT (decl)
> - || forced_by_abi
> - || used_from_object_file_p ()))
> - return false;
> - return true;
> -}
> -
> /* Worker for cgraph_can_remove_if_no_direct_calls_p. */
>
> static bool
> @@ -3363,4 +3305,24 @@ cgraph_c_finalize (void)
> version_info_node = NULL;
> }
>
> +/* A wroker for call_for_symbol_and_aliases. */
> +
> +bool
> +cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
> + void *),
> + void *data,
> + bool include_overwritable)
> +{
> + ipa_ref *ref;
> + FOR_EACH_ALIAS (this, ref)
> + {
> + cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
> + if (include_overwritable
> + || alias->get_availability () > AVAIL_INTERPOSABLE)
> + if (alias->call_for_symbol_and_aliases (callback, data,
> + include_overwritable))
> + return true;
> + }
> + return false;
> +}
> #include "gt-cgraph.h"
> Index: cgraph.h
> ===================================================================
> --- cgraph.h (revision 220608)
> +++ cgraph.h (working copy)
> @@ -377,10 +377,6 @@ public:
> /* Verify symbol table for internal consistency. */
> static DEBUG_FUNCTION void verify_symtab_nodes (void);
>
> - /* Return true when NODE is known to be used from other (non-LTO)
> - object file. Known only when doing LTO via linker plugin. */
> - static bool used_from_object_file_p_worker (symtab_node *node);
> -
> /* Type of the symbol. */
> ENUM_BITFIELD (symtab_type) type : 8;
>
> @@ -523,6 +519,10 @@ protected:
> allocated structure is returned. */
> struct symbol_priority_map *priority_info (void);
>
> + /* Worker for call_for_symbol_and_aliases_1. */
> + bool call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *, void *),
> + void *data,
> + bool include_overwrite);
> private:
> /* Worker for set_section. */
> static bool set_section (symtab_node *n, void *s);
> @@ -532,6 +532,9 @@ private:
>
> /* Worker searching noninterposable alias. */
> static bool noninterposable_alias (symtab_node *node, void *data);
> +
> + /* Worker for ultimate_alias_target. */
> + symtab_node *ultimate_alias_target_1 (enum availability *avail = NULL);
> };
>
> /* Walk all aliases for NODE. */
> @@ -1291,6 +1294,12 @@ public:
> unsigned nonfreeing_fn : 1;
> /* True if there was multiple COMDAT bodies merged by lto-symtab. */
> unsigned merged : 1;
> +
> +private:
> + /* Worker for call_for_symbol_and_aliases. */
> + bool call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
> + void *),
> + void *data, bool include_overwritable);
> };
>
> /* A cgraph node set is a collection of cgraph nodes. A cgraph node
> @@ -1670,9 +1679,9 @@ public:
> /* Call calback on varpool symbol and aliases associated to varpool symbol.
> When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
> skipped. */
> - bool call_for_node_and_aliases (bool (*callback) (varpool_node *, void *),
> - void *data,
> - bool include_overwritable);
> + bool call_for_symbol_and_aliases (bool (*callback) (varpool_node *, void *),
> + void *data,
> + bool include_overwritable);
>
> /* Return true when variable should be considered externally visible. */
> bool externally_visible_p (void);
> @@ -1747,6 +1756,11 @@ public:
> private:
> /* Assemble thunks and aliases associated to varpool node. */
> void assemble_aliases (void);
> +
> + /* Worker for call_for_node_and_aliases. */
> + bool call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *, void *),
> + void *data,
> + bool include_overwritable);
> };
>
> /* Every top level asm statement is put into a asm_node. */
> @@ -2181,7 +2195,6 @@ bool cgraph_function_possibly_inlined_p
> const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
> cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t);
>
> -bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution);
> extern bool gimple_check_call_matching_types (gimple, tree, bool);
>
> /* In cgraphunit.c */
> @@ -2209,6 +2222,9 @@ bool ipa_discover_readonly_nonaddressabl
> /* In varpool.c */
> tree ctor_for_folding (tree);
>
> +/* In tree-chkp.c */
> +extern bool chkp_function_instrumented_p (tree fndecl);
> +
> /* Return true when the symbol is real symbol, i.e. it is not inline clone
> or abstract function kept for debug info purposes only. */
> inline bool
> @@ -2270,6 +2286,7 @@ symtab_node::get_alias_target (void)
> }
>
> /* Return next reachable static symbol with initializer after the node. */
> +
> inline symtab_node *
> symtab_node::next_defined_symbol (void)
> {
> @@ -2282,6 +2299,78 @@ symtab_node::next_defined_symbol (void)
> return NULL;
> }
>
> +/* Iterates I-th reference in the list, REF is also set. */
> +
> +inline ipa_ref *
> +symtab_node::iterate_reference (unsigned i, ipa_ref *&ref)
> +{
> + vec_safe_iterate (ref_list.references, i, &ref);
> +
> + return ref;
> +}
> +
> +/* Iterates I-th referring item in the list, REF is also set. */
> +
> +inline ipa_ref *
> +symtab_node::iterate_referring (unsigned i, ipa_ref *&ref)
> +{
> + ref_list.referring.iterate (i, &ref);
> +
> + return ref;
> +}
> +
> +/* Iterates I-th referring alias item in the list, REF is also set. */
> +
> +inline ipa_ref *
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Chromium: LTO
2015-02-15 19:23 ` Trevor Saunders
@ 2015-02-15 22:33 ` Jan Hubicka
0 siblings, 0 replies; 3+ messages in thread
From: Jan Hubicka @ 2015-02-15 22:33 UTC (permalink / raw)
To: Trevor Saunders; +Cc: Jan Hubicka, Martin Liška, gcc-patches
> Hi,
>
> > +symtab_node::iterate_direct_aliases (unsigned i, ipa_ref *&ref)
> > +{
> > + ref_list.referring.iterate (i, &ref);
> > +
> > + if (ref && ref->use != IPA_REF_ALIAS)
> > + return NULL;
> > +
> > + return ref;
> > +}
>
> it seems a little weird the out arg can return a non alias, and so if
> you only want to look at aliases you have to check the return value.
>
> > +
> > +/* Return true if list contains an alias. */
> > +
> > +inline bool
> > +symtab_node::has_aliases_p (void)
> > +{
> > + ipa_ref *ref = NULL;
> > + int i;
> > +
> > + for (i = 0; iterate_direct_aliases (i, ref); i++)
> > + if (ref->use == IPA_REF_ALIAS)
> > + return true;
> > + return false;
> > +}
>
> can it ever be true there is an alias in the list but it isn't the first
> thing? the function above suggests not.
Yeah, you are right here; I was not very cureful when simplifying the function.
>
> > +symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
> > + void *),
> > + void *data,
> > + bool include_overwritable)
> > +{
> > + ipa_ref *ref;
> > +
> > + if (callback (this, data))
> > + return true;
> > + if (iterate_direct_aliases (0, ref))
>
> wouldn't has_aliases_p be a little more clear?
Indeed.
I commited the following cleanup that also cleans get_binfo_at_offset per
martin Jambor comments.
* cgraph.h (symtab_node::has_aliases_p): Simplify.
(symtab_node::call_for_symbol_and_aliases): Use has_aliases_p
* tree.c (lookup_binfo_at_offset): Make static.
(get_binfo_at_offset): Do not shadow offset; add explanatory
comment.
Index: cgraph.h
===================================================================
--- cgraph.h (revision 220709)
+++ cgraph.h (working copy)
@@ -2338,12 +2338,8 @@ inline bool
symtab_node::has_aliases_p (void)
{
ipa_ref *ref = NULL;
- int i;
- for (i = 0; iterate_direct_aliases (i, ref); i++)
- if (ref->use == IPA_REF_ALIAS)
- return true;
- return false;
+ return (iterate_direct_aliases (0, ref) != NULL);
}
/* Return true when RESOLUTION indicate that linker will use
@@ -2984,11 +2980,9 @@ symtab_node::call_for_symbol_and_aliases
void *data,
bool include_overwritable)
{
- ipa_ref *ref;
-
if (callback (this, data))
return true;
- if (iterate_direct_aliases (0, ref))
+ if (has_aliases_p ())
return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
return false;
}
@@ -3003,13 +2997,10 @@ cgraph_node::call_for_symbol_and_aliases
void *data,
bool include_overwritable)
{
- ipa_ref *ref;
-
if (callback (this, data))
return true;
- if (iterate_direct_aliases (0, ref))
+ if (has_aliases_p ())
return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
-
return false;
}
@@ -3023,13 +3014,10 @@ varpool_node::call_for_symbol_and_aliase
void *data,
bool include_overwritable)
{
- ipa_ref *ref;
-
if (callback (this, data))
return true;
- if (iterate_direct_aliases (0, ref))
+ if (has_aliases_p ())
return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
-
return false;
}
Index: tree.c
===================================================================
--- tree.c (revision 220709)
+++ tree.c (working copy)
@@ -11992,7 +11992,7 @@ type_in_anonymous_namespace_p (const_tre
/* Lookup sub-BINFO of BINFO of TYPE at offset POS. */
-tree
+static tree
lookup_binfo_at_offset (tree binfo, tree type, HOST_WIDE_INT pos)
{
unsigned int i;
@@ -12045,11 +12045,13 @@ get_binfo_at_offset (tree binfo, HOST_WI
else if (offset != 0)
{
tree found_binfo = NULL, base_binfo;
- int offset = (tree_to_shwi (BINFO_OFFSET (binfo)) + pos
- / BITS_PER_UNIT);
+ /* Offsets in BINFO are in bytes relative to the whole structure
+ while POS is in bits relative to the containing field. */
+ int binfo_offset = (tree_to_shwi (BINFO_OFFSET (binfo)) + pos
+ / BITS_PER_UNIT);
for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
- if (tree_to_shwi (BINFO_OFFSET (base_binfo)) == offset
+ if (tree_to_shwi (BINFO_OFFSET (base_binfo)) == binfo_offset
&& types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
{
found_binfo = base_binfo;
@@ -12058,7 +12060,8 @@ get_binfo_at_offset (tree binfo, HOST_WI
if (found_binfo)
binfo = found_binfo;
else
- binfo = lookup_binfo_at_offset (binfo, TREE_TYPE (fld), offset);
+ binfo = lookup_binfo_at_offset (binfo, TREE_TYPE (fld),
+ binfo_offset);
}
type = TREE_TYPE (fld);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-02-15 22:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <54DE7CE2.8040202@suse.cz>
2015-02-14 18:44 ` Chromium: LTO Jan Hubicka
2015-02-15 19:23 ` Trevor Saunders
2015-02-15 22:33 ` Jan Hubicka
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).