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)
{
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;
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.
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)
{
/* 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));
|| 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)
{
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)
{
return;
gswitch *last = as_a <gswitch *> (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)
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);
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. */
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<predicate_t> nonconstant_names)
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;
}
{
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;
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);
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<predicate_t> 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;
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 ());
}
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++)
}
/* TODO: Obviously predicates can be propagated down across CFG. */
- if (parms_info)
+ if (fbi.info)
{
if (bb->aux)
bb_predicate = *(struct predicate *) bb->aux;
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;
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;
/* 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)
{
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
&& !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))
|| 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))
#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<cgraph_edge *> cg_edges;
- /* Alias analysis statuses of each formal parameter at this bb. */
- vec<param_aa_status> 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<ipa_bb_info> 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. */
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<ipa_param_descriptor> 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<ipa_param_descriptor> 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;
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
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;
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
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<cgraph_edge *> cg_edges;
+ /* Alias analysis statuses of each formal parameter at this bb. */
+ vec<param_aa_status> 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<ipa_bb_info> 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. */
/* 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<ipa_param_descriptor>, gimple, tree, int *,
+ HOST_WIDE_INT *, HOST_WIDE_INT *, bool *);
/* Debugging interface. */
void ipa_print_node_params (FILE *, struct cgraph_node *node);