From: Aldy Hernandez Date: Thu, 4 Nov 2021 08:23:24 +0000 (+0100) Subject: Convert arrays in ssa pointer_equiv_analyzer to auto_vec's. X-Git-Tag: basepoints/gcc-13~3422 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb27f5e9ec3c7ab0f5c859d90c59dd4573b53d97;p=thirdparty%2Fgcc.git Convert arrays in ssa pointer_equiv_analyzer to auto_vec's. 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 tree-optimization/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. --- diff --git a/gcc/testsuite/gcc.dg/pr103062.c b/gcc/testsuite/gcc.dg/pr103062.c new file mode 100644 index 000000000000..cbc371b4cd54 --- /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 7d2658b77a49..f07d5d5c7ce7 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> 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 0921579d52a4..dc747d0af70d 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 m_global_points; // Conditional pointer equivalency. class ssa_equiv_stack *m_cond_points; };