diff options
author | Jeff Law <law@redhat.com> | 2016-01-14 00:38:18 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2016-01-14 00:38:18 -0700 |
commit | 947c2ce56cf736fb2c48ad3d777e7c352585ce16 (patch) | |
tree | e2d540323b0a78d1cf4ebeecd230feb41d5aded8 /gcc/tree-ssa-dom.c | |
parent | 19860f48c4f999240d1b14278b6756cb6e614c80 (diff) | |
download | gcc-947c2ce56cf736fb2c48ad3d777e7c352585ce16.zip gcc-947c2ce56cf736fb2c48ad3d777e7c352585ce16.tar.gz gcc-947c2ce56cf736fb2c48ad3d777e7c352585ce16.tar.bz2 |
[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
Diffstat (limited to 'gcc/tree-ssa-dom.c')
-rw-r--r-- | gcc/tree-ssa-dom.c | 54 |
1 files changed, 41 insertions, 13 deletions
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) |