aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-dom.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2016-01-14 00:38:18 -0700
committerJeff Law <law@gcc.gnu.org>2016-01-14 00:38:18 -0700
commit947c2ce56cf736fb2c48ad3d777e7c352585ce16 (patch)
treee2d540323b0a78d1cf4ebeecd230feb41d5aded8 /gcc/tree-ssa-dom.c
parent19860f48c4f999240d1b14278b6756cb6e614c80 (diff)
downloadgcc-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.c54
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)