#include "gcov-io.h"
#include "timevar.h"
#include "tree-pass.h"
+#include "toplev.h"
static struct value_prof_hooks *value_prof_hooks;
-/* This is the vector of histograms. Created in find_values_to_profile.
- During profile generation, freed by instrument_values.
- During profile use, freed by value_profile_transformations. */
-
-static histogram_values static_values = NULL;
-
/* In this file value profile based optimizations are placed. Currently the
following optimizations are implemented (for more detailed descriptions
see comments at value_profile_transformations):
static bool tree_mod_pow2_value_transform (tree);
static bool tree_mod_subtract_transform (tree);
+/* 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 somehow. */
+static bool
+check_counter (tree stmt, const char * name, gcov_type all, gcov_type bb_count)
+{
+ if (all != bb_count)
+ {
+ location_t * locus;
+ locus = (stmt != NULL && EXPR_HAS_LOCATION (stmt)
+ ? EXPR_LOCUS (stmt)
+ : &DECL_SOURCE_LOCATION (current_function_decl));
+ error ("%HCorrupted value profile: %s profiler overall count (%d) does not match BB count (%d)",
+ locus, name, (int)all, (int)bb_count);
+ return true;
+ }
+ return false;
+}
+
/* Tree based transformations. */
static bool
tree_value_profile_transformations (void)
{
changed = true;
/* Original statement may no longer be in the same block. */
- bb = bb_for_stmt (stmt);
+ if (bb != bb_for_stmt (stmt))
+ {
+ bb = bb_for_stmt (stmt);
+ bsi = bsi_for_stmt (stmt);
+ }
}
/* Free extra storage from compute_value_histograms. */
if (simple_cst_equal (op2, value) != 1 || 2 * count < all)
return false;
+ if (check_counter (stmt, "value", all, bb_for_stmt (stmt)->count))
+ return false;
+
/* Compute probability of taking the optimal path. */
prob = (count * REG_BR_PROB_BASE + all / 2) / all;
gcov_type count, gcov_type all)
{
tree stmt1, stmt2, stmt3, stmt4;
- tree tmp1, tmp2, tmp3;
+ tree tmp2, tmp3;
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
tree label_decl3 = create_artificial_label ();
bb = bb_for_stmt (stmt);
bsi = bsi_for_stmt (stmt);
- tmp1 = create_tmp_var (optype, "PROF");
tmp2 = create_tmp_var (optype, "PROF");
tmp3 = create_tmp_var (optype, "PROF");
- stmt1 = build2 (MODIFY_EXPR, optype, tmp1, fold_convert (optype, op2));
stmt2 = build2 (MODIFY_EXPR, optype, tmp2,
- build2 (PLUS_EXPR, optype, op2, integer_minus_one_node));
+ build2 (PLUS_EXPR, optype, op2, build_int_cst (optype, -1)));
stmt3 = build2 (MODIFY_EXPR, optype, tmp3,
- build2 (BIT_AND_EXPR, optype, tmp2, tmp1));
+ build2 (BIT_AND_EXPR, optype, tmp2, op2));
stmt4 = build3 (COND_EXPR, void_type_node,
- build2 (NE_EXPR, boolean_type_node, tmp3, integer_zero_node),
- build1 (GOTO_EXPR, void_type_node, label_decl2),
- build1 (GOTO_EXPR, void_type_node, label_decl1));
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ build2 (NE_EXPR, boolean_type_node,
+ tmp3, build_int_cst (optype, 0)),
+ build1 (GOTO_EXPR, void_type_node, label_decl2),
+ build1 (GOTO_EXPR, void_type_node, label_decl1));
bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
bsi_insert_before (&bsi, stmt4, BSI_SAME_STMT);
/* Compute probability of taking the optimal path. */
all = count + wrong_values;
+ if (check_counter (stmt, "pow2", all, bb_for_stmt (stmt)->count))
+ return false;
+
prob = (count * REG_BR_PROB_BASE + all / 2) / all;
result = tree_mod_pow2 (stmt, op, op1, op2, prob, count, all);
wrong_values += histogram->hvalue.counters[i+1];
all += wrong_values;
+ /* Compute probability of taking the optimal path. */
+ if (check_counter (stmt, "interval", all, bb_for_stmt (stmt)->count))
+ return false;
+
/* We require that we use just subtractions in at least 50% of all
evaluations. */
count = 0;
FOR_EACH_BB (bb)
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
tree_values_to_profile (bsi_stmt (bsi), values);
- static_values = *values;
for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++)
{
bool
value_profile_transformations (void)
{
- bool retval = (value_prof_hooks->value_profile_transformations) ();
- VEC_free (histogram_value, heap, static_values);
- return retval;
+ return (value_prof_hooks->value_profile_transformations) ();
}
\f