diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-22 11:40:18 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-22 11:40:18 +0000 |
commit | ef378c275d52d00d8ed044dc81ec9c48be2222e6 (patch) | |
tree | 0ab06e5072b8d0118d4bed1aa031422e8dd59204 /gcc/ipa-pure-const.c | |
parent | 8867b500961593ba73be72ea17bbbd4f8a2d74ef (diff) | |
download | gcc-ef378c275d52d00d8ed044dc81ec9c48be2222e6.tar.gz |
PR tree-optimize/40556
* ipa-reference.c (has_proper_scope_for_analysis): Add fixme about global vars.
(check_call): Handle only indirect calls.
(propagate_bits): Update comment.
(write_node_summary_p): Turn bogus check to assert.
(ipa_reference_write_summary): Stream calls_read_all properly.
(ipa_reference_read_summary): Stream in calls_read_all properly.
(read_write_all_from_decl): New function.
(propagate): Handle OVERWRITABLE nodes and external calls here.
* ipa-pre-const.c (check_call): In IPA mode handle indirect calls
only.
(analyze_function): Do not check visibility here.
(add_new_function): We summary OVERWRITABLE too.
(generate_summary): Stream OVERWRITABLE nodes too.
(propagate): Handle external calls and OVERWRITABLE nodes here.
(local_pure_const): Check visibility here.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153450 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-pure-const.c')
-rw-r--r-- | gcc/ipa-pure-const.c | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index ea1d81ea5e2..e37af05d08e 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -330,12 +330,11 @@ check_call (funct_state local, gimple call, bool ipa) /* When not in IPA mode, we can still handle self recursion. */ if (!ipa && callee_t == current_function_decl) local->looping = true; - /* The callee is either unknown (indirect call) or there is just no - scannable code for it (external call) . We look to see if there - are any bits available for the callee (such as by declaration or - because it is builtin) and process solely on the basis of those - bits. */ - else if (avail <= AVAIL_OVERWRITABLE || !ipa) + /* Either calle is unknown or we are doing local analysis. + Look to see if there are any bits available for the callee (such as by + declaration or because it is builtin) and process solely on the basis of + those bits. */ + else if (!ipa || !callee_t) { if (possibly_throws && flag_non_call_exceptions) { @@ -492,13 +491,6 @@ analyze_function (struct cgraph_node *fn, bool ipa) funct_state l; basic_block this_block; - if (cgraph_function_body_availability (fn) <= AVAIL_OVERWRITABLE) - { - if (dump_file) - fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n"); - return NULL; - } - l = XCNEW (struct funct_state_d); l->pure_const_state = IPA_CONST; l->state_previously_known = IPA_NEITHER; @@ -609,7 +601,7 @@ end: static void add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) { - if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) + 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 @@ -686,12 +678,12 @@ generate_summary (void) /* Process all of the functions. - 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. - */ + We process AVAIL_OVERWRITABLE functions. We can not use the results + by default, but the info can be used at LTO with -fwhole-program or + when function got clonned and the clone is AVAILABLE. */ + for (node = cgraph_nodes; node; node = node->next) - if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE) + if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE) set_function_state (node, analyze_function (node, true)); pointer_set_destroy (visited_nodes); @@ -878,6 +870,12 @@ propagate (void) if (w_l->looping) looping = true; + if (cgraph_function_body_availability (w) == AVAIL_OVERWRITABLE) + { + looping |= w_l->looping_previously_known; + if (pure_const_state < w_l->state_previously_known) + pure_const_state = w_l->state_previously_known; + } if (pure_const_state == IPA_NEITHER) break; @@ -901,6 +899,20 @@ propagate (void) if (y_l->looping) looping = true; } + else + { + int flags = flags_from_decl_or_type (y->decl); + + if (flags & ECF_LOOPING_CONST_OR_PURE) + looping = true; + if (flags & ECF_CONST) + ; + else if ((flags & ECF_PURE) && pure_const_state == IPA_CONST) + pure_const_state = IPA_PURE; + else + pure_const_state = IPA_NEITHER, looping = true; + + } } w_info = (struct ipa_dfs_info *) w->aux; w = w_info->next_cycle; @@ -988,7 +1000,8 @@ propagate (void) struct cgraph_edge *e; funct_state w_l = get_function_state (w); - if (w_l->can_throw) + if (w_l->can_throw + || cgraph_function_body_availability (w) == AVAIL_OVERWRITABLE) can_throw = true; if (can_throw) @@ -1008,6 +1021,8 @@ propagate (void) && e->can_throw_external) can_throw = true; } + else if (e->can_throw_external && !TREE_NOTHROW (y->decl)) + can_throw = true; } w_info = (struct ipa_dfs_info *) w->aux; w = w_info->next_cycle; @@ -1046,7 +1061,7 @@ propagate (void) free (node->aux); node->aux = NULL; } - if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE) + if (cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE) free (get_function_state (node)); } @@ -1109,15 +1124,16 @@ local_pure_const (void) fprintf (dump_file, "Function called in recursive cycle; ignoring\n"); return 0; } - - l = analyze_function (cgraph_node (current_function_decl), false); - if (!l) + if (cgraph_function_body_availability (cgraph_node (current_function_decl)) + <= AVAIL_OVERWRITABLE) { if (dump_file) fprintf (dump_file, "Function has wrong visibility; ignoring\n"); return 0; } + l = analyze_function (cgraph_node (current_function_decl), false); + switch (l->pure_const_state) { case IPA_CONST: |