Strip only selected predictors after early tree passes (PR tree-optimization/85799).
2018-08-10 Martin Liska <mliska@suse.cz> PR tree-optimization/85799 * passes.def: Add argument for pass_strip_predict_hints. * predict.c (class pass_strip_predict_hints): Add new argument early_p. (strip_predictor_early): New function. (pass_strip_predict_hints::execute): Call the function to strip predictors. (strip_predict_hints): New function. * predict.def: Fix comment. 2018-08-10 Martin Liska <mliska@suse.cz> PR tree-optimization/85799 * gcc.dg/pr85799.c: New test. From-SVN: r263465
This commit is contained in:
parent
d568f0b6db
commit
7a096965f6
@ -1,3 +1,15 @@
|
||||
2018-08-10 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR tree-optimization/85799
|
||||
* passes.def: Add argument for pass_strip_predict_hints.
|
||||
* predict.c (class pass_strip_predict_hints): Add new argument
|
||||
early_p.
|
||||
(strip_predictor_early): New function.
|
||||
(pass_strip_predict_hints::execute): Call the function to
|
||||
strip predictors.
|
||||
(strip_predict_hints): New function.
|
||||
* predict.def: Fix comment.
|
||||
|
||||
2018-08-10 Thomas Preud'homme <thomas.preudhomme@linaro.org>
|
||||
|
||||
* Makefile.in: Clarify which tm.texi to copy over to assert the
|
||||
|
@ -98,7 +98,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
early optimizations again. It is thus good idea to do this
|
||||
late. */
|
||||
NEXT_PASS (pass_split_functions);
|
||||
NEXT_PASS (pass_strip_predict_hints);
|
||||
NEXT_PASS (pass_strip_predict_hints, true /* early_p */);
|
||||
POP_INSERT_PASSES ()
|
||||
NEXT_PASS (pass_release_ssa_names);
|
||||
NEXT_PASS (pass_rebuild_cgraph_edges);
|
||||
@ -183,7 +183,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
NEXT_PASS (pass_remove_cgraph_callee_edges);
|
||||
/* Initial scalar cleanups before alias computation.
|
||||
They ensure memory accesses are not indirect wherever possible. */
|
||||
NEXT_PASS (pass_strip_predict_hints);
|
||||
NEXT_PASS (pass_strip_predict_hints, false /* early_p */);
|
||||
NEXT_PASS (pass_ccp, true /* nonzero_p */);
|
||||
NEXT_PASS (pass_post_ipa_warn);
|
||||
/* After CCP we rewrite no longer addressed locals into SSA
|
||||
@ -348,7 +348,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
NEXT_PASS (pass_all_optimizations_g);
|
||||
PUSH_INSERT_PASSES_WITHIN (pass_all_optimizations_g)
|
||||
NEXT_PASS (pass_remove_cgraph_callee_edges);
|
||||
NEXT_PASS (pass_strip_predict_hints);
|
||||
NEXT_PASS (pass_strip_predict_hints, false /* early_p */);
|
||||
/* Lower remaining pieces of GIMPLE. */
|
||||
NEXT_PASS (pass_lower_complex);
|
||||
NEXT_PASS (pass_lower_vector_ssa);
|
||||
|
100
gcc/predict.c
100
gcc/predict.c
@ -3884,38 +3884,28 @@ make_pass_profile (gcc::context *ctxt)
|
||||
return new pass_profile (ctxt);
|
||||
}
|
||||
|
||||
namespace {
|
||||
/* Return true when PRED predictor should be removed after early
|
||||
tree passes. Most of the predictors are beneficial to survive
|
||||
as early inlining can also distribute then into caller's bodies. */
|
||||
|
||||
const pass_data pass_data_strip_predict_hints =
|
||||
static bool
|
||||
strip_predictor_early (enum br_predictor pred)
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"*strip_predict_hints", /* name */
|
||||
OPTGROUP_NONE, /* optinfo_flags */
|
||||
TV_BRANCH_PROB, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_strip_predict_hints : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_strip_predict_hints (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_strip_predict_hints, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
opt_pass * clone () { return new pass_strip_predict_hints (m_ctxt); }
|
||||
virtual unsigned int execute (function *);
|
||||
|
||||
}; // class pass_strip_predict_hints
|
||||
switch (pred)
|
||||
{
|
||||
case PRED_TREE_EARLY_RETURN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get rid of all builtin_expect calls and GIMPLE_PREDICT statements
|
||||
we no longer need. */
|
||||
we no longer need. EARLY is set to true when called from early
|
||||
optimizations. */
|
||||
|
||||
unsigned int
|
||||
pass_strip_predict_hints::execute (function *fun)
|
||||
strip_predict_hints (function *fun, bool early)
|
||||
{
|
||||
basic_block bb;
|
||||
gimple *ass_stmt;
|
||||
@ -3931,15 +3921,20 @@ pass_strip_predict_hints::execute (function *fun)
|
||||
|
||||
if (gimple_code (stmt) == GIMPLE_PREDICT)
|
||||
{
|
||||
gsi_remove (&bi, true);
|
||||
changed = true;
|
||||
continue;
|
||||
if (!early
|
||||
|| strip_predictor_early (gimple_predict_predictor (stmt)))
|
||||
{
|
||||
gsi_remove (&bi, true);
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (is_gimple_call (stmt))
|
||||
{
|
||||
tree fndecl = gimple_call_fndecl (stmt);
|
||||
|
||||
if ((fndecl
|
||||
if ((!early
|
||||
&& fndecl
|
||||
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
|
||||
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
|
||||
&& gimple_call_num_args (stmt) == 2)
|
||||
@ -3967,6 +3962,49 @@ pass_strip_predict_hints::execute (function *fun)
|
||||
return changed ? TODO_cleanup_cfg : 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_strip_predict_hints =
|
||||
{
|
||||
GIMPLE_PASS, /* type */
|
||||
"*strip_predict_hints", /* name */
|
||||
OPTGROUP_NONE, /* optinfo_flags */
|
||||
TV_BRANCH_PROB, /* tv_id */
|
||||
PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
0, /* todo_flags_finish */
|
||||
};
|
||||
|
||||
class pass_strip_predict_hints : public gimple_opt_pass
|
||||
{
|
||||
public:
|
||||
pass_strip_predict_hints (gcc::context *ctxt)
|
||||
: gimple_opt_pass (pass_data_strip_predict_hints, ctxt)
|
||||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
opt_pass * clone () { return new pass_strip_predict_hints (m_ctxt); }
|
||||
void set_pass_param (unsigned int n, bool param)
|
||||
{
|
||||
gcc_assert (n == 0);
|
||||
early_p = param;
|
||||
}
|
||||
|
||||
virtual unsigned int execute (function *);
|
||||
|
||||
private:
|
||||
bool early_p;
|
||||
|
||||
}; // class pass_strip_predict_hints
|
||||
|
||||
unsigned int
|
||||
pass_strip_predict_hints::execute (function *fun)
|
||||
{
|
||||
return strip_predict_hints (fun, early_p);
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
|
@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
DEF_PREDICTOR (ENUM, NAME, HITRATE)
|
||||
|
||||
This macro will be called once for each predictor. The ENUM will
|
||||
be of type `enum predictor', and will enumerate all supported
|
||||
be of type `enum br_predictor', and will enumerate all supported
|
||||
predictors. The order of DEF_PREDICTOR calls is important, as
|
||||
in the first match combining heuristics, the predictor appearing
|
||||
first in this file will win.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2018-08-10 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR tree-optimization/85799
|
||||
* gcc.dg/pr85799.c: New test.
|
||||
|
||||
2018-08-09 Jeff Law <law@redhat.com>
|
||||
|
||||
PR middle-end/86897
|
||||
|
19
gcc/testsuite/gcc.dg/pr85799.c
Normal file
19
gcc/testsuite/gcc.dg/pr85799.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
|
||||
|
||||
void unlikely();
|
||||
void likely();
|
||||
|
||||
inline int expect_false(int b) {
|
||||
return __builtin_expect(b, 0);
|
||||
}
|
||||
|
||||
void inline_func_hint(int b) {
|
||||
if (expect_false(b)) {
|
||||
unlikely();
|
||||
} else {
|
||||
likely();
|
||||
}
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "_builtin_expect heuristics of edge" "profile_estimate"} } */
|
Loading…
Reference in New Issue
Block a user