From: Jeff Law Date: Thu, 14 Jan 2016 07:38:18 +0000 (-0700) Subject: [PATCH][PR tree-optimization/69270] Exploit VRP information in DOM X-Git-Tag: upstream/12.2.0~49522 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=947c2ce56cf736fb2c48ad3d777e7c352585ce16;p=platform%2Fupstream%2Fgcc.git [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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc13621..40e3dfb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-01-14 Jeff Law + + 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 PR ipa/66487 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f393e25..63976ea 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-14 Jeff Law + + PR tree-optimization/69270 + * gcc.dg/tree-ssa/pr69270.c: New test. + 2016-01-13 Bernd Schmidt PR c/66208 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c b/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c new file mode 100644 index 0000000..529b521 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c @@ -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; + } +} diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 9d2e189..a9abed9 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -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)