public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Andrew Macleod <amacleod@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r13-5577] Properly set GORI relation trios.
Date: Tue, 31 Jan 2023 14:58:00 +0000 (GMT)	[thread overview]
Message-ID: <20230131145800.9DEB53858CDB@sourceware.org> (raw)

https://gcc.gnu.org/g:99fda5de368d84d97eb29a9f03e0d6039068f8b9

commit r13-5577-g99fda5de368d84d97eb29a9f03e0d6039068f8b9
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Wed Jan 25 16:26:39 2023 -0500

    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.

Diff:
---
 gcc/gimple-range-gori.cc | 70 +++++++++++++++++-------------------------------
 gcc/range-op.cc          |  4 +--
 gcc/value-relation.cc    | 34 +++++++++++++++++++++++
 gcc/value-relation.h     |  1 +
 4 files changed, 62 insertions(+), 47 deletions(-)

diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 930e2a0f0ab..3dc4576ff13 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 6e5754e9130..ed2dd1eb99c 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 5ca8a7eb0d9..f5b1e67e420 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 664fd71c925..340f9c42554 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 ();

                 reply	other threads:[~2023-01-31 14:58 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230131145800.9DEB53858CDB@sourceware.org \
    --to=amacleod@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).