[COMMITTED] Convert arrays in ssa pointer_equiv_analyzer to auto_vec's.

Aldy Hernandez aldyh@redhat.com
Thu Nov 4 10:47:14 GMT 2021


The problem in this PR is an off-by-one bug.  We should've allocated
num_ssa_names + 1.  However, in fixing this, I noticed that
num_ssa_names can change between queries, so I have replaced the array
with an auto_vec and added code to grow the vector as necessary.

Tested on x86-64 Linux.

	PR 103062

gcc/ChangeLog:

	PR tree-optimization/103062
	* value-pointer-equiv.cc (ssa_equiv_stack::ssa_equiv_stack):
	Increase size of allocation by 1.
	(ssa_equiv_stack::push_replacement): Grow as needed.
	(ssa_equiv_stack::get_replacement): Same.
	(pointer_equiv_analyzer::pointer_equiv_analyzer): Same.
	(pointer_equiv_analyzer::~pointer_equiv_analyzer): Remove delete.
	(pointer_equiv_analyzer::set_global_equiv): Grow as needed.
	(pointer_equiv_analyzer::get_equiv): Same.
	(pointer_equiv_analyzer::get_equiv_expr): Remove const.
	* value-pointer-equiv.h (class pointer_equiv_analyzer): Remove
	const markers.  Use auto_vec instead of tree *.

gcc/testsuite/ChangeLog:

	* gcc.dg/pr103062.c: New test.
---
 gcc/testsuite/gcc.dg/pr103062.c |  7 ++++++
 gcc/value-pointer-equiv.cc      | 43 ++++++++++++++++++++++++---------
 gcc/value-pointer-equiv.h       |  6 ++---
 3 files changed, 41 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr103062.c

diff --git a/gcc/testsuite/gcc.dg/pr103062.c b/gcc/testsuite/gcc.dg/pr103062.c
new file mode 100644
index 00000000000..cbc371b4cd5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr103062.c
@@ -0,0 +1,7 @@
+// { dg-do compile }
+// { dg-options "-O2 -fno-tree-forwprop" }
+
+void *a, *b, *c;
+void foo(void) {
+  c = (void *)((__INTPTR_TYPE__)a & (__INTPTR_TYPE__)b);
+}
diff --git a/gcc/value-pointer-equiv.cc b/gcc/value-pointer-equiv.cc
index 7d2658b77a4..f07d5d5c7ce 100644
--- a/gcc/value-pointer-equiv.cc
+++ b/gcc/value-pointer-equiv.cc
@@ -58,7 +58,7 @@ public:
   void enter (basic_block);
   void leave (basic_block);
   void push_replacement (tree name, tree replacement);
-  tree get_replacement (tree name) const;
+  tree get_replacement (tree name);
 
 private:
   auto_vec<std::pair <tree, tree>> m_stack;
@@ -68,7 +68,7 @@ private:
 
 ssa_equiv_stack::ssa_equiv_stack ()
 {
-  m_replacements.safe_grow_cleared (num_ssa_names);
+  m_replacements.safe_grow_cleared (num_ssa_names + 1);
 }
 
 // Pushes a marker at the given point.
@@ -99,29 +99,38 @@ ssa_equiv_stack::leave (basic_block)
 void
 ssa_equiv_stack::push_replacement (tree name, tree replacement)
 {
-  tree old = m_replacements[SSA_NAME_VERSION (name)];
-  m_replacements[SSA_NAME_VERSION (name)] = replacement;
+  unsigned v = SSA_NAME_VERSION (name);
+
+  if (v >= m_replacements.length ())
+    m_replacements.safe_grow_cleared (num_ssa_names + 1);
+
+  tree old = m_replacements[v];
+  m_replacements[v] = replacement;
   m_stack.safe_push (std::make_pair (name, old));
 }
 
 // Return the equivalence of NAME.
 
 tree
-ssa_equiv_stack::get_replacement (tree name) const
+ssa_equiv_stack::get_replacement (tree name)
 {
-  return m_replacements[SSA_NAME_VERSION (name)];
+  unsigned v = SSA_NAME_VERSION (name);
+
+  if (v >= m_replacements.length ())
+    m_replacements.safe_grow_cleared (num_ssa_names + 1);
+
+  return m_replacements[v];
 }
 
 pointer_equiv_analyzer::pointer_equiv_analyzer (gimple_ranger *r)
 {
   m_ranger = r;
-  m_global_points = new tree[num_ssa_names] ();
+  m_global_points.safe_grow_cleared (num_ssa_names + 1);
   m_cond_points = new ssa_equiv_stack;
 }
 
 pointer_equiv_analyzer::~pointer_equiv_analyzer ()
 {
-  delete[] m_global_points;
   delete m_cond_points;
 }
 
@@ -130,7 +139,12 @@ pointer_equiv_analyzer::~pointer_equiv_analyzer ()
 void
 pointer_equiv_analyzer::set_global_equiv (tree ssa, tree pointee)
 {
-  m_global_points[SSA_NAME_VERSION (ssa)] = pointee;
+  unsigned v = SSA_NAME_VERSION (ssa);
+
+  if (v >= m_global_points.length ())
+    m_global_points.safe_grow_cleared (num_ssa_names + 1);
+
+  m_global_points[v] = pointee;
 }
 
 // Set the conditional pointer equivalency for SSA to POINTEE.
@@ -146,9 +160,14 @@ pointer_equiv_analyzer::set_cond_equiv (tree ssa, tree pointee)
 // conditional info.
 
 tree
-pointer_equiv_analyzer::get_equiv (tree ssa) const
+pointer_equiv_analyzer::get_equiv (tree ssa)
 {
-  tree ret = m_global_points[SSA_NAME_VERSION (ssa)];
+  unsigned v = SSA_NAME_VERSION (ssa);
+
+  if (v >= m_global_points.length ())
+    m_global_points.safe_grow_cleared (num_ssa_names + 1);
+
+  tree ret = m_global_points[v];
   if (ret)
     return ret;
   return m_cond_points->get_replacement (ssa);
@@ -211,7 +230,7 @@ pointer_equiv_analyzer::leave (basic_block bb)
 // nor an invariant.
 
 tree
-pointer_equiv_analyzer::get_equiv_expr (tree_code code, tree expr) const
+pointer_equiv_analyzer::get_equiv_expr (tree_code code, tree expr)
 {
   if (code == SSA_NAME)
     return get_equiv (expr);
diff --git a/gcc/value-pointer-equiv.h b/gcc/value-pointer-equiv.h
index 0921579d52a..dc747d0af70 100644
--- a/gcc/value-pointer-equiv.h
+++ b/gcc/value-pointer-equiv.h
@@ -38,17 +38,17 @@ public:
   void enter (basic_block);
   void leave (basic_block);
   void visit_stmt (gimple *stmt);
-  tree get_equiv (tree ssa) const;
+  tree get_equiv (tree ssa);
 
 private:
   void visit_edge (edge e);
-  tree get_equiv_expr (tree_code code, tree expr) const;
+  tree get_equiv_expr (tree_code code, tree expr);
   void set_global_equiv (tree ssa, tree pointee);
   void set_cond_equiv (tree ssa, tree pointee);
 
   gimple_ranger *m_ranger;
   // Global pointer equivalency indexed by SSA_NAME_VERSION.
-  tree *m_global_points;
+  auto_vec<tree> m_global_points;
   // Conditional pointer equivalency.
   class ssa_equiv_stack *m_cond_points;
 };
-- 
2.31.1



More information about the Gcc-patches mailing list