hist->fun = fun;
}
-
/* Remove histogram HIST from STMT's histogram list. */
void
free (hist);
}
-
/* Lookup histogram of type TYPE in the STMT. */
histogram_value
if (hist->hvalue.next)
stream_out_histogram_value (ob, hist->hvalue.next);
}
+
/* Dump information about HIST to DUMP_FILE. */
void
}
}
-
/* Move all histograms associated with OSTMT to STMT. */
void
return 1;
}
-
/* Verify sanity of the histograms. */
DEBUG_FUNCTION void
}
}
-
/* The overall number of invocations of the counter should match
execution count of basic block. Report it as error rather than
internal error as it might mean that user has misused the profile
return false;
}
-
/* GIMPLE based transformations. */
bool
basic_block bb;
gimple_stmt_iterator gsi;
bool changed = false;
-
FOR_EACH_BB_FN (bb, cfun)
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
return changed;
}
-
/* Generate code for transformation 1 (with parent gimple assignment
STMT and probability of taking the optimal path PROB, which is
equivalent to COUNT/ALL within roundoff error). This generates the
return tmp2;
}
-
/* Do transform 1) on INSN if applicable. */
static bool
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
the temp; it does not replace or alter the original STMT. */
+
static tree
gimple_mod_pow2 (gassign *stmt, int prob, gcov_type count, gcov_type all)
{
}
/* Do transform 2) on INSN if applicable. */
+
static bool
gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
{
return result;
}
-
/* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */
static bool
unsigned int i, steps;
gcov_type count1, count2;
gassign *stmt;
-
stmt = dyn_cast <gassign *> (gsi_stmt (*si));
if (!stmt)
return false;
return true;
}
-/* 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.
-*/
+/* Return true if the stringop CALL 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, gcall *call, int *size_arg)
+interesting_stringop_to_profile_p (gcall *call, int *size_arg)
{
- enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ enum built_in_function fcode;
+ fcode = DECL_FUNCTION_CODE (gimple_call_fndecl (call));
if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY
&& fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO)
return false;
}
}
-/* Convert stringop (..., vcall_size)
+/* Convert stringop (..., vcall_size)
into
if (vcall_size == icall_size)
stringop (..., icall_size);
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))
+ if (!interesting_stringop_to_profile_p (vcall_stmt, &size_arg))
gcc_unreachable ();
cond_bb = gimple_bb (vcall_stmt);
/* Find values inside STMT for that we want to measure histograms for
division/modulo optimization. */
+
static bool
gimple_stringops_transform (gimple_stmt_iterator *gsi)
{
gcall *stmt;
- tree fndecl;
tree blck_size;
enum built_in_function fcode;
histogram_value histogram;
stmt = dyn_cast <gcall *> (gsi_stmt (*gsi));
if (!stmt)
return false;
- fndecl = gimple_call_fndecl (stmt);
- if (!fndecl)
+
+ if (!gimple_call_builtin_p (gsi_stmt (*gsi), BUILT_IN_NORMAL))
return false;
- fcode = DECL_FUNCTION_CODE (fndecl);
- if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
+
+ if (!interesting_stringop_to_profile_p (stmt, &size_arg))
return false;
blck_size = gimple_call_arg (stmt, size_arg);
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
if (!histogram)
return false;
+
val = histogram->hvalue.counters[0];
count = histogram->hvalue.counters[1];
all = histogram->hvalue.counters[2];
gimple_remove_histogram_value (cfun, stmt, histogram);
+
/* We require that count is at least half of all; this means
that for the transformation to fire the value must be constant
at least 80% of time. */
prob = GCOV_COMPUTE_SCALE (count, all);
else
prob = 0;
+
dest = gimple_call_arg (stmt, 0);
dest_align = get_pointer_alignment (dest);
+ fcode = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt));
switch (fcode)
{
case BUILT_IN_MEMCPY:
default:
gcc_unreachable ();
}
+
if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT))
tree_val = build_int_cst (get_gcov_type (), val);
else
(int)val);
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
+
gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
return true;
{
histogram_value histogram;
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
+
if (!histogram)
*expected_size = -1;
else if (!histogram->hvalue.counters[1])
*expected_size = size;
gimple_remove_histogram_value (cfun, stmt, histogram);
}
+
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
+
if (!histogram)
*expected_align = 0;
else if (!histogram->hvalue.counters[0])
\f
/* Find values inside STMT for that we want to measure histograms for
division/modulo optimization. */
+
static void
gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
{
/* Find values inside STMT for that we want to measure histograms for
string operations. */
+
static void
gimple_stringops_values_to_profile (gimple gs, histogram_values *values)
{
gcall *stmt;
- tree fndecl;
tree blck_size;
tree dest;
int size_arg;
stmt = dyn_cast <gcall *> (gs);
if (!stmt)
return;
- fndecl = gimple_call_fndecl (stmt);
- if (!fndecl)
+
+ if (!gimple_call_builtin_p (gs, BUILT_IN_NORMAL))
return;
- if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
+ if (!interesting_stringop_to_profile_p (stmt, &size_arg))
return;
dest = gimple_call_arg (stmt, 0);
values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
stmt, blck_size));
}
+
if (TREE_CODE (blck_size) != INTEGER_CST)
values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
stmt, dest));