re PR tree-optimization/69270 (DOM should exploit range information to create more equivalences)

PR tree-optimization/69270
	* tree-ssanames.c (ssa_name_has_boolean_range): Moved here from
	tree-ssa-dom.c.  Improve test for [0..1] ranve from VRP.
	* tree-ssa-dom.c (ssa_name_has_boolean_range): Remove.
	* tree-ssanames.h (ssa_name_has_boolean_range): Prototype.
	* tree-ssa-uncprop.c (associate_equivalences_with_edges): Use
	ssa_name_has_boolean_range and constant_boolean_node.

	PR tree-optimization/69270
	* gcc.dg/tree-ssa/pr69270-2.c: New test.
	* gcc.dg/tree-ssa/pr69270-3.c: New test.

From-SVN: r232453
This commit is contained in:
Jeff Law 2016-01-15 15:32:05 -07:00 committed by Jeff Law
parent cebeb718fe
commit 40c43acacc
8 changed files with 141 additions and 42 deletions

View File

@ -1,3 +1,13 @@
2016-01-15 Jeff Law <law@redhat.com>
PR tree-optimization/69270
* tree-ssanames.c (ssa_name_has_boolean_range): Moved here from
tree-ssa-dom.c. Improve test for [0..1] ranve from VRP.
* tree-ssa-dom.c (ssa_name_has_boolean_range): Remove.
* tree-ssanames.h (ssa_name_has_boolean_range): Prototype.
* tree-ssa-uncprop.c (associate_equivalences_with_edges): Use
ssa_name_has_boolean_range and constant_boolean_node.
2016-01-15 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/69030

View File

@ -1,3 +1,9 @@
2016-01-15 Jeff Law <law@redhat.com>
PR tree-optimization/69270
* gcc.dg/tree-ssa/pr69270-2.c: New test.
* gcc.dg/tree-ssa/pr69270-3.c: New test.
2016-01-15 Paul Thomas <pault@gcc.gnu.org>
PR fortran/49630

View File

@ -0,0 +1,52 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-dom3-details -w" } */
/* There should be a reference to usecount that turn into
constants. */
/* { dg-final { scan-tree-dump-times "Replaced .usecount_\[0-9\]+. with constant .1." 1 "dom3"} } */
/* And an assignment using usecount ought to fold down to constants. */
/* { dg-final { scan-tree-dump-times "Folded to: usecount_\[0-9\]+ = 2;" 1 "dom3"} } */
/* The arithmetic using usecount should be gone, except for the one in the
details debugging. */
/* { dg-final { scan-tree-dump-times "usecount_\[0-9\]+ = usecount_\[0-9\]+ . 1;" 1 "dom3"} } */
typedef union tree_node *tree;
typedef union gimple_statement_d *gimple;
extern const int tree_code_type[];
union tree_node
{
int code:16;
};
typedef struct immediate_use_iterator_d
{
}
imm_use_iterator;
void
insert_debug_temp_for_var_def (gimple stmt)
{
gimple def_stmt = ((void *) 0);
int usecount = 0;
tree value = ((void *) 0);
for (; arf ();)
{
if (!gimple_debug_bind_p (stmt))
continue;
if (usecount++)
break;
unsigned char no_value = 0;
if (!gimple_bb (def_stmt))
no_value = 1;
if (!no_value)
value = gimple_assign_rhs_to_tree ();
}
if (value)
{
if ((tree_code_type[(int) (((value)->code))] == 42)
|| (usecount == 1 && (is_gimple_min_invariant (value))))
value = unshare_expr (value);
}
}

View File

@ -0,0 +1,26 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-uncprop-details -w" } */
/* We're looking for a constant argument a PHI node. There
should only be one if we unpropagate correctly. */
/* { dg-final { scan-tree-dump-times ", 1" 1 "uncprop1"} } */
typedef long unsigned int size_t;
typedef union gimple_statement_d *gimple;
unsigned char
propagate_with_phi ()
{
gimple use_stmt;
unsigned char phi_inserted;
phi_inserted = 0;
for (; !end_imm_use_stmt_p (); next_imm_use_stmt ())
{
if (!(arf () == 10 && boo () == 20))
continue;
if (!phi_inserted)
phi_inserted = 1;
else
update_stmt ();
}
}

