mirror of git://gcc.gnu.org/git/gcc.git
Teach VRP to register assertions along default switch labels (PR18046)
gcc/ChangeLog: PR tree-optimization/18046 * genmodes.c (emit_mode_size_inline): Emit an assert that verifies that mode is a valid array index. (emit_mode_nuinits_inline): Likewise. (emit_mode_inner_inline): Likewise. (emit_mode_unit_size_inline): Likewise. (emit_mode_unit_precision_inline): Likewise. * tree-vrp.c: Include params.h. (find_switch_asserts): Register edge assertions for the default label which correspond to the anti-ranges of each case label. * params.def (PARAM_MAX_VRP_SWITCH_ASSERTIONS): New. * doc/invoke.texi: Document it. gcc/testsuite/ChangeLog: PR tree-optimization/18046 * gcc.dg/tree-ssa/ssa-dom-thread-6.c: Bump FSM count to 5. * gcc.dg/tree-ssa/vrp103.c: New test. * gcc.dg/tree-ssa/vrp104.c: New test. From-SVN: r238761
This commit is contained in:
parent
100665d8d7
commit
524cf1e47a
|
|
@ -1,3 +1,18 @@
|
||||||
|
2016-07-26 Patrick Palka <ppalka@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR tree-optimization/18046
|
||||||
|
* genmodes.c (emit_mode_size_inline): Emit an assert that
|
||||||
|
verifies that mode is a valid array index.
|
||||||
|
(emit_mode_nuinits_inline): Likewise.
|
||||||
|
(emit_mode_inner_inline): Likewise.
|
||||||
|
(emit_mode_unit_size_inline): Likewise.
|
||||||
|
(emit_mode_unit_precision_inline): Likewise.
|
||||||
|
* tree-vrp.c: Include params.h.
|
||||||
|
(find_switch_asserts): Register edge assertions for the default
|
||||||
|
label which correspond to the anti-ranges of each case label.
|
||||||
|
* params.def (PARAM_MAX_VRP_SWITCH_ASSERTIONS): New.
|
||||||
|
* doc/invoke.texi: Document it.
|
||||||
|
|
||||||
2016-07-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
2016-07-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* gimple-ssa-strength-reduction.c (slsr_process_phi): Remove dead
|
* gimple-ssa-strength-reduction.c (slsr_process_phi): Remove dead
|
||||||
|
|
|
||||||
|
|
@ -9781,6 +9781,10 @@ enable it.
|
||||||
The maximum number of may-defs we analyze when looking for a must-def
|
The maximum number of may-defs we analyze when looking for a must-def
|
||||||
specifying the dynamic type of an object that invokes a virtual call
|
specifying the dynamic type of an object that invokes a virtual call
|
||||||
we may be able to devirtualize speculatively.
|
we may be able to devirtualize speculatively.
|
||||||
|
|
||||||
|
@item max-vrp-switch-assertions
|
||||||
|
The maximum number of assertions to add along the default edge of a switch
|
||||||
|
statement during VRP. The default is 10.
|
||||||
@end table
|
@end table
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -976,6 +976,7 @@ unsigned char\n\
|
||||||
mode_size_inline (machine_mode mode)\n\
|
mode_size_inline (machine_mode mode)\n\
|
||||||
{\n\
|
{\n\
|
||||||
extern %sunsigned char mode_size[NUM_MACHINE_MODES];\n\
|
extern %sunsigned char mode_size[NUM_MACHINE_MODES];\n\
|
||||||
|
gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
|
||||||
switch (mode)\n\
|
switch (mode)\n\
|
||||||
{\n", adj_bytesize ? "" : "const ");
|
{\n", adj_bytesize ? "" : "const ");
|
||||||
|
|
||||||
|
|
@ -1006,6 +1007,7 @@ unsigned char\n\
|
||||||
mode_nunits_inline (machine_mode mode)\n\
|
mode_nunits_inline (machine_mode mode)\n\
|
||||||
{\n\
|
{\n\
|
||||||
extern const unsigned char mode_nunits[NUM_MACHINE_MODES];\n\
|
extern const unsigned char mode_nunits[NUM_MACHINE_MODES];\n\
|
||||||
|
gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
|
||||||
switch (mode)\n\
|
switch (mode)\n\
|
||||||
{");
|
{");
|
||||||
|
|
||||||
|
|
@ -1035,6 +1037,7 @@ unsigned char\n\
|
||||||
mode_inner_inline (machine_mode mode)\n\
|
mode_inner_inline (machine_mode mode)\n\
|
||||||
{\n\
|
{\n\
|
||||||
extern const unsigned char mode_inner[NUM_MACHINE_MODES];\n\
|
extern const unsigned char mode_inner[NUM_MACHINE_MODES];\n\
|
||||||
|
gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
|
||||||
switch (mode)\n\
|
switch (mode)\n\
|
||||||
{");
|
{");
|
||||||
|
|
||||||
|
|
@ -1067,6 +1070,7 @@ mode_unit_size_inline (machine_mode mode)\n\
|
||||||
{\n\
|
{\n\
|
||||||
extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];\
|
extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];\
|
||||||
\n\
|
\n\
|
||||||
|
gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
|
||||||
switch (mode)\n\
|
switch (mode)\n\
|
||||||
{");
|
{");
|
||||||
|
|
||||||
|
|
@ -1103,6 +1107,7 @@ unsigned short\n\
|
||||||
mode_unit_precision_inline (machine_mode mode)\n\
|
mode_unit_precision_inline (machine_mode mode)\n\
|
||||||
{\n\
|
{\n\
|
||||||
extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];\n\
|
extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];\n\
|
||||||
|
gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
|
||||||
switch (mode)\n\
|
switch (mode)\n\
|
||||||
{");
|
{");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1246,6 +1246,12 @@ DEFPARAM (PARAM_MAX_SPECULATIVE_DEVIRT_MAYDEFS,
|
||||||
"Maximum number of may-defs visited when devirtualizing "
|
"Maximum number of may-defs visited when devirtualizing "
|
||||||
"speculatively", 50, 0, 0)
|
"speculatively", 50, 0, 0)
|
||||||
|
|
||||||
|
DEFPARAM (PARAM_MAX_VRP_SWITCH_ASSERTIONS,
|
||||||
|
"max-vrp-switch-assertions",
|
||||||
|
"Maximum number of assertions to add along the default "
|
||||||
|
"edge of a switch statement during VRP",
|
||||||
|
10, 0, 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Local variables:
|
Local variables:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
2016-07-26 Patrick Palka <ppalka@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR tree-optimization/18046
|
||||||
|
* gcc.dg/tree-ssa/ssa-dom-thread-6.c: Bump FSM count to 5.
|
||||||
|
* gcc.dg/tree-ssa/vrp103.c: New test.
|
||||||
|
* gcc.dg/tree-ssa/vrp104.c: New test.
|
||||||
|
|
||||||
2016-07-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
2016-07-26 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* gcc.target/powerpc/pr63354.c: Require lp64 since
|
* gcc.target/powerpc/pr63354.c: Require lp64 since
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* { dg-do compile } */
|
/* { dg-do compile } */
|
||||||
/* { dg-options "-O2 -fdump-tree-thread1-details -fdump-tree-thread2-details" } */
|
/* { dg-options "-O2 -fdump-tree-thread1-details -fdump-tree-thread2-details" } */
|
||||||
/* { dg-final { scan-tree-dump-times "FSM" 3 "thread1" } } */
|
/* { dg-final { scan-tree-dump-times "FSM" 3 "thread1" } } */
|
||||||
/* { dg-final { scan-tree-dump-times "FSM" 4 "thread2" } } */
|
/* { dg-final { scan-tree-dump-times "FSM" 5 "thread2" } } */
|
||||||
|
|
||||||
int sum0, sum1, sum2, sum3;
|
int sum0, sum1, sum2, sum3;
|
||||||
int foo (char *s, char **ret)
|
int foo (char *s, char **ret)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* PR tree-optimization/18046 */
|
||||||
|
/* { dg-options "-O2 -fdump-tree-vrp" } */
|
||||||
|
/* { dg-final { scan-tree-dump-times "baz \\(0\\);" 4 "vrp1" } } */
|
||||||
|
|
||||||
|
void foo (void);
|
||||||
|
void bar (void);
|
||||||
|
void baz (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
test (int i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
foo ();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
bar ();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* These tests should be folded to 0, resulting in 4 calls of baz(0). */
|
||||||
|
baz (i == 1);
|
||||||
|
baz (i == 2);
|
||||||
|
baz (i == 3);
|
||||||
|
baz (i == 5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* PR tree-optimization/18046 */
|
||||||
|
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||||
|
/* { dg-final { scan-tree-dump-times "switch" 1 "optimized" } } */
|
||||||
|
|
||||||
|
void foo (void);
|
||||||
|
void bar (void);
|
||||||
|
void baz (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
test (int i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
foo ();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bar ();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This switch should be gone after threading/VRP. */
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
foo ();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
baz ();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "omp-low.h"
|
#include "omp-low.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "case-cfn-macros.h"
|
#include "case-cfn-macros.h"
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
/* Range of values that can be associated with an SSA_NAME after VRP
|
/* Range of values that can be associated with an SSA_NAME after VRP
|
||||||
has executed. */
|
has executed. */
|
||||||
|
|
@ -5917,6 +5918,7 @@ find_switch_asserts (basic_block bb, gswitch *last)
|
||||||
ci[idx].expr = gimple_switch_label (last, idx);
|
ci[idx].expr = gimple_switch_label (last, idx);
|
||||||
ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr));
|
ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr));
|
||||||
}
|
}
|
||||||
|
edge default_edge = find_edge (bb, ci[0].bb);
|
||||||
qsort (ci, n, sizeof (struct case_info), compare_case_labels);
|
qsort (ci, n, sizeof (struct case_info), compare_case_labels);
|
||||||
|
|
||||||
for (idx = 0; idx < n; ++idx)
|
for (idx = 0; idx < n; ++idx)
|
||||||
|
|
@ -5945,8 +5947,8 @@ find_switch_asserts (basic_block bb, gswitch *last)
|
||||||
max = CASE_LOW (ci[idx].expr);
|
max = CASE_LOW (ci[idx].expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing to do if the range includes the default label until we
|
/* Can't extract a useful assertion out of a range that includes the
|
||||||
can register anti-ranges. */
|
default label. */
|
||||||
if (min == NULL_TREE)
|
if (min == NULL_TREE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -5964,6 +5966,62 @@ find_switch_asserts (basic_block bb, gswitch *last)
|
||||||
}
|
}
|
||||||
|
|
||||||
XDELETEVEC (ci);
|
XDELETEVEC (ci);
|
||||||
|
|
||||||
|
if (!live_on_edge (default_edge, op))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Now register along the default label assertions that correspond to the
|
||||||
|
anti-range of each label. */
|
||||||
|
int insertion_limit = PARAM_VALUE (PARAM_MAX_VRP_SWITCH_ASSERTIONS);
|
||||||
|
for (idx = 1; idx < n; idx++)
|
||||||
|
{
|
||||||
|
tree min, max;
|
||||||
|
tree cl = gimple_switch_label (last, idx);
|
||||||
|
|
||||||
|
min = CASE_LOW (cl);
|
||||||
|
max = CASE_HIGH (cl);
|
||||||
|
|
||||||
|
/* Combine contiguous case ranges to reduce the number of assertions
|
||||||
|
to insert. */
|
||||||
|
for (idx = idx + 1; idx < n; idx++)
|
||||||
|
{
|
||||||
|
tree next_min, next_max;
|
||||||
|
tree next_cl = gimple_switch_label (last, idx);
|
||||||
|
|
||||||
|
next_min = CASE_LOW (next_cl);
|
||||||
|
next_max = CASE_HIGH (next_cl);
|
||||||
|
|
||||||
|
wide_int difference = wi::sub (next_min, max ? max : min);
|
||||||
|
if (wi::eq_p (difference, 1))
|
||||||
|
max = next_max ? next_max : next_min;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idx--;
|
||||||
|
|
||||||
|
if (max == NULL_TREE)
|
||||||
|
{
|
||||||
|
/* Register the assertion OP != MIN. */
|
||||||
|
min = fold_convert (TREE_TYPE (op), min);
|
||||||
|
register_edge_assert_for (op, default_edge, bsi, NE_EXPR, op, min);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Register the assertion (unsigned)OP - MIN > (MAX - MIN),
|
||||||
|
which will give OP the anti-range ~[MIN,MAX]. */
|
||||||
|
tree uop = fold_convert (unsigned_type_for (TREE_TYPE (op)), op);
|
||||||
|
min = fold_convert (TREE_TYPE (uop), min);
|
||||||
|
max = fold_convert (TREE_TYPE (uop), max);
|
||||||
|
|
||||||
|
tree lhs = fold_build2 (MINUS_EXPR, TREE_TYPE (uop), uop, min);
|
||||||
|
tree rhs = int_const_binop (MINUS_EXPR, max, min);
|
||||||
|
register_new_assert_for (op, lhs, GT_EXPR, rhs,
|
||||||
|
NULL, default_edge, bsi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--insertion_limit == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue