This corresponds to: [PATCH 55/89] Use gimple_call for callgraph edges https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01221.html from the original 89-patch kit
That earlier patch was approved by Jeff: > OK once prereqs go in. in https://gcc.gnu.org/ml/gcc-patches/2014-05/msg00867.html gcc/ * cgraph.h (cgraph_edge::call_stmt): Strengthen field from plain gimple to a gimple_call. (cgraph_node::set_call_stmt_including_clones): Likewise for param "new_stmt". (cgraph_node::create_edge): Likewise for param "call_stmt". (cgraph_node::create_indirect_edge): Likewise. (cgraph_node::create_edge_including_clones): Likewise for param "stmt". (cgraph_edge::set_call_stmt): Likewise for param "new_stmt". (cgraph_edge::clone): Likewise for param "call_stmt". (symbol_table::create_edge): Likewise. * cgraph.c (cgraph_edge::set_call_stmt): Require a gimple_call rather than a plain gimple. (symbol_table::create_edge): Likewise. (cgraph_node::create_edge): Likewise. (cgraph_node::create_indirect_edge): Likewise. (cgraph_edge::redirect_call_stmt_to_callee): Strengthen local "new_stmt" from gimple to gimple_call. (cgraph_update_edges_for_call_stmt_node): Add checked casts to gimple_call. * cgraphbuild.c (pass_build_cgraph_edges::execute): Replace is_gimple_call with dyn_cast<gimple_call> and new local "call_stmt". (cgraph_edge::rebuild_edges): Likewise. * cgraphclones.c (cgraph_edge::clone): Require a gimple_call rather than a plain gimple. (cgraph_node::set_call_stmt_including_clones): Likewise. (cgraph_node::create_edge_including_clones): Likewise. * lto-streamer-in.c (fixup_call_stmt_edges_1): Add checked casts to gimple_call. * omp-low.c (simd_clone_adjust): Strengthen local "call" from gimple to gimple_call. * trans-mem.c (ipa_tm_insert_irr_call): Likewise for "g". (ipa_tm_insert_gettmclone_call): Likewise; also strengthen "g2" to gimple_assign. * tree-emutls.c (gen_emutls_addr): Strengthen local "x" from gimple to gimple_call. * tree-inline.c (copy_bb): Replace is_gimple_call with dyn_cast<gimple_call> and new local "call_stmt". * value-prof.c (gimple_ic): Require and return a gimple_call, rather than a plain gimple. * value-prof.h (gimple_ic): Likewise. --- gcc/ChangeLog.gimple-classes | 56 ++++++++++++++++++++++++++++++++++++++++++++ gcc/cgraph.c | 21 +++++++++-------- gcc/cgraph.h | 16 ++++++------- gcc/cgraphbuild.c | 24 +++++++++---------- gcc/cgraphclones.c | 7 +++--- gcc/lto-streamer-in.c | 4 ++-- gcc/omp-low.c | 2 +- gcc/trans-mem.c | 5 ++-- gcc/tree-emutls.c | 2 +- gcc/tree-inline.c | 14 +++++------ gcc/value-prof.c | 8 +++---- gcc/value-prof.h | 3 ++- 12 files changed, 111 insertions(+), 51 deletions(-) diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes index 9654b49..115f7ea 100644 --- a/gcc/ChangeLog.gimple-classes +++ b/gcc/ChangeLog.gimple-classes @@ -1,5 +1,61 @@ 2014-10-24 David Malcolm <dmalc...@redhat.com> + Use gimple_call for callgraph edges + + * cgraph.h (cgraph_edge::call_stmt): Strengthen field from plain + gimple to a gimple_call. + (cgraph_node::set_call_stmt_including_clones): Likewise for param + "new_stmt". + (cgraph_node::create_edge): Likewise for param "call_stmt". + (cgraph_node::create_indirect_edge): Likewise. + (cgraph_node::create_edge_including_clones): Likewise for param + "stmt". + (cgraph_edge::set_call_stmt): Likewise for param "new_stmt". + (cgraph_edge::clone): Likewise for param "call_stmt". + (symbol_table::create_edge): Likewise. + + * cgraph.c (cgraph_edge::set_call_stmt): Require a gimple_call + rather than a plain gimple. + (symbol_table::create_edge): Likewise. + (cgraph_node::create_edge): Likewise. + (cgraph_node::create_indirect_edge): Likewise. + (cgraph_edge::redirect_call_stmt_to_callee): Strengthen local + "new_stmt" from gimple to gimple_call. + (cgraph_update_edges_for_call_stmt_node): Add checked casts to + gimple_call. + + * cgraphbuild.c (pass_build_cgraph_edges::execute): Replace + is_gimple_call with dyn_cast<gimple_call> and new local + "call_stmt". + (cgraph_edge::rebuild_edges): Likewise. + + * cgraphclones.c (cgraph_edge::clone): Require a gimple_call + rather than a plain gimple. + (cgraph_node::set_call_stmt_including_clones): Likewise. + (cgraph_node::create_edge_including_clones): Likewise. + + * lto-streamer-in.c (fixup_call_stmt_edges_1): Add checked casts + to gimple_call. + + * omp-low.c (simd_clone_adjust): Strengthen local "call" from + gimple to gimple_call. + + * trans-mem.c (ipa_tm_insert_irr_call): Likewise for "g". + (ipa_tm_insert_gettmclone_call): Likewise; also strengthen "g2" + to gimple_assign. + + * tree-emutls.c (gen_emutls_addr): Strengthen local "x" from + gimple to gimple_call. + + * tree-inline.c (copy_bb): Replace is_gimple_call with + dyn_cast<gimple_call> and new local "call_stmt". + + * value-prof.c (gimple_ic): Require and return a gimple_call, + rather than a plain gimple. + * value-prof.h (gimple_ic): Likewise. + +2014-10-24 David Malcolm <dmalc...@redhat.com> + Make gimple_call_return_slot_opt_p require a gimple_call. * gimple.h (gimple_call_return_slot_opt_p): Require a gimple_call diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 2694c40..947d432 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -691,7 +691,7 @@ cgraph_node::get_edge (gimple call_stmt) edge, then update all components. */ void -cgraph_edge::set_call_stmt (gimple new_stmt, bool update_speculative) +cgraph_edge::set_call_stmt (gimple_call new_stmt, bool update_speculative) { tree decl; @@ -744,8 +744,8 @@ cgraph_edge::set_call_stmt (gimple new_stmt, bool update_speculative) cgraph_edge * symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, - gimple call_stmt, gcov_type count, int freq, - bool indir_unknown_callee) + gimple_call call_stmt, gcov_type count, int freq, + bool indir_unknown_callee) { cgraph_edge *edge; @@ -825,7 +825,7 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, cgraph_edge * cgraph_node::create_edge (cgraph_node *callee, - gimple call_stmt, gcov_type count, int freq) + gimple_call call_stmt, gcov_type count, int freq) { cgraph_edge *edge = symtab->create_edge (this, callee, call_stmt, count, freq, false); @@ -861,7 +861,7 @@ cgraph_allocate_init_indirect_info (void) PARAM_INDEX. */ cgraph_edge * -cgraph_node::create_indirect_edge (gimple call_stmt, int ecf_flags, +cgraph_node::create_indirect_edge (gimple_call call_stmt, int ecf_flags, gcov_type count, int freq, bool compute_indirect_info) { @@ -1247,7 +1247,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void) if (e->speculative) { cgraph_edge *e2; - gimple new_stmt; + gimple_call new_stmt; ipa_ref *ref; e->speculative_call_info (e, e2, ref); @@ -1375,7 +1375,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void) } else { - new_stmt = as_a <gimple_call> (e->call_stmt); + new_stmt = e->call_stmt; gimple_call_set_fndecl (new_stmt, e->callee->decl); update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt); } @@ -1454,7 +1454,7 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node, if (callee->decl == new_call || callee->former_clone_of == new_call) { - e->set_call_stmt (new_stmt); + e->set_call_stmt (as_a <gimple_call> (new_stmt)); return; } callee = callee->clone_of; @@ -1483,13 +1483,14 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node *node, if (new_call) { ne = node->create_edge (cgraph_node::get_create (new_call), - new_stmt, count, frequency); + as_a <gimple_call> (new_stmt), count, + frequency); gcc_assert (ne->inline_failed); } } /* We only updated the call stmt; update pointer in cgraph edge.. */ else if (old_stmt != new_stmt) - node->get_edge (old_stmt)->set_call_stmt (new_stmt); + node->get_edge (old_stmt)->set_call_stmt (as_a <gimple_call> (new_stmt)); } /* Update or remove the corresponding cgraph edge if a GIMPLE_CALL diff --git a/gcc/cgraph.h b/gcc/cgraph.h index a5777c2..de66165 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -779,7 +779,7 @@ public: When WHOLE_SPECULATIVE_EDGES is true, all three components of speculative edge gets updated. Otherwise we update only direct call. */ - void set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt, + void set_call_stmt_including_clones (gimple old_stmt, gimple_call new_stmt, bool update_speculative = true); /* Walk the alias chain to return the function cgraph_node is alias of. @@ -955,13 +955,13 @@ public: /* Create edge from a given function to CALLEE in the cgraph. */ cgraph_edge *create_edge (cgraph_node *callee, - gimple call_stmt, gcov_type count, + gimple_call call_stmt, gcov_type count, int freq); /* Create an indirect edge with a yet-undetermined callee where the call statement destination is a formal parameter of the caller with index PARAM_INDEX. */ - cgraph_edge *create_indirect_edge (gimple call_stmt, int ecf_flags, + cgraph_edge *create_indirect_edge (gimple_call call_stmt, int ecf_flags, gcov_type count, int freq, bool compute_indirect_info = true); @@ -969,7 +969,7 @@ public: same function body. If clones already have edge for OLD_STMT; only update the edge same way as cgraph_set_call_stmt_including_clones does. */ void create_edge_including_clones (cgraph_node *callee, - gimple old_stmt, gimple stmt, + gimple old_stmt, gimple_call stmt, gcov_type count, int freq, cgraph_inline_failed_t reason); @@ -1427,7 +1427,7 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"), /* Change field call_stmt of edge to NEW_STMT. If UPDATE_SPECULATIVE and E is any component of speculative edge, then update all components. */ - void set_call_stmt (gimple new_stmt, bool update_speculative = true); + void set_call_stmt (gimple_call new_stmt, bool update_speculative = true); /* Redirect callee of the edge to N. The function does not update underlying call expression. */ @@ -1460,7 +1460,7 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"), /* Create clone of edge in the node N represented by CALL_EXPR the callgraph. */ - cgraph_edge * clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid, + cgraph_edge * clone (cgraph_node *n, gimple_call call_stmt, unsigned stmt_uid, gcov_type count_scale, int freq_scale, bool update_original); /* Return true when call of edge can not lead to return from caller @@ -1490,7 +1490,7 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"), cgraph_edge *next_caller; cgraph_edge *prev_callee; cgraph_edge *next_callee; - gimple call_stmt; + gimple_call call_stmt; /* Additional information about an indirect call. Not cleared when an edge becomes direct. */ cgraph_indirect_call_info *indirect_info; @@ -2018,7 +2018,7 @@ private: parameters of which only CALLEE can be NULL (when creating an indirect call edge). */ cgraph_edge *create_edge (cgraph_node *caller, cgraph_node *callee, - gimple call_stmt, gcov_type count, int freq, + gimple_call call_stmt, gcov_type count, int freq, bool indir_unknown_callee); /* Put the edge onto the free list. */ diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index be3e866..a97e397 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -337,18 +337,18 @@ pass_build_cgraph_edges::execute (function *fun) if (is_gimple_debug (stmt)) continue; - if (is_gimple_call (stmt)) + if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt)) { int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); - decl = gimple_call_fndecl (stmt); + decl = gimple_call_fndecl (call_stmt); if (decl) - node->create_edge (cgraph_node::get_create (decl), stmt, bb->count, freq); - else if (gimple_call_internal_p (stmt)) + node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count, freq); + else if (gimple_call_internal_p (call_stmt)) ; else - node->create_indirect_edge (stmt, - gimple_call_flags (stmt), + node->create_indirect_edge (call_stmt, + gimple_call_flags (call_stmt), bb->count, freq); } node->record_stmt_references (stmt); @@ -433,19 +433,19 @@ cgraph_edge::rebuild_edges (void) gimple stmt = gsi_stmt (gsi); tree decl; - if (is_gimple_call (stmt)) + if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt)) { int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); - decl = gimple_call_fndecl (stmt); + decl = gimple_call_fndecl (call_stmt); if (decl) - node->create_edge (cgraph_node::get_create (decl), stmt, + node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count, freq); - else if (gimple_call_internal_p (stmt)) + else if (gimple_call_internal_p (call_stmt)) ; else - node->create_indirect_edge (stmt, - gimple_call_flags (stmt), + node->create_indirect_edge (call_stmt, + gimple_call_flags (call_stmt), bb->count, freq); } node->record_stmt_references (stmt); diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index c487c13..d5c2697 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -106,7 +106,7 @@ along with GCC; see the file COPYING3. If not see the callgraph. */ cgraph_edge * -cgraph_edge::clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid, +cgraph_edge::clone (cgraph_node *n, gimple_call call_stmt, unsigned stmt_uid, gcov_type count_scale, int freq_scale, bool update_original) { cgraph_edge *new_edge; @@ -688,7 +688,8 @@ cgraph_node::find_replacement (void) call. */ void -cgraph_node::set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt, +cgraph_node::set_call_stmt_including_clones (gimple old_stmt, + gimple_call new_stmt, bool update_speculative) { cgraph_node *node; @@ -743,7 +744,7 @@ cgraph_node::set_call_stmt_including_clones (gimple old_stmt, gimple new_stmt, void cgraph_node::create_edge_including_clones (cgraph_node *callee, - gimple old_stmt, gimple stmt, + gimple old_stmt, gimple_call stmt, gcov_type count, int freq, cgraph_inline_failed_t reason) diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 271b51c..150e7ba 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -788,7 +788,7 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts, { if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid) fatal_error ("Cgraph edge statement index out of range"); - cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1]; + cedge->call_stmt = as_a <gimple_call> (stmts[cedge->lto_stmt_uid - 1]); if (!cedge->call_stmt) fatal_error ("Cgraph edge statement index not found"); } @@ -796,7 +796,7 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts, { if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid) fatal_error ("Cgraph edge statement index out of range"); - cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1]; + cedge->call_stmt = as_a <gimple_call> (stmts[cedge->lto_stmt_uid - 1]); if (!cedge->call_stmt) fatal_error ("Cgraph edge statement index not found"); } diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 327c6e1..7b4e325 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -12136,7 +12136,7 @@ simd_clone_adjust (struct cgraph_node *node) tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED); gimple_seq seq = NULL; bool need_cvt = false; - gimple call + gimple_call call = gimple_build_call (fn, 2, def, size_int (alignment)); g = call; if (!useless_type_conversion_p (TREE_TYPE (orig_arg), diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 86a081a..9e90812 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -4965,7 +4965,7 @@ ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region, basic_block bb) { gimple_stmt_iterator gsi; - gimple g; + gimple_call g; transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE); @@ -4991,7 +4991,8 @@ ipa_tm_insert_gettmclone_call (struct cgraph_node *node, gimple_stmt_iterator *gsi, gimple stmt) { tree gettm_fn, ret, old_fn, callfn; - gimple g, g2; + gimple_call g; + gimple_assign g2; bool safe; old_fn = gimple_call_fn (stmt); diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index c915e33..8d62dba 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -406,7 +406,7 @@ gen_emutls_addr (tree decl, struct lower_emutls_data *d) { varpool_node *cvar; tree cdecl; - gimple x; + gimple_call x; cvar = data->control_var; cdecl = cvar->decl; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index beae377..a95aa09 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1811,7 +1811,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, /* We're duplicating a CALL_EXPR. Find any corresponding callgraph edges and update or duplicate them. */ - if (is_gimple_call (stmt)) + if (gimple_call call_stmt = dyn_cast <gimple_call> (stmt)) { struct cgraph_edge *edge; @@ -1824,7 +1824,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int edge_freq = edge->frequency; int new_freq; struct cgraph_edge *old_edge = edge; - edge = edge->clone (id->dst_node, stmt, + edge = edge->clone (id->dst_node, call_stmt, gimple_uid (stmt), REG_BR_PROB_BASE, CGRAPH_FREQ_BASE, true); @@ -1843,7 +1843,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, gcc_assert (!edge->indirect_unknown_callee); old_edge->speculative_call_info (direct, indirect, ref); - indirect = indirect->clone (id->dst_node, stmt, + indirect = indirect->clone (id->dst_node, call_stmt, gimple_uid (stmt), REG_BR_PROB_BASE, CGRAPH_FREQ_BASE, true); @@ -1882,14 +1882,14 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, case CB_CGE_MOVE_CLONES: id->dst_node->set_call_stmt_including_clones (orig_stmt, - stmt); + call_stmt); edge = id->dst_node->get_edge (stmt); break; case CB_CGE_MOVE: edge = id->dst_node->get_edge (orig_stmt); if (edge) - edge->set_call_stmt (stmt); + edge->set_call_stmt (call_stmt); break; default: @@ -1918,12 +1918,12 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, || !id->dst_node->definition); if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) id->dst_node->create_edge_including_clones - (dest, orig_stmt, stmt, bb->count, + (dest, orig_stmt, call_stmt, bb->count, compute_call_stmt_bb_frequency (id->dst_node->decl, copy_basic_block), CIF_ORIGINALLY_INDIRECT_CALL); else - id->dst_node->create_edge (dest, stmt, + id->dst_node->create_edge (dest, call_stmt, bb->count, compute_call_stmt_bb_frequency (id->dst_node->decl, diff --git a/gcc/value-prof.c b/gcc/value-prof.c index e5ccf48..a2d62e9 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1370,11 +1370,11 @@ check_ic_target (gimple_call call_stmt, struct cgraph_node *target) old call */ -gimple -gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, +gimple_call +gimple_ic (gimple_call icall_stmt, struct cgraph_node *direct_call, int prob, gcov_type count, gcov_type all) { - gimple dcall_stmt; + gimple_call dcall_stmt; gimple_assign load_stmt; gimple_cond cond_stmt; tree tmp0, tmp1, tmp; @@ -1407,7 +1407,7 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, gimple_set_vdef (icall_stmt, NULL_TREE); gimple_set_vuse (icall_stmt, NULL_TREE); update_stmt (icall_stmt); - dcall_stmt = gimple_copy (icall_stmt); + dcall_stmt = as_a <gimple_call> (gimple_copy (icall_stmt)); gimple_call_set_fndecl (dcall_stmt, direct_call->decl); dflags = flags_from_decl_or_type (direct_call->decl); if ((dflags & ECF_NORETURN) != 0) diff --git a/gcc/value-prof.h b/gcc/value-prof.h index 00a89fa..dec879b 100644 --- a/gcc/value-prof.h +++ b/gcc/value-prof.h @@ -90,7 +90,8 @@ void gimple_move_stmt_histograms (struct function *, gimple, gimple); void verify_histograms (void); void free_histograms (void); void stringop_block_profile (gimple, unsigned int *, HOST_WIDE_INT *); -gimple gimple_ic (gimple, struct cgraph_node *, int, gcov_type, gcov_type); +gimple_call gimple_ic (gimple_call, struct cgraph_node *, int, gcov_type, + gcov_type); /* In tree-profile.c. */ -- 1.8.5.3