[PATCH][PR tree-optimization/69270] Exploit VRP information in DOM
PR tree-optimization/69270 * tree-ssa-dom.c (ssa_name_has_boolean_range): New function. (record_edge_info): Use it. Convert boolean_{true,false}_node to the type of op0. PR tree-optimization/69270 * gcc.dg/tree-ssa/pr69270.c: New test. From-SVN: r232361
This commit is contained in:
parent
19860f48c4
commit
947c2ce56c
|
@ -1,3 +1,10 @@
|
|||
2016-01-14 Jeff Law <law@redhat.com>
|
||||
|
||||
PR tree-optimization/69270
|
||||
* tree-ssa-dom.c (ssa_name_has_boolean_range): New function.
|
||||
(record_edge_info): Use it. Convert boolean_{true,false}_node
|
||||
to the type of op0.
|
||||
|
||||
2016-01-13 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR ipa/66487
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-01-14 Jeff Law <law@redhat.com>
|
||||
|
||||
PR tree-optimization/69270
|
||||
* gcc.dg/tree-ssa/pr69270.c: New test.
|
||||
|
||||
2016-01-13 Bernd Schmidt <bschmidt@redhat.com>
|
||||
|
||||
PR c/66208
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fsplit-paths -fdump-tree-dom3-details" } */
|
||||
|
||||
/* There should be two references to bufferstep that turn into
|
||||
constants. */
|
||||
/* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with constant .0." 1 "dom3"} } */
|
||||
/* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with constant .1." 1 "dom3"} } */
|
||||
|
||||
/* And some assignments ought to fold down to constants. */
|
||||
/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 1;" 2 "dom3"} } */
|
||||
/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 0;" 2 "dom3"} } */
|
||||
|
||||
/* The XOR operations should have been optimized to constants. */
|
||||
/* { dg-final { scan-tree-dump-not "bit_xor" "dom3"} } */
|
||||
|
||||
|
||||
extern int *stepsizeTable;
|
||||
|
||||
void
|
||||
adpcm_coder (signed char *outdata, int len)
|
||||
{
|
||||
signed char *outp;
|
||||
int delta;
|
||||
int outputbuffer;
|
||||
int bufferstep = 0;
|
||||
outp = (signed char *) outdata;
|
||||
int step = 0;
|
||||
int index = 0;
|
||||
int diff = 0;
|
||||
for (; len > 0; len--)
|
||||
{
|
||||
delta = 0;
|
||||
if (diff >= step)
|
||||
delta = 4;
|
||||
step = stepsizeTable[index];
|
||||
if (bufferstep)
|
||||
outputbuffer = (delta << 4) & 0xf0;
|
||||
else
|
||||
*outp++ = (delta & 0x0f) | outputbuffer;
|
||||
bufferstep = !bufferstep;
|
||||
}
|
||||
}
|
|
@ -316,6 +316,38 @@ 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 type with
|
||||
a single bit of precision, or has known range of values
|
||||
it might old 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_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. */
|
||||
|
||||
|
@ -390,36 +422,32 @@ record_edge_info (basic_block bb)
|
|||
can record an equivalence for OP0 rather than COND. */
|
||||
if ((code == EQ_EXPR || code == NE_EXPR)
|
||||
&& TREE_CODE (op0) == SSA_NAME
|
||||
&& TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
|
||||
&& ssa_name_has_boolean_range (op0)
|
||||
&& is_gimple_min_invariant (op1))
|
||||
{
|
||||
tree true_val = fold_convert (TREE_TYPE (op0),
|
||||
boolean_true_node);
|
||||
tree false_val = fold_convert (TREE_TYPE (op0),
|
||||
boolean_false_node);
|
||||
if (code == EQ_EXPR)
|
||||
{
|
||||
edge_info = allocate_edge_info (true_edge);
|
||||
edge_info->lhs = op0;
|
||||
edge_info->rhs = (integer_zerop (op1)
|
||||
? boolean_false_node
|
||||
: boolean_true_node);
|
||||
edge_info->rhs = (integer_zerop (op1) ? false_val : true_val);
|
||||
|
||||
edge_info = allocate_edge_info (false_edge);
|
||||
edge_info->lhs = op0;
|
||||
edge_info->rhs = (integer_zerop (op1)
|
||||
? boolean_true_node
|
||||
: boolean_false_node);
|
||||
edge_info->rhs = (integer_zerop (op1) ? true_val : false_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
edge_info = allocate_edge_info (true_edge);
|
||||
edge_info->lhs = op0;
|
||||
edge_info->rhs = (integer_zerop (op1)
|
||||
? boolean_true_node
|
||||
: boolean_false_node);
|
||||
edge_info->rhs = (integer_zerop (op1) ? true_val : false_val);
|
||||
|
||||
edge_info = allocate_edge_info (false_edge);
|
||||
edge_info->lhs = op0;
|
||||
edge_info->rhs = (integer_zerop (op1)
|
||||
? boolean_false_node
|
||||
: boolean_true_node);
|
||||
edge_info->rhs = (integer_zerop (op1) ? false_val : true_val);
|
||||
}
|
||||
}
|
||||
else if (is_gimple_min_invariant (op0)
|
||||
|
|
Loading…
Reference in New Issue