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:
parent
a45d577b2b
commit
bb27f5e9ec
3 changed files with 41 additions and 15 deletions
7
gcc/testsuite/gcc.dg/pr103062.c
Normal file
7
gcc/testsuite/gcc.dg/pr103062.c
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue