From ff302741f10c7d6f014eb46f7632b57bdc43a4f5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 15 Jul 2015 15:58:43 +0000 Subject: [PATCH] Limit AA walking when inlining analysis examines parameters 2015-07-15 Paolo Bonzini Martin Jambor * ipa-inline-analysis.c (unmodified_parm_or_parm_agg_item): Accept struct func_body_info* instead of struct ipa_node_params*, expecting fbi->info to be filled in. Replace throughout. Adjust call to ipa_load_from_parm_agg. (set_cond_stmt_execution_predicate): Accept struct func_body_info* instead of struct ipa_node_params*. Adjust calls to other functions so that they pass either fbi or fbi->info. (set_switch_stmt_execution_predicate): Likewise. (will_be_nonconstant_predicate): Likewise. (compute_bb_predicates): Likewise. (estimate_function_body_sizes): Move asserts earlier. Fill in struct func_body_info, replace parms_info with fbi.info. Adjust calls to functions that now accept struct func_body_info. * ipa-prop.c (param_aa_status, struct ipa_bb_info): Move to ipa-prop.h. (struct func_body_info): Likewise. (ipa_load_from_parm_agg_1): Rename to ipa_load_from_parm_agg, remove static. Adjust callers. (ipa_load_from_parm_agg): Remove. * ipa-prop.h (param_aa_status, ipa_bb_info): Move from ipa-prop.c. (func_body_info): Likewise. (ipa_load_from_parm_agg): Adjust prototype. Co-Authored-By: Martin Jambor From-SVN: r225838 --- gcc/ChangeLog | 25 ++++++++++++ gcc/ipa-inline-analysis.c | 72 ++++++++++++++++++--------------- gcc/ipa-prop.c | 85 +++++---------------------------------- gcc/ipa-prop.h | 56 +++++++++++++++++++++++++- 4 files changed, 129 insertions(+), 109 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b6ee390d3bb..a2ce483c774 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2015-07-15 Paolo Bonzini + Martin Jambor + + * ipa-inline-analysis.c (unmodified_parm_or_parm_agg_item): Accept + struct func_body_info* instead of struct ipa_node_params*, expecting + fbi->info to be filled in. Replace throughout. Adjust call to + ipa_load_from_parm_agg. + (set_cond_stmt_execution_predicate): Accept struct func_body_info* + instead of struct ipa_node_params*. Adjust calls to other functions + so that they pass either fbi or fbi->info. + (set_switch_stmt_execution_predicate): Likewise. + (will_be_nonconstant_predicate): Likewise. + (compute_bb_predicates): Likewise. + (estimate_function_body_sizes): Move asserts earlier. Fill in + struct func_body_info, replace parms_info with fbi.info. Adjust + calls to functions that now accept struct func_body_info. + * ipa-prop.c (param_aa_status, struct ipa_bb_info): Move to ipa-prop.h. + (struct func_body_info): Likewise. + (ipa_load_from_parm_agg_1): Rename to ipa_load_from_parm_agg, + remove static. Adjust callers. + (ipa_load_from_parm_agg): Remove. + * ipa-prop.h (param_aa_status, ipa_bb_info): Move from ipa-prop.c. + (func_body_info): Likewise. + (ipa_load_from_parm_agg): Adjust prototype. + 2015-07-12 Trevor Saunders * gensupport.c (rtx_handle_directive): Adjust. diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index d5dbfbd6887..81a6860f114 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -1574,7 +1574,7 @@ unmodified_parm (gimple stmt, tree op) loaded. */ static bool -unmodified_parm_or_parm_agg_item (struct ipa_node_params *info, +unmodified_parm_or_parm_agg_item (struct func_body_info *fbi, gimple stmt, tree op, int *index_p, struct agg_position_info *aggpos) { @@ -1583,7 +1583,7 @@ unmodified_parm_or_parm_agg_item (struct ipa_node_params *info, gcc_checking_assert (aggpos); if (res) { - *index_p = ipa_get_param_decl_index (info, res); + *index_p = ipa_get_param_decl_index (fbi->info, res); if (*index_p < 0) return false; aggpos->agg_contents = false; @@ -1599,13 +1599,14 @@ unmodified_parm_or_parm_agg_item (struct ipa_node_params *info, stmt = SSA_NAME_DEF_STMT (op); op = gimple_assign_rhs1 (stmt); if (!REFERENCE_CLASS_P (op)) - return unmodified_parm_or_parm_agg_item (info, stmt, op, index_p, + return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, aggpos); } aggpos->agg_contents = true; - return ipa_load_from_parm_agg (info, stmt, op, index_p, &aggpos->offset, - &aggpos->by_ref); + return ipa_load_from_parm_agg (fbi, fbi->info->descriptors, + stmt, op, index_p, &aggpos->offset, + NULL, &aggpos->by_ref); } /* See if statement might disappear after inlining. @@ -1744,7 +1745,7 @@ eliminated_by_inlining_prob (gimple stmt) predicates to the CFG edges. */ static void -set_cond_stmt_execution_predicate (struct ipa_node_params *info, +set_cond_stmt_execution_predicate (struct func_body_info *fbi, struct inline_summary *summary, basic_block bb) { @@ -1767,7 +1768,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info, /* TODO: handle conditionals like var = op0 < 4; if (var != 0). */ - if (unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos)) + if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos)) { code = gimple_cond_code (last); inverted_code = invert_tree_comparison (code, HONOR_NANS (op)); @@ -1810,8 +1811,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info, || gimple_call_num_args (set_stmt) != 1) return; op2 = gimple_call_arg (set_stmt, 0); - if (!unmodified_parm_or_parm_agg_item - (info, set_stmt, op2, &index, &aggpos)) + if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &aggpos)) return; FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE) { @@ -1827,7 +1827,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info, predicates to the CFG edges. */ static void -set_switch_stmt_execution_predicate (struct ipa_node_params *info, +set_switch_stmt_execution_predicate (struct func_body_info *fbi, struct inline_summary *summary, basic_block bb) { @@ -1845,7 +1845,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info, return; gswitch *last = as_a (lastg); op = gimple_switch_index (last); - if (!unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos)) + if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos)) return; FOR_EACH_EDGE (e, ei, bb->succs) @@ -1888,8 +1888,8 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info, which it is executable. */ static void -compute_bb_predicates (struct cgraph_node *node, - struct ipa_node_params *parms_info, +compute_bb_predicates (struct func_body_info *fbi, + struct cgraph_node *node, struct inline_summary *summary) { struct function *my_function = DECL_STRUCT_FUNCTION (node->decl); @@ -1898,8 +1898,8 @@ compute_bb_predicates (struct cgraph_node *node, FOR_EACH_BB_FN (bb, my_function) { - set_cond_stmt_execution_predicate (parms_info, summary, bb); - set_switch_stmt_execution_predicate (parms_info, summary, bb); + set_cond_stmt_execution_predicate (fbi, summary, bb); + set_switch_stmt_execution_predicate (fbi, summary, bb); } /* Entry block is always executable. */ @@ -2031,7 +2031,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info, a compile time constant. */ static struct predicate -will_be_nonconstant_predicate (struct ipa_node_params *info, +will_be_nonconstant_predicate (struct func_body_info *fbi, struct inline_summary *summary, gimple stmt, vec nonconstant_names) @@ -2065,7 +2065,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, tree op; gcc_assert (gimple_assign_single_p (stmt)); op = gimple_assign_rhs1 (stmt); - if (!unmodified_parm_or_parm_agg_item (info, stmt, op, &base_index, + if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, &aggpos)) return p; } @@ -2078,7 +2078,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, { tree parm = unmodified_parm (stmt, use); /* For arguments we can build a condition. */ - if (parm && ipa_get_param_decl_index (info, parm) >= 0) + if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0) continue; if (TREE_CODE (use) != SSA_NAME) return p; @@ -2099,7 +2099,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, tree parm = unmodified_parm (stmt, use); int index; - if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0) + if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0) { if (index != base_index) p = add_condition (summary, index, NULL, CHANGED, NULL_TREE); @@ -2481,13 +2481,17 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) int freq; struct inline_summary *info = inline_summaries->get (node); struct predicate bb_predicate; - struct ipa_node_params *parms_info = NULL; + struct func_body_info fbi; vec nonconstant_names = vNULL; int nblocks, n; int *order; predicate array_index = true_predicate (); gimple fix_builtin_expect_stmt; + gcc_assert (my_function && my_function->cfg); + gcc_assert (cfun == my_function); + + memset(&fbi, 0, sizeof(fbi)); info->conds = NULL; info->entry = NULL; @@ -2510,7 +2514,11 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) if (ipa_node_params_sum) { - parms_info = IPA_NODE_REF (node); + fbi.node = node; + fbi.info = IPA_NODE_REF (node); + fbi.bb_infos = vNULL; + fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun)); + fbi.param_count = count_formal_params(node->decl); nonconstant_names.safe_grow_cleared (SSANAMES (my_function)->length ()); } @@ -2528,10 +2536,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) bb_predicate = not_inlined_predicate (); account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &bb_predicate); - gcc_assert (my_function && my_function->cfg); - if (parms_info) - compute_bb_predicates (node, parms_info, info); - gcc_assert (cfun == my_function); + if (fbi.info) + compute_bb_predicates (&fbi, node, info); order = XNEWVEC (int, n_basic_blocks_for_fn (cfun)); nblocks = pre_and_rev_post_order_compute (NULL, order, false); for (n = 0; n < nblocks; n++) @@ -2548,7 +2554,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) } /* TODO: Obviously predicates can be propagated down across CFG. */ - if (parms_info) + if (fbi.info) { if (bb->aux) bb_predicate = *(struct predicate *) bb->aux; @@ -2564,7 +2570,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) dump_predicate (dump_file, info->conds, &bb_predicate); } - if (parms_info && nonconstant_names.exists ()) + if (fbi.info && nonconstant_names.exists ()) { struct predicate phi_predicate; bool first_phi = true; @@ -2573,7 +2579,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) gsi_next (&bsi)) { if (first_phi - && !phi_result_unknown_predicate (parms_info, info, bb, + && !phi_result_unknown_predicate (fbi.info, info, bb, &phi_predicate, nonconstant_names)) break; @@ -2682,9 +2688,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) /* TODO: When conditional jump or swithc is known to be constant, but we did not translate it into the predicates, we really can account just maximum of the possible paths. */ - if (parms_info) + if (fbi.info) will_be_nonconstant - = will_be_nonconstant_predicate (parms_info, info, + = will_be_nonconstant_predicate (&fbi, info, stmt, nonconstant_names); if (this_time || this_size) { @@ -2699,7 +2705,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "\t\tWill be eliminated by inlining\n"); - if (parms_info) + if (fbi.info) p = and_predicates (info->conds, &bb_predicate, &will_be_nonconstant); else @@ -2767,7 +2773,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) && !is_gimple_min_invariant (niter_desc.niter)) { predicate will_be_nonconstant - = will_be_nonconstant_expr_predicate (parms_info, info, + = will_be_nonconstant_expr_predicate (fbi.info, info, niter_desc.niter, nonconstant_names); if (!true_predicate_p (&will_be_nonconstant)) @@ -2805,7 +2811,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) || is_gimple_min_invariant (iv.step)) continue; will_be_nonconstant - = will_be_nonconstant_expr_predicate (parms_info, info, + = will_be_nonconstant_expr_predicate (fbi.info, info, iv.step, nonconstant_names); if (!true_predicate_p (&will_be_nonconstant)) diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 29178d4046f..615f749f8fd 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -70,57 +70,6 @@ along with GCC; see the file COPYING3. If not see #include "domwalk.h" #include "builtins.h" -/* Intermediate information that we get from alias analysis about a particular - parameter in a particular basic_block. When a parameter or the memory it - references is marked modified, we use that information in all dominatd - blocks without cosulting alias analysis oracle. */ - -struct param_aa_status -{ - /* Set when this structure contains meaningful information. If not, the - structure describing a dominating BB should be used instead. */ - bool valid; - - /* Whether we have seen something which might have modified the data in - question. PARM is for the parameter itself, REF is for data it points to - but using the alias type of individual accesses and PT is the same thing - but for computing aggregate pass-through functions using a very inclusive - ao_ref. */ - bool parm_modified, ref_modified, pt_modified; -}; - -/* Information related to a given BB that used only when looking at function - body. */ - -struct ipa_bb_info -{ - /* Call graph edges going out of this BB. */ - vec cg_edges; - /* Alias analysis statuses of each formal parameter at this bb. */ - vec param_aa_statuses; -}; - -/* Structure with global information that is only used when looking at function - body. */ - -struct func_body_info -{ - /* The node that is being analyzed. */ - cgraph_node *node; - - /* Its info. */ - struct ipa_node_params *info; - - /* Information about individual BBs. */ - vec bb_infos; - - /* Number of parameters. */ - int param_count; - - /* Number of statements already walked by when analyzing this function. */ - unsigned int aa_walked; -}; - /* Function summary where the parameter infos are actually stored. */ ipa_node_params_t *ipa_node_params_sum = NULL; /* Vector of IPA-CP transformation data for each clone. */ @@ -1010,12 +959,12 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index, within the aggregate and whether it is a load from a value passed by reference respectively. */ -static bool -ipa_load_from_parm_agg_1 (struct func_body_info *fbi, - vec descriptors, - gimple stmt, tree op, int *index_p, - HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p, - bool *by_ref_p) +bool +ipa_load_from_parm_agg (struct func_body_info *fbi, + vec descriptors, + gimple stmt, tree op, int *index_p, + HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p, + bool *by_ref_p) { int index; HOST_WIDE_INT size, max_size; @@ -1082,18 +1031,6 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi, return false; } -/* Just like the previous function, just without the param_analysis_info - pointer, for users outside of this file. */ - -bool -ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt, - tree op, int *index_p, HOST_WIDE_INT *offset_p, - bool *by_ref_p) -{ - return ipa_load_from_parm_agg_1 (NULL, info->descriptors, stmt, op, index_p, - offset_p, NULL, by_ref_p); -} - /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result of an assignment statement STMT, try to determine whether we are actually handling any of the following cases and construct an appropriate jump @@ -1977,9 +1914,9 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gcall *call, int index; gimple def = SSA_NAME_DEF_STMT (target); if (gimple_assign_single_p (def) - && ipa_load_from_parm_agg_1 (fbi, info->descriptors, def, - gimple_assign_rhs1 (def), &index, &offset, - NULL, &by_ref)) + && ipa_load_from_parm_agg (fbi, info->descriptors, def, + gimple_assign_rhs1 (def), &index, &offset, + NULL, &by_ref)) { struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call); cs->indirect_info->offset = offset; @@ -5192,8 +5129,8 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb) if (vce) continue; - if (!ipa_load_from_parm_agg_1 (m_fbi, m_descriptors, stmt, rhs, &index, - &offset, &size, &by_ref)) + if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index, + &offset, &size, &by_ref)) continue; for (v = m_aggval; v; v = v->next) if (v->index == index diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index c4958948e86..a6b26b8a4f6 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -336,6 +336,57 @@ struct ipa_node_params unsigned node_calling_single_call : 1; }; +/* Intermediate information that we get from alias analysis about a particular + parameter in a particular basic_block. When a parameter or the memory it + references is marked modified, we use that information in all dominatd + blocks without cosulting alias analysis oracle. */ + +struct param_aa_status +{ + /* Set when this structure contains meaningful information. If not, the + structure describing a dominating BB should be used instead. */ + bool valid; + + /* Whether we have seen something which might have modified the data in + question. PARM is for the parameter itself, REF is for data it points to + but using the alias type of individual accesses and PT is the same thing + but for computing aggregate pass-through functions using a very inclusive + ao_ref. */ + bool parm_modified, ref_modified, pt_modified; +}; + +/* Information related to a given BB that used only when looking at function + body. */ + +struct ipa_bb_info +{ + /* Call graph edges going out of this BB. */ + vec cg_edges; + /* Alias analysis statuses of each formal parameter at this bb. */ + vec param_aa_statuses; +}; + +/* Structure with global information that is only used when looking at function + body. */ + +struct func_body_info +{ + /* The node that is being analyzed. */ + cgraph_node *node; + + /* Its info. */ + struct ipa_node_params *info; + + /* Information about individual BBs. */ + vec bb_infos; + + /* Number of parameters. */ + int param_count; + + /* Number of statements already walked by when analyzing this function. */ + unsigned int aa_walked; +}; + /* ipa_node_params access functions. Please use these to access fields that are or will be shared among various passes. */ @@ -585,8 +636,9 @@ void ipa_analyze_node (struct cgraph_node *); /* Aggregate jump function related functions. */ tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT, bool); -bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *, - HOST_WIDE_INT *, bool *); +bool ipa_load_from_parm_agg (struct func_body_info *, + vec, gimple, tree, int *, + HOST_WIDE_INT *, HOST_WIDE_INT *, bool *); /* Debugging interface. */ void ipa_print_node_params (FILE *, struct cgraph_node *node); -- 2.30.2