Commit ca90b1ed by Yuri Rumyantsev Committed by Ilya Enkovich

re PR rtl-optimization/68920 (Undesirable if-conversion for a rarely taken branch)

gcc/

2016-01-11  Yuri Rumyantsev  <ysrumyan@gmail.com>

	PR rtl-optimization/68920
	* config/i386/i386.c (ix86_option_override_internal): Restrict number
	of conditional moves for  RTL if-conversion to 1 for
	TARGET_ONE_IF_CONV_INSN.
	* config/i386/i386.h (TARGET_ONE_IF_CONV_INSN): New macros.
	* config/i386/x86-tune.def (X86_TUNE_ONE_IF_CONV_INSN): New macros.
	* params.def (PARAM_MAX_RTL_IF_CONVERSION_INSNS) : Introduce new
	parameter to restirct number of conditional moves for
	RTL if-conversion.
	* doc/invoke.texi (max-rtl-if-conversion-insns): Document it.
	* ifcvt.c (bb_ok_for_noce_convert_multiple_sets): Limit number of
	conditionl moves.

gcc/testsuite/

2016-01-11  Yuri Rumyantsev  <ysrumyan@gmail.com>

	PR rtl-optimization/68920
	* gcc.dg/ifcvt-4.c: Add "--param max-rtl-if-conversion-insns=3" option
	for ix86 targets.
	* gcc.dg/ifcvt-5.c: New test.