View File

@ -316,39 +316,6 @@ record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
edge_info->cond_equivalences.safe_push (c);
}
/* Return TRUE is OP, an SSA_NAME has a range of values [0..1], false
otherwise.
This can be because it is a boolean type, any unsigned integral
type with a single bit of precision, or has known range of [0..1]
via VRP analysis. */
static bool
ssa_name_has_boolean_range (tree op)
{
/* Boolean types always have a range [0..1]. */
if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE)
return true;
/* An integral type with a single bit of precision. */
if (INTEGRAL_TYPE_P (TREE_TYPE (op))
&& TYPE_UNSIGNED (TREE_TYPE (op))
&& TYPE_PRECISION (TREE_TYPE (op)) == 1)
return true;
/* An integral type with more precision, but the object
only takes on values [0..1] as determined by VRP
analysis. */
wide_int min, max;
if (INTEGRAL_TYPE_P (TREE_TYPE (op))
&& get_range_info (op, &min, &max) == VR_RANGE
&& wi::eq_p (min, 0)
&& wi::eq_p (max, 1))
return true;
return false;
}
/* We have finished optimizing BB, record any information implied by
taking a specific outgoing edge from BB. */

View File

@ -94,23 +94,26 @@ associate_equivalences_with_edges (void)
can record an equivalence for OP0 rather than COND. */
if (TREE_CODE (op0) == SSA_NAME
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
&& TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
&& ssa_name_has_boolean_range (op0)
&& is_gimple_min_invariant (op1))
{
tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
tree false_val = constant_boolean_node (false,
TREE_TYPE (op0));
if (code == EQ_EXPR)
{
equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_false_node
: boolean_true_node);
? false_val
: true_val);
true_edge->aux = equivalency;
equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_true_node
: boolean_false_node);
? true_val
: false_val);
false_edge->aux = equivalency;
}
else
@ -118,15 +121,15 @@ associate_equivalences_with_edges (void)
equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_true_node
: boolean_false_node);
? true_val
: false_val);
true_edge->aux = equivalency;
equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = (integer_zerop (op1)
? boolean_false_node
: boolean_true_node);
? false_val
: true_val);
false_edge->aux = equivalency;
}
}

View File

@ -411,6 +411,40 @@ get_nonzero_bits (const_tree name)
return ri->get_nonzero_bits ();
}
/* Return TRUE is OP, an SSA_NAME has a range of values [0..1], false
otherwise.
This can be because it is a boolean type, any unsigned integral
type with a single bit of precision, or has known range of [0..1]
via VRP analysis. */
bool
ssa_name_has_boolean_range (tree op)
{
gcc_assert (TREE_CODE (op) == SSA_NAME);
/* Boolean types always have a range [0..1]. */
if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE)
return true;
/* An integral type with a single bit of precision. */
if (INTEGRAL_TYPE_P (TREE_TYPE (op))
&& TYPE_UNSIGNED (TREE_TYPE (op))
&& TYPE_PRECISION (TREE_TYPE (op)) == 1)
return true;
/* An integral type with more precision, but the object
only takes on values [0..1] as determined by VRP
analysis. */
if (INTEGRAL_TYPE_P (TREE_TYPE (op))
&& (TYPE_PRECISION (TREE_TYPE (op)) > 1
|| TYPE_UNSIGNED (TREE_TYPE (op)))
&& wi::eq_p (get_nonzero_bits (op), 1))
return true;
return false;
}
/* We no longer need the SSA_NAME expression VAR, release it so that
it may be reused.

View File

@ -75,6 +75,7 @@ extern enum value_range_type get_range_info (const_tree, wide_int *,
wide_int *);
extern void set_nonzero_bits (tree, const wide_int_ref &);
extern wide_int get_nonzero_bits (const_tree);
extern bool ssa_name_has_boolean_range (tree);
extern void init_ssanames (struct function *, int);
extern void fini_ssanames (struct function *);
extern void ssanames_print_statistics (void);