diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-18 17:28:40 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-18 17:28:40 +0000 |
commit | 86844d6c095dfa67c72e0dd4db3446aa85c5e663 (patch) | |
tree | ebbd388fee9c2b29fa34e1972bac913405e30d33 /gcc/ipa-pure-const.c | |
parent | 9abaa85a3de5dd957de49a911fdcaab1122d2d7f (diff) | |
download | gcc-86844d6c095dfa67c72e0dd4db3446aa85c5e663.tar.gz |
PR middle-end/37448
* ipa-reference.c (ipa_reference_local_vars_info_d,
ipa_reference_global_vars_info_d,
ipa_reference_local_vars_info_t, ipa_reference_global_vars_info_t,
ipa_reference_vars_info_t): Move here from ipa-reference.h
(node_duplication_hook_holder, node_removal_hook_holder): New.
(get_reference_vars_info_from_cgraph): Rename to ...
(get_reference_vars_info): ... this one, use cgraph uids.
(get_local_reference_vars_info, get_global_reference_vars_info):
Use cgraph instead of decl.
(ipa_reference_get_read_local, ipa_reference_get_written_local): Remove.
(ipa_reference_get_read_global, ipa_reference_get_not_read_global
ipa_reference_get_written_global, ipa_reference_get_not_written_global): Use
cgraph argument.
(check_call): Simplify avail check.
(scan_stmt_for_static_refs): Update.
(propagate_bits): Update.
(merge_callee_local_info): Remove.
(init_function_info): Use cgraph nodes.
(clean_function_local_data): Break out from ...
(clean_function): ... here.
(copy_local_bitmap, copy_global_bitmap): New functions.
(duplicate_node_data, remove_node_data): New functions.
(generate_summary): Register hooks; use visibility instead of
master clones.
(propafate): Use cgraph nodes; copy bitmap to each node in cycle.
* ipa-reference.h (ipa_reference_local_vars_info_d,
ipa_reference_global_vars_info_d,
ipa_reference_local_vars_info_t, ipa_reference_global_vars_info_t,
ipa_reference_vars_info_t): Move to ipa-reference.c
(ipa_reference_get_read_local, ipa_reference_get_written_local):
Remove.
(ipa_reference_get_read_global, ipa_reference_get_written_global,
ipa_reference_get_not_read_global, ipa_reference_get_not_written_global):
Update prototype.
* ipa-pure-const.c (funct_state_vec): Turn into VECtor.
(init_state): Remove.
(node_duplication_hook_holder, node_removal_hook_holder): New.
(get_function_state, set_function_state): Use VECtor.
(analyze_function): Check body availability.
(add_new_function): Likewise.
(duplicate_node_data, remove_node_data): New.
(generate_summary): Register hooks; do not care about clones.
(propafate): Do not care about clones; recursive functions are not looping.
* ipa-utils.c (searchc, ipa_utils_reduced_inorder): Do not skip clones.
* ipa-prop.c (edge_removal_hook_holder, node_removal_hook_holder,
* edge_duplication_hook_holder, node_duplication_hook_holder): Make
static.
* tree-flow.h (function_ann_d): Remove reference_vars_info.
* tree-ssa-opreands.c (add_call_clobber_ops, add_call_read_ops): Update call of
ipa-reference accesors.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140463 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-pure-const.c')
-rw-r--r-- | gcc/ipa-pure-const.c | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 20abdf3f477..f21638f383e 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -94,19 +94,14 @@ typedef struct funct_state_d * funct_state; /* Array, indexed by cgraph node uid, of function states. */ -static funct_state *funct_state_vec; +DEF_VEC_P (funct_state); +DEF_VEC_ALLOC_P (funct_state, heap); +static VEC (funct_state, heap) *funct_state_vec; /* Holders of ipa cgraph hooks: */ static struct cgraph_node_hook_list *function_insertion_hook_holder; - -/* Init the function state. */ - -static void -init_state (void) -{ - funct_state_vec = XCNEWVEC (funct_state, cgraph_max_uid); -} - +static struct cgraph_2node_hook_list *node_duplication_hook_holder; +static struct cgraph_node_hook_list *node_removal_hook_holder; /* Init the function state. */ @@ -122,7 +117,10 @@ finish_state (void) static inline funct_state get_function_state (struct cgraph_node *node) { - return funct_state_vec[node->uid]; + if (!funct_state_vec + || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid) + return NULL; + return VEC_index (funct_state, funct_state_vec, node->uid); } /* Set the function state S for NODE. */ @@ -130,7 +128,10 @@ get_function_state (struct cgraph_node *node) static inline void set_function_state (struct cgraph_node *node, funct_state s) { - funct_state_vec[node->uid] = s; + if (!funct_state_vec + || VEC_length (funct_state, funct_state_vec) <= (unsigned int)node->uid) + VEC_safe_grow_cleared (funct_state, heap, funct_state_vec, node->uid + 1); + VEC_replace (funct_state, funct_state_vec, node->uid, s); } /* Check to see if the use (or definition when CHECKING_WRITE is true) @@ -585,6 +586,9 @@ analyze_function (struct cgraph_node *fn) tree decl = fn->decl; funct_state l = XCNEW (struct funct_state_d); + if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE) + return; + set_function_state (fn, l); l->pure_const_state = IPA_CONST; @@ -683,7 +687,8 @@ end: static void add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) { - funct_state_vec = XRESIZEVEC (funct_state, funct_state_vec, cgraph_max_uid); + if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) + return; /* There are some shared nodes, in particular the initializers on static declarations. We do not need to scan them more than once since all we would be interested in are the addressof @@ -694,6 +699,33 @@ add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) visited_nodes = NULL; } +/* Called when new clone is inserted to callgraph late. */ + +static void +duplicate_node_data (struct cgraph_node *src, struct cgraph_node *dst, + void *data ATTRIBUTE_UNUSED) +{ + if (get_function_state (src)) + { + funct_state l = XNEW (struct funct_state_d); + gcc_assert (!get_function_state (dst)); + memcpy (l, get_function_state (src), sizeof (*l)); + set_function_state (dst, l); + } +} + +/* Called when new clone is inserted to callgraph late. */ + +static void +remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +{ + if (get_function_state (node)) + { + free (get_function_state (node)); + set_function_state (node, NULL); + } +} + /* Analyze each function in the cgraph to see if it is locally PURE or CONST. */ @@ -703,9 +735,12 @@ generate_summary (void) { struct cgraph_node *node; + node_removal_hook_holder = + cgraph_add_node_removal_hook (&remove_node_data, NULL); + node_duplication_hook_holder = + cgraph_add_node_duplication_hook (&duplicate_node_data, NULL); function_insertion_hook_holder = cgraph_add_function_insertion_hook (&add_new_function, NULL); - init_state (); /* There are some shared nodes, in particular the initializers on static declarations. We do not need to scan them more than once since all we would be interested in are the addressof @@ -714,14 +749,12 @@ generate_summary (void) /* Process all of the functions. - We do not want to process any of the clones so we check that this - is a master clone. However, we do NOT process any - AVAIL_OVERWRITABLE functions (these are never clones) we cannot + We do NOT process any AVAIL_OVERWRITABLE functions, we cannot guarantee that what we learn about the one we see will be true for the one that overrides it. */ for (node = cgraph_nodes; node; node = node->next) - if (node->analyzed && cgraph_is_master_clone (node)) + if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE) analyze_function (node); pointer_set_destroy (visited_nodes); @@ -745,6 +778,8 @@ propagate (void) struct ipa_dfs_info * w_info; cgraph_remove_function_insertion_hook (function_insertion_hook_holder); + cgraph_remove_node_duplication_hook (node_duplication_hook_holder); + cgraph_remove_node_removal_hook (node_removal_hook_holder); order_pos = ipa_utils_reduced_inorder (order, true, false); if (dump_file) { @@ -788,12 +823,8 @@ propagate (void) for (e = w->callees; e; e = e->next_callee) { struct cgraph_node *y = e->callee; - /* Only look at the master nodes and skip external nodes. */ - y = cgraph_master_clone (y); - if (w == y) - looping = true; - if (y) + if (cgraph_function_body_availability (y) > AVAIL_OVERWRITABLE) { funct_state y_l = get_function_state (y); if (pure_const_state < y_l->pure_const_state) @@ -861,11 +892,12 @@ propagate (void) free (node->aux); node->aux = NULL; } - if (node->analyzed && cgraph_is_master_clone (node)) + if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE) free (get_function_state (node)); } free (order); + VEC_free (funct_state, heap, funct_state_vec); finish_state (); return 0; } @@ -873,7 +905,7 @@ propagate (void) static bool gate_pure_const (void) { - return (flag_ipa_pure_const + return (flag_ipa_pure_const /* Don't bother doing anything if the program has errors. */ && !(errorcount || sorrycount)); } |