diff mbox series

[COMMITTED] Relation oracle: Make each def a new equivalency record.

Message ID c0dbafe4-d976-5562-3672-e346247bfbfe@redhat.com
State New
Headers show
Series [COMMITTED] Relation oracle: Make each def a new equivalency record. | expand

Commit Message

Andrew MacLeod Sept. 20, 2021, 9:59 p.m. UTC
The current equivalence oracle is not "killing" back edge equivalence 
sets sometimes.   Missing is that a definition starts a new equivalence 
set at that point, with nothing in it but the def itself.

Creating this new equivalence set will ensure that any subsequent 
comparisons with values live from the back edge will have 
non-symmetrical equivalence sets, and the oracle will no longer pick up 
the equivalence.  This initial set is created lazily, the first time 
that an attempt is made to combine it with another set.

Eventually I may move to a more fine grained location based analysis, 
but for now this takes care of most of the issue.

bootstrapped on x86_64-pc-linux-gnu with no regressions.  pushed.

Andrew
diff mbox series

Patch

From 5d110fe90afcd850ea21aee6429f22edd6b1b592 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Fri, 17 Sep 2021 14:58:06 -0400
Subject: [PATCH 1/2] Make each def a new equivalency record.

Create a new equivalency set at each def point killing any equivalencies
coming into the block from back edges.  Do not add equivalences for PHI
arguments defined in this block.

	* value-relation.cc (equiv_oracle::register_initial_def): New.
	(equiv_oracle::register_relation): Call register_initial_def.
	(equiv_oracle::add_equiv_to_block): New.  Split register_relation.
	(relation_oracle::register_stmt): Check def block of PHI arguments.
	* value-relation.h (equiv_oracle): Add new prototypes.
---
 gcc/value-relation.cc | 57 +++++++++++++++++++++++++++++++++++++++++++
 gcc/value-relation.h  |  3 ++-
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index d370f93d128..ac5f3f9afc0 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -407,6 +407,24 @@  equiv_oracle::register_equiv (basic_block bb, equiv_chain *equiv_1,
   return b;
 }
 
+// Create an equivalency set containing only SSA in its definition block.
+// This is done the first time SSA is registered in an equivalency and blocks
+// any DOM searches past the definition.
+
+void
+equiv_oracle::register_initial_def (tree ssa)
+{
+  if (SSA_NAME_IS_DEFAULT_DEF (ssa))
+    return;
+  basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (ssa));
+  gcc_checking_assert (bb && !find_equiv_dom (ssa, bb));
+
+  unsigned v = SSA_NAME_VERSION (ssa);
+  bitmap_set_bit (m_equiv_set, v);
+  bitmap equiv_set = BITMAP_ALLOC (&m_bitmaps);
+  bitmap_set_bit (equiv_set, v);
+  add_equiv_to_block (bb, equiv_set);
+}
 
 // Register an equivalence between SSA1 and SSA2 in block BB.
 // The equivalence oracle maintains a vector of equivalencies indexed by basic
@@ -425,6 +443,14 @@  equiv_oracle::register_relation (basic_block bb, relation_kind k, tree ssa1,
 
   unsigned v1 = SSA_NAME_VERSION (ssa1);
   unsigned v2 = SSA_NAME_VERSION (ssa2);
+
+  // If this is the first time an ssa_name has an equivalency registered
+  // create a self-equivalency record in the def block.
+  if (!bitmap_bit_p (m_equiv_set, v1))
+    register_initial_def (ssa1);
+  if (!bitmap_bit_p (m_equiv_set, v2))
+    register_initial_def (ssa2);
+
   equiv_chain *equiv_1 = find_equiv_dom (ssa1, bb);
   equiv_chain *equiv_2 = find_equiv_dom (ssa2, bb);
 
@@ -456,6 +482,15 @@  equiv_oracle::register_relation (basic_block bb, relation_kind k, tree ssa1,
   if (!equiv_set)
     return;
 
+  add_equiv_to_block (bb, equiv_set);
+}
+
+// Add an equivalency record in block BB containing bitmap EQUIV_SET.
+// Note the internal caller is responible for allocating EQUIV_SET properly.
+
+void
+equiv_oracle::add_equiv_to_block (basic_block bb, bitmap equiv_set)
+{
   equiv_chain *ptr;
 
   // Check if this is the first time a block has an equivalence added.
@@ -786,6 +821,28 @@  relation_oracle::register_stmt (gimple *stmt, relation_kind k, tree op1,
       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     }
 
+  // If an equivalence is being added between a PHI and one of its arguments
+  // make sure that that argument is not defined in the same block.
+  // This can happen along back edges and the equivalence will not be
+  // applicable as it would require a use before def.
+  if (k == EQ_EXPR && is_a<gphi *> (stmt))
+    {
+      tree phi_def = gimple_phi_result (stmt);
+      gcc_checking_assert (phi_def == op1 || phi_def == op2);
+      tree arg = op2;
+      if (phi_def == op2)
+	arg = op1;
+      if (gimple_bb (stmt) == gimple_bb (SSA_NAME_DEF_STMT (arg)))
+	{
+	  if (dump_file && (dump_flags & TDF_DETAILS))
+	    {
+	      fprintf (dump_file, "  Not registered due to ");
+	      print_generic_expr (dump_file, arg, TDF_SLIM);
+	      fprintf (dump_file, " being defined in the same block.\n");
+	    }
+	  return;
+	}
+    }
   register_relation (gimple_bb (stmt), k, op1, op2);
 }
 
diff --git a/gcc/value-relation.h b/gcc/value-relation.h
index 574fdc9efe8..53cefbfa7dc 100644
--- a/gcc/value-relation.h
+++ b/gcc/value-relation.h
@@ -146,7 +146,8 @@  private:
   bitmap register_equiv (basic_block bb, unsigned v, equiv_chain *equiv_1);
   bitmap register_equiv (basic_block bb, equiv_chain *equiv_1,
 			 equiv_chain *equiv_2);
-
+  void register_initial_def (tree ssa);
+  void add_equiv_to_block (basic_block bb, bitmap equiv);
 };
 
 // Summary block header for relations.
-- 
2.17.2