e13->count = all - count;
remove_edge (e23);
-
+
e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
e24->probability = REG_BR_PROB_BASE;
e24->count = count;
return false;
code = gimple_assign_rhs_code (stmt);
-
+
if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
return false;
/* Generate code for transformation 2 (with parent gimple assign STMT and
probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
- within roundoff error). This generates the result into a temp and returns
+ within roundoff error). This generates the result into a temp and returns
the temp; it does not replace or alter the original STMT. */
static tree
gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
e13->count = all - count;
remove_edge (e23);
-
+
e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
e24->probability = REG_BR_PROB_BASE;
e24->count = count;
return false;
code = gimple_assign_rhs_code (stmt);
-
+
if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
return false;
NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
supported and this is built into this interface. The probabilities of taking
the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
- COUNT2/ALL respectively within roundoff error). This generates the
- result into a temp and returns the temp; it does not replace or alter
+ COUNT2/ALL respectively within roundoff error). This generates the
+ result into a temp and returns the temp; it does not replace or alter
the original STMT. */
/* FIXME: Generalize the interface to handle NCOUNTS > 1. */
e12 = split_block (bb, bb1end);
bb2 = e12->dest;
bb2->count = all - count1;
-
+
if (ncounts) /* Assumed to be 0 or 1. */
{
e23 = split_block (bb2, bb2end);
histogram_value histogram;
enum tree_code code;
gcov_type count, wrong_values, all;
- tree lhs_type, result, value;
+ tree lhs_type, result;
gcov_type prob1, prob2;
unsigned int i, steps;
gcov_type count1, count2;
return false;
code = gimple_assign_rhs_code (stmt);
-
+
if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
return false;
if (!histogram)
return false;
- value = histogram->hvalue.value;
all = 0;
wrong_values = 0;
for (i = 0; i < histogram->hdata.intvl.steps; i++)
/* Initialize map of pids (pid -> cgraph node) */
-static void
+static void
init_pid_map (void)
{
struct cgraph_node *n;
*/
static gimple
-gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
+gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
int prob, gcov_type count, gcov_type all)
{
gimple dcall_stmt, load_stmt, cond_stmt;
load_stmt = gimple_build_assign (tmpv, tmp);
gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
- tmp = fold_convert (optype, build_addr (direct_call->decl,
+ tmp = fold_convert (optype, build_addr (direct_call->decl,
current_function_decl));
load_stmt = gimple_build_assign (tmp1, tmp);
gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
e_ci->count = all - count;
remove_edge (e_di);
-
+
e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
e_dj->probability = REG_BR_PROB_BASE;
e_dj->count = count;
lp_nr = lookup_stmt_eh_lp (icall_stmt);
if (lp_nr != 0)
{
- gimple_purge_dead_eh_edges (join_bb);
-
if (stmt_could_throw_p (dcall_stmt))
{
add_stmt_to_eh_lp (dcall_stmt, lp_nr);
gcc_assert (stmt_could_throw_p (icall_stmt));
make_eh_edges (icall_stmt);
+
+ /* The old EH edges are sill on the join BB, purge them. */
+ gimple_purge_dead_eh_edges (join_bb);
}
return dcall_stmt;
tree callee;
gimple modify;
struct cgraph_node *direct_call;
-
+
if (gimple_code (stmt) != GIMPLE_CALL)
return false;
return false;
bb_all = gimple_bb (stmt)->count;
- /* The order of CHECK_COUNTER calls is important -
+ /* The order of CHECK_COUNTER calls is important -
since check_counter can correct the third parameter
and we want to make count <= all <= bb_all. */
if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
return true;
}
-/* Return true if the stringop CALL with FNDECL shall be profiled. */
+/* Return true if the stringop CALL with FNDECL shall be profiled.
+ SIZE_ARG be set to the argument index for the size of the string
+ operation.
+*/
static bool
-interesting_stringop_to_profile_p (tree fndecl, gimple call)
+interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
{
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
{
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMPCPY:
+ *size_arg = 2;
return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
INTEGER_TYPE, VOID_TYPE);
case BUILT_IN_MEMSET:
+ *size_arg = 2;
return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
INTEGER_TYPE, VOID_TYPE);
case BUILT_IN_BZERO:
+ *size_arg = 1;
return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
VOID_TYPE);
default:
}
/* Convert stringop (..., vcall_size)
- into
+ into
if (vcall_size == icall_size)
stringop (..., icall_size);
else
basic_block cond_bb, icall_bb, vcall_bb, join_bb;
edge e_ci, e_cv, e_iv, e_ij, e_vj;
gimple_stmt_iterator gsi;
+ tree fndecl;
+ int size_arg;
+
+ fndecl = gimple_call_fndecl (vcall_stmt);
+ if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg))
+ gcc_unreachable();
cond_bb = gimple_bb (vcall_stmt);
gsi = gsi_for_stmt (vcall_stmt);
- vcall_size = gimple_call_arg (vcall_stmt, 2);
+ vcall_size = gimple_call_arg (vcall_stmt, size_arg);
optype = TREE_TYPE (vcall_size);
tmpv = create_tmp_var (optype, "PROF");
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
icall_stmt = gimple_copy (vcall_stmt);
- gimple_call_set_arg (icall_stmt, 2, icall_size);
+ gimple_call_set_arg (icall_stmt, size_arg, icall_size);
gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
/* Fix CFG. */
e_cv->count = all - count;
remove_edge (e_iv);
-
+
e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
e_ij->probability = REG_BR_PROB_BASE;
e_ij->count = count;
enum built_in_function fcode;
histogram_value histogram;
gcov_type count, all, val;
- tree value;
tree dest, src;
unsigned int dest_align, src_align;
gcov_type prob;
tree tree_val;
+ int size_arg;
if (gimple_code (stmt) != GIMPLE_CALL)
return false;
if (!fndecl)
return false;
fcode = DECL_FUNCTION_CODE (fndecl);
- if (!interesting_stringop_to_profile_p (fndecl, stmt))
+ if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
return false;
- if (fcode == BUILT_IN_BZERO)
- blck_size = gimple_call_arg (stmt, 1);
- else
- blck_size = gimple_call_arg (stmt, 2);
+ blck_size = gimple_call_arg (stmt, size_arg);
if (TREE_CODE (blck_size) == INTEGER_CST)
return false;
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
if (!histogram)
return false;
- value = histogram->hvalue.value;
val = histogram->hvalue.counters[0];
count = histogram->hvalue.counters[1];
all = histogram->hvalue.counters[2];
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
-
+
return true;
}
/* Identify and exploit properties of values that are hard to analyze
statically. See value-prof.c for more detail. */
- bool (*value_profile_transformations) (void);
+ bool (*value_profile_transformations) (void);
};
\f
/* Find values inside STMT for that we want to measure histograms for
}
}
-/* Find calls inside STMT for that we want to measure histograms for
- indirect/virtual call optimization. */
+/* Find calls inside STMT for that we want to measure histograms for
+ indirect/virtual call optimization. */
static void
gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
VEC_reserve (histogram_value, heap, *values, 3);
- VEC_quick_push (histogram_value, *values,
+ VEC_quick_push (histogram_value, *values,
gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
stmt, callee));
tree fndecl;
tree blck_size;
tree dest;
- enum built_in_function fcode;
+ int size_arg;
if (gimple_code (stmt) != GIMPLE_CALL)
return;
fndecl = gimple_call_fndecl (stmt);
if (!fndecl)
return;
- fcode = DECL_FUNCTION_CODE (fndecl);
- if (!interesting_stringop_to_profile_p (fndecl, stmt))
+ if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
return;
dest = gimple_call_arg (stmt, 0);
- if (fcode == BUILT_IN_BZERO)
- blck_size = gimple_call_arg (stmt, 1);
- else
- blck_size = gimple_call_arg (stmt, 2);
+ blck_size = gimple_call_arg (stmt, size_arg);
if (TREE_CODE (blck_size) != INTEGER_CST)
{
FOR_EACH_BB (bb)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
gimple_values_to_profile (gsi_stmt (gsi), values);
-
+
for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++)
{
switch (hist->type)