aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2023-01-25 16:26:39 -0500
committerAndrew MacLeod <amacleod@redhat.com>2023-01-31 09:56:27 -0500
commit99fda5de368d84d97eb29a9f03e0d6039068f8b9 (patch)
tree8cd99fab7a800094f52a5d860454b126779c9549
parent7f583a335769591d016caa51490e3e5dd50354fe (diff)
downloadgcc-99fda5de368d84d97eb29a9f03e0d6039068f8b9.zip
gcc-99fda5de368d84d97eb29a9f03e0d6039068f8b9.tar.gz
gcc-99fda5de368d84d97eb29a9f03e0d6039068f8b9.tar.bz2
Properly set GORI relation trios.
When relation trios were added to GORI, there was only one use. As they are utilized more by range-ops, it is apparent that the implelemtation was not complete. This patch fleshes it out completely so that every GORI operation has a complete relation trio. * gimple-range-gori.cc (gori_compute::compute_operand_range): Do not abort calculations if there is a valid relation available. (gori_compute::refine_using_relation): Pass correct relation trio. (gori_compute::compute_operand1_range): Create trio and use it. (gori_compute::compute_operand2_range): Ditto. * range-op.cc (operator_plus::op1_range): Use correct trio member. (operator_minus::op1_range): Use correct trio member. * value-relation.cc (value_relation::create_trio): New. * value-relation.h (value_relation::create_trio): New prototype.
-rw-r--r--gcc/gimple-range-gori.cc70
-rw-r--r--gcc/range-op.cc4
-rw-r--r--gcc/value-relation.cc34
-rw-r--r--gcc/value-relation.h1
4 files changed, 62 insertions, 47 deletions
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 930e2a0..3dc4576 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -632,6 +632,9 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt,
if (op1 && op2)
{
relation_kind k = handler.op1_op2_relation (lhs);
+ // If there is no relation, and op1 == op2, create a relation.
+ if (!vrel_ptr && k == VREL_VARYING && op1 == op2)
+ k = VREL_EQ;
if (k != VREL_VARYING)
{
vrel.set_relation (k, op1, op2);
@@ -952,7 +955,9 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range,
{
gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
- gcc_checking_assert (k != VREL_VARYING && k != VREL_UNDEFINED);
+
+ if (k == VREL_VARYING || k == VREL_EQ || k == VREL_UNDEFINED)
+ return false;
bool change = false;
bool op1_def_p = in_chain_p (op2, op1);
@@ -991,7 +996,7 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range,
Value_Range new_result (type);
if (!op_handler.op1_range (new_result, type,
op1_def_p ? op1_range : op2_range,
- other_op, relation_trio::lhs_op2 (k)))
+ other_op, relation_trio::lhs_op1 (k)))
return false;
if (op1_def_p)
{
@@ -1023,7 +1028,7 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range,
Value_Range new_result (type);
if (!op_handler.op2_range (new_result, type,
op1_def_p ? op1_range : op2_range,
- other_op, relation_trio::lhs_op1 (k)))
+ other_op, relation_trio::lhs_op2 (k)))
return false;
if (op1_def_p)
{
@@ -1062,6 +1067,10 @@ gori_compute::compute_operand1_range (vrange &r,
tree op2 = handler.operand2 ();
tree lhs_name = gimple_get_lhs (stmt);
+ relation_trio trio;
+ if (rel)
+ trio = rel->create_trio (lhs_name, op1, op2);
+
Value_Range op1_range (TREE_TYPE (op1));
Value_Range tmp (TREE_TYPE (op1));
Value_Range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
@@ -1073,27 +1082,11 @@ gori_compute::compute_operand1_range (vrange &r,
if (op2)
{
src.get_operand (op2_range, op2);
- relation_kind k = VREL_VARYING;
- relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING;
- if (rel)
- {
- if (lhs_name == rel->op1 () && op1 == rel->op2 ())
- k = rel->kind ();
- else if (lhs_name == rel->op2 () && op1 == rel->op1 ())
- k = relation_swap (rel->kind ());
- else if (op1 == rel->op1 () && op2 == rel->op2 ())
- {
- op_op = rel->kind ();
- refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
- }
- else if (op1 == rel->op2 () && op2 == rel->op1 ())
- {
- op_op = relation_swap (rel->kind ());
- refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
- }
- }
- if (!handler.calc_op1 (tmp, lhs, op2_range, relation_trio (VREL_VARYING,
- k, op_op)))
+ relation_kind op_op = trio.op1_op2 ();
+ if (op_op != VREL_VARYING)
+ refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
+
+ if (!handler.calc_op1 (tmp, lhs, op2_range, trio))
return false;
}
else
@@ -1101,7 +1094,7 @@ gori_compute::compute_operand1_range (vrange &r,
// We pass op1_range to the unary operation. Nomally it's a
// hidden range_for_type parameter, but sometimes having the
// actual range can result in better information.
- if (!handler.calc_op1 (tmp, lhs, op1_range, TRIO_VARYING))
+ if (!handler.calc_op1 (tmp, lhs, op1_range, trio))
return false;
}
@@ -1172,29 +1165,16 @@ gori_compute::compute_operand2_range (vrange &r,
src.get_operand (op1_range, op1);
src.get_operand (op2_range, op2);
- relation_kind k = VREL_VARYING;
- relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING;
+
+ relation_trio trio;
if (rel)
- {
- if (lhs_name == rel->op1 () && op2 == rel->op2 ())
- k = rel->kind ();
- else if (lhs_name == rel->op2 () && op2 == rel->op1 ())
- k = relation_swap (rel->kind ());
- else if (op1 == rel->op1 () && op2 == rel->op2 ())
- {
- op_op = rel->kind ();
- refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
- }
- else if (op1 == rel->op2 () && op2 == rel->op1 ())
- {
- op_op = relation_swap (rel->kind ());
- refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
- }
- }
+ trio = rel->create_trio (lhs_name, op1, op2);
+ relation_kind op_op = trio.op1_op2 ();
+ if (op_op != VREL_VARYING)
+ refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
// Intersect with range for op2 based on lhs and op1.
- if (!handler.calc_op2 (tmp, lhs, op1_range, relation_trio (k, VREL_VARYING,
- op_op)))
+ if (!handler.calc_op2 (tmp, lhs, op1_range, trio))
return false;
unsigned idx;
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 6e5754e..ed2dd1e 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1460,7 +1460,7 @@ operator_plus::op1_range (irange &r, tree type,
if (!minus)
return false;
bool res = minus.fold_range (r, type, lhs, op2);
- relation_kind rel = trio.lhs_op2 ();
+ relation_kind rel = trio.lhs_op1 ();
// Check for a relation refinement.
if (res)
adjust_op1_for_overflow (r, op2, rel, true /* PLUS_EXPR */);
@@ -1632,7 +1632,7 @@ operator_minus::op1_range (irange &r, tree type,
if (!minus)
return false;
bool res = minus.fold_range (r, type, lhs, op2);
- relation_kind rel = trio.lhs_op2 ();
+ relation_kind rel = trio.lhs_op1 ();
if (res)
adjust_op1_for_overflow (r, op2, rel, false /* PLUS_EXPR */);
return res;
diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index 5ca8a7e..f5b1e67 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -883,6 +883,40 @@ value_relation::apply_transitive (const value_relation &rel)
return false;
}
+// Create a trio from this value relation given LHS, OP1 and OP2.
+
+relation_trio
+value_relation::create_trio (tree lhs, tree op1, tree op2)
+{
+ relation_kind lhs_1;
+ if (lhs == name1 && op1 == name2)
+ lhs_1 = related;
+ else if (lhs == name2 && op1 == name1)
+ lhs_1 = relation_swap (related);
+ else
+ lhs_1 = VREL_VARYING;
+
+ relation_kind lhs_2;
+ if (lhs == name1 && op2 == name2)
+ lhs_2 = related;
+ else if (lhs == name2 && op2 == name1)
+ lhs_2 = relation_swap (related);
+ else
+ lhs_2 = VREL_VARYING;
+
+ relation_kind op_op;
+ if (op1 == name1 && op2 == name2)
+ op_op = related;
+ else if (op1 == name2 && op2 == name1)
+ op_op = relation_swap (related);
+ else if (op1 == op2)
+ op_op = VREL_EQ;
+ else
+ op_op = VREL_VARYING;
+
+ return relation_trio (lhs_1, lhs_2, op_op);
+}
+
// Dump the relation to file F.
void
diff --git a/gcc/value-relation.h b/gcc/value-relation.h
index 664fd71..340f9c4 100644
--- a/gcc/value-relation.h
+++ b/gcc/value-relation.h
@@ -426,6 +426,7 @@ public:
inline tree op1 () const { return name1; }
inline tree op2 () const { return name2; }
+ relation_trio create_trio (tree lhs, tree op1, tree op2);
bool union_ (value_relation &p);
bool intersect (value_relation &p);
void negate ();