From-SVN: r232220
parent b4934671
2016-01-11 Yuri Rumyantsev <ysrumyan@gmail.com>
PR rtl-optimization/68920
* config/i386/i386.c (ix86_option_override_internal): Restrict number
of conditional moves for RTL if-conversion to 1 for
TARGET_ONE_IF_CONV_INSN.
* config/i386/i386.h (TARGET_ONE_IF_CONV_INSN): New macros.
* config/i386/x86-tune.def (X86_TUNE_ONE_IF_CONV_INSN): New macros.
* params.def (PARAM_MAX_RTL_IF_CONVERSION_INSNS) : Introduce new
parameter to restirct number of conditional moves for
RTL if-conversion.
* doc/invoke.texi (max-rtl-if-conversion-insns): Document it.
* ifcvt.c (bb_ok_for_noce_convert_multiple_sets): Limit number of
conditionl moves.
2016-01-11 Alexandre Oliva <aoliva@redhat.com>
PR bootstrap/69123
......
......@@ -5343,6 +5343,13 @@ ix86_option_override_internal (bool main_args_p,
opts->x_param_values,
opts_set->x_param_values);
/* Restrict number of if-converted SET insns to 1. */
if (TARGET_ONE_IF_CONV_INSN)
maybe_set_param_value (PARAM_MAX_RTL_IF_CONVERSION_INSNS,
1,
opts->x_param_values,
opts_set->x_param_values);
/* Enable sw prefetching at -O3 for CPUS that prefetching is helpful. */
if (opts->x_flag_prefetch_loop_arrays < 0
&& HAVE_prefetch
......@@ -499,6 +499,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST];
ix86_tune_features[X86_TUNE_ADJUST_UNROLL]
#define TARGET_AVOID_FALSE_DEP_FOR_BMI \
ix86_tune_features[X86_TUNE_AVOID_FALSE_DEP_FOR_BMI]
#define TARGET_ONE_IF_CONV_INSN \
ix86_tune_features[X86_TUNE_ONE_IF_CONV_INSN]
/* Feature tests against the various architecture variations. */
enum ix86_arch_indices {
......
......@@ -550,3 +550,8 @@ DEF_TUNE (X86_TUNE_PROMOTE_QI_REGS, "promote_qi_regs", 0)
unrolling small loop less important. For, such architectures we adjust
the unroll factor so that the unrolled loop fits the loop buffer. */
DEF_TUNE (X86_TUNE_ADJUST_UNROLL, "adjust_unroll_factor", m_BDVER3 | m_BDVER4)
/* X86_TUNE_ONE_IF_CONV_INSNS: Restrict a number of set insns to be
if-converted to one. */
DEF_TUNE (X86_TUNE_ONE_IF_CONV_INSN, "one_if_conv_insn",
m_SILVERMONT | m_KNL | m_INTEL | m_CORE_ALL | m_GENERIC)
......@@ -10365,6 +10365,14 @@ In each case, the @var{value} is an integer. The allowable choices for
When branch is predicted to be taken with probability lower than this threshold
(in percent), then it is considered well predictable. The default is 10.
@item max-rtl-if-conversion-insns
RTL if-conversion tries to remove conditional branches around a block and
replace them with conditionally executed instructions. This parameter
gives the maximum number of instructions in a block which should be
considered for if-conversion. The default is 10, though the compiler will
also use other heuristics to decide whether if-conversion is likely to be
profitable.
@item max-crossjump-edges
The maximum number of incoming edges to consider for cross-jumping.
The algorithm used by @option{-fcrossjumping} is @math{O(N^2)} in
......
......@@ -44,6 +44,7 @@
#include "shrink-wrap.h"
#include "rtl-iter.h"
#include "ifcvt.h"
#include "params.h"
#ifndef MAX_CONDITIONAL_EXECUTE
#define MAX_CONDITIONAL_EXECUTE \
......@@ -3242,6 +3243,8 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
{
rtx_insn *insn;
unsigned count = 0;
unsigned param = PARAM_VALUE (PARAM_MAX_RTL_IF_CONVERSION_INSNS);
unsigned limit = MIN (ii->branch_cost, param);
FOR_BB_INSNS (test_bb, insn)
{
......@@ -3277,8 +3280,8 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
/* FORNOW: Our cost model is a count of the number of instructions we
would if-convert. This is suboptimal, and should be improved as part
of a wider rework of branch_cost. */
if (count > ii->branch_cost)
return FALSE;
if (count > limit)
return false;
return count > 0;
}
......@@ -3823,7 +3826,6 @@ cond_move_process_if_block (struct noce_if_info *if_info)
}
num_updated_if_blocks++;
success_p = TRUE;
done:
......@@ -4810,7 +4812,6 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
num_true_changes++;
num_updated_if_blocks++;
return TRUE;
}
......
......@@ -1177,6 +1177,12 @@ DEFPARAM (PARAM_MAX_SSA_NAME_QUERY_DEPTH,
"Maximum recursion depth allowed when querying a property of an"
" SSA name.",
2, 1, 0)
DEFPARAM (PARAM_MAX_RTL_IF_CONVERSION_INSNS,
"max-rtl-if-conversion-insns",
"Maximum number of insns in a basic block to consider for RTL "
"if-conversion.",
10, 0, 99)
/*
Local variables:
......
2016-01-11 Yuri Rumyantsev <ysrumyan@gmail.com>
PR rtl-optimization/68920
* gcc.dg/ifcvt-4.c: Add "--param max-rtl-if-conversion-insns=3" option
for ix86 targets.
* gcc.dg/ifcvt-5.c: New test.
2016-01-11 Alexandre Oliva <aoliva@redhat.com>
PR bootstrap/69123
......
/* { dg-options "-fdump-rtl-ce1 -O2" } */
/* { dg-options "-fdump-rtl-ce1 -O2 --param max-rtl-if-conversion-insns=3" } */
/* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" { "arm*-*-* powerpc64le*-*-*" } {"*"} { "" } } */
int
......
/* Check that multi-insn if-conversion is not done if the override
parameter would not allow it. */
/* { dg-options "-fdump-rtl-ce1 -O2 --param max-rtl-if-conversion-insns=1" } */
int
foo (int x, int y, int a)
{
int i = x;
int j = y;
if (x > y)
{
i = a;
j = i;
}
return i * j;
}
/* { dg-final { scan-rtl-dump "0 true changes made" "ce1" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment