diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cgraph.h | 1 | ||||
-rw-r--r-- | gcc/cgraphbuild.c | 32 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 14 | ||||
-rw-r--r-- | gcc/ipa-ref.c | 14 | ||||
-rw-r--r-- | gcc/ipa-ref.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/pr57294.c | 18 |
8 files changed, 80 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d9d2dcd11e..38a0d8a5b76 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2013-05-24 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/57294 + * cgraph.h (ipa_record_stmt_references): Declare. + * cgraphbuild.c (ipa_record_stmt_references): New function. + (build_cgraph_edges): Use ipa_record_stmt_references. + (rebuild_cgraph_edges): Likewise. + (cgraph_rebuild_references): Likewise. + * ipa-prop.c (ipa_modify_call_arguments): Discard references + associated with the old statement and build references from the + newly built statements. + * ipa-ref.c (ipa_remove_stmt_references): New function. + * ipa-ref.h (ipa_remove_stmt_references): Declare. + 2013-05-24 Vladimir Makarov <vmakarov@redhat.com> * lra-constraints.c (emit_spill_move): Use smaller mode for diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 9103a2547c4..fcb9261ff62 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -705,6 +705,7 @@ unsigned int rebuild_cgraph_edges (void); void cgraph_rebuild_references (void); int compute_call_stmt_bb_frequency (tree, basic_block bb); void record_references_in_initializer (tree, bool); +void ipa_record_stmt_references (struct cgraph_node *, gimple); /* In ipa.c */ bool symtab_remove_unreachable_nodes (bool, FILE *); diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index a74a4c043e3..fb1515d6037 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -288,6 +288,14 @@ mark_store (gimple stmt, tree t, void *data) return false; } +/* Record all references from NODE that are taken in statement STMT. */ +void +ipa_record_stmt_references (struct cgraph_node *node, gimple stmt) +{ + walk_stmt_load_store_addr_ops (stmt, node, mark_load, mark_store, + mark_address); +} + /* Create cgraph edges for function calls. Also look for functions and variables having addresses taken. */ @@ -323,8 +331,7 @@ build_cgraph_edges (void) gimple_call_flags (stmt), bb->count, freq); } - walk_stmt_load_store_addr_ops (stmt, node, mark_load, - mark_store, mark_address); + ipa_record_stmt_references (node, stmt); if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL && gimple_omp_parallel_child_fn (stmt)) { @@ -348,8 +355,7 @@ build_cgraph_edges (void) } } for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node, - mark_load, mark_store, mark_address); + ipa_record_stmt_references (node, gsi_stmt (gsi)); } /* Look for initializers of constant variables and private statics. */ @@ -437,13 +443,10 @@ rebuild_cgraph_edges (void) gimple_call_flags (stmt), bb->count, freq); } - walk_stmt_load_store_addr_ops (stmt, node, mark_load, - mark_store, mark_address); - + ipa_record_stmt_references (node, stmt); } for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node, - mark_load, mark_store, mark_address); + ipa_record_stmt_references (node, gsi_stmt (gsi)); } record_eh_tables (node, cfun); gcc_assert (!node->global.inlined_to); @@ -468,16 +471,9 @@ cgraph_rebuild_references (void) FOR_EACH_BB (bb) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - - walk_stmt_load_store_addr_ops (stmt, node, mark_load, - mark_store, mark_address); - - } + ipa_record_stmt_references (node, gsi_stmt (gsi)); for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node, - mark_load, mark_store, mark_address); + ipa_record_stmt_references (node, gsi_stmt (gsi)); } record_eh_tables (node, cfun); } diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 7129b302156..7c3987e222e 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -3219,18 +3219,22 @@ void ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, ipa_parm_adjustment_vec adjustments) { + struct cgraph_node *current_node = cgraph_get_node (current_function_decl); vec<tree> vargs; vec<tree, va_gc> **debug_args = NULL; gimple new_stmt; - gimple_stmt_iterator gsi; + gimple_stmt_iterator gsi, prev_gsi; tree callee_decl; int i, len; len = adjustments.length (); vargs.create (len); callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->symbol.decl; + ipa_remove_stmt_references ((symtab_node) current_node, stmt); gsi = gsi_for_stmt (stmt); + prev_gsi = gsi; + gsi_prev (&prev_gsi); for (i = 0; i < len; i++) { struct ipa_parm_adjustment *adj; @@ -3425,6 +3429,14 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, gsi_replace (&gsi, new_stmt, true); if (cs) cgraph_set_call_stmt (cs, new_stmt); + do + { + ipa_record_stmt_references (current_node, gsi_stmt (gsi)); + gsi_prev (&gsi); + } + while ((gsi_end_p (prev_gsi) && !gsi_end_p (gsi)) + || (!gsi_end_p (prev_gsi) && gsi_stmt (gsi) == gsi_stmt (prev_gsi))); + update_ssa (TODO_update_ssa); free_dominance_info (CDI_DOMINATORS); } diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c index d6ac25ffccd..7909805e0ce 100644 --- a/gcc/ipa-ref.c +++ b/gcc/ipa-ref.c @@ -215,3 +215,17 @@ ipa_find_reference (symtab_node referring_node, symtab_node referred_node, return r; return NULL; } + +/* Remove all references from REFERRING_NODE that are associated with statement + STMT. */ + +void +ipa_remove_stmt_references (symtab_node referring_node, gimple stmt) +{ + struct ipa_ref *r = NULL; + int i; + + FOR_EACH_VEC_SAFE_ELT (referring_node->symbol.ref_list.references, i, r) + if (r->stmt == stmt) + ipa_remove_reference (r); +} diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h index 972e9737f9a..79f60056601 100644 --- a/gcc/ipa-ref.h +++ b/gcc/ipa-ref.h @@ -72,3 +72,4 @@ void ipa_clone_referring (symtab_node, struct ipa_ref_list *); bool ipa_ref_cannot_lead_to_return (struct ipa_ref *); bool ipa_ref_has_aliases_p (struct ipa_ref_list *); struct ipa_ref * ipa_find_reference (symtab_node, symtab_node, gimple); +void ipa_remove_stmt_references (symtab_node, gimple); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf8ba0bb92b..af4b16e2f11 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-05-24 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/57294 + * gcc.dg/ipa/pr57294.c: New test. + 2013-05-24 Ian Bolton <ian.bolton@arm.com> * gcc.target/aarch64/scalar_intrinsics.c diff --git a/gcc/testsuite/gcc.dg/ipa/pr57294.c b/gcc/testsuite/gcc.dg/ipa/pr57294.c new file mode 100644 index 00000000000..0871f3f4183 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr57294.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +void baz (void); +int func (); + +static void +bar (int a, int foo (void)) +{ + baz (); + foo (); +} + +void +baz (void) +{ + bar (0, func); +} |