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.
This commit is contained in:
Aldy Hernandez 2021-11-04 09:23:24 +01:00
parent a45d577b2b
commit bb27f5e9ec
3 changed files with 41 additions and 15 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
};