Commit b89ffb98 by Richard Biener Committed by Richard Biener

tree-ssa-sccvn.h (struct vn_nary_op_s): Add next member.

2018-07-20  Richard Biener  <rguenther@suse.de>

	* tree-ssa-sccvn.h (struct vn_nary_op_s): Add next member.
	(struct vn_phi_s): Likewise.
	(struct vn_reference_s): Likewise.
	* tree-ssa-sccvn.c (vn_nary_op_hasher::equal): Add shortcut
	for searching the slot of an entry known to be in the hash itself.
	(vn_phi_hasher::equal): Likewise.
	(vn_reference_hasher::equal): Likewise.
	(last_inserted_ref, last_inserted_phi, last_inserted_nary): New
	globals.
	(optimistic_info, current_info): Remove, keeping only valid_info.
	(vn_reference_lookup_1): Remove fallback lookup.
	(vn_reference_lookup_2): Likewise.
	(vn_nary_op_lookup_1): Likewise.
	(vn_phi_lookup): Likewise.
	(vn_nary_build_or_lookup_1): Make sure to not chain the built
	hash element.
	(vn_reference_insert): Adjust, chain the inserted hash element
	at last_inserted_ref.
	(vn_reference_insert_pieces): Likewise.
	(visit_reference_op_call): Likewise.
	(vn_nary_op_insert_into): Chain the inserted hash element at
	last_inserted_nary.
	(vn_nary_op_insert_pieces): Adjust.
	(vn_nary_op_insert): Likewise.
	(vn_nary_op_insert_stmt): Likewise.
	(vn_phi_insert): Adjust, chain the inserted hash element at
	last_inserted_phi.
	(process_scc): Remove clearing and copying the optimistic
	table.  Instead remove elements inserted during an optimistic
	iteration from the single table we maintain.
	(init_scc_vn): Adjust.
	(free_scc_vn): Likewise.
	(sccvn_dom_walker::record_cond): Likewise.
	(sccvn_dom_walker::after_dom_children): Likewise.

From-SVN: r262899
parent 3b0df776
2018-07-20 Richard Biener <rguenther@suse.de>
* tree-ssa-sccvn.h (struct vn_nary_op_s): Add next member.
(struct vn_phi_s): Likewise.
(struct vn_reference_s): Likewise.
* tree-ssa-sccvn.c (vn_nary_op_hasher::equal): Add shortcut
for searching the slot of an entry known to be in the hash itself.
(vn_phi_hasher::equal): Likewise.
(vn_reference_hasher::equal): Likewise.
(last_inserted_ref, last_inserted_phi, last_inserted_nary): New
globals.
(optimistic_info, current_info): Remove, keeping only valid_info.
(vn_reference_lookup_1): Remove fallback lookup.
(vn_reference_lookup_2): Likewise.
(vn_nary_op_lookup_1): Likewise.
(vn_phi_lookup): Likewise.
(vn_nary_build_or_lookup_1): Make sure to not chain the built
hash element.
(vn_reference_insert): Adjust, chain the inserted hash element
at last_inserted_ref.
(vn_reference_insert_pieces): Likewise.
(visit_reference_op_call): Likewise.
(vn_nary_op_insert_into): Chain the inserted hash element at
last_inserted_nary.
(vn_nary_op_insert_pieces): Adjust.
(vn_nary_op_insert): Likewise.
(vn_nary_op_insert_stmt): Likewise.
(vn_phi_insert): Adjust, chain the inserted hash element at
last_inserted_phi.
(process_scc): Remove clearing and copying the optimistic
table. Instead remove elements inserted during an optimistic
iteration from the single table we maintain.
(init_scc_vn): Adjust.
(free_scc_vn): Likewise.
(sccvn_dom_walker::record_cond): Likewise.
(sccvn_dom_walker::after_dom_children): Likewise.
2018-07-19 Martin Sebor <msebor@redhat.com>
PR tree-optimization/84047
......
......@@ -156,7 +156,7 @@ vn_nary_op_hasher::hash (const vn_nary_op_s *vno1)
inline bool
vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2)
{
return vn_nary_op_eq (vno1, vno2);
return vno1 == vno2 || vn_nary_op_eq (vno1, vno2);
}
typedef hash_table<vn_nary_op_hasher> vn_nary_op_table_type;
......@@ -187,7 +187,7 @@ vn_phi_hasher::hash (const vn_phi_s *vp1)
inline bool
vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2)
{
return vn_phi_eq (vp1, vp2);
return vp1 == vp2 || vn_phi_eq (vp1, vp2);
}
typedef hash_table<vn_phi_hasher> vn_phi_table_type;
......@@ -242,7 +242,7 @@ vn_reference_hasher::hash (const vn_reference_s *vr1)
inline bool
vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c)
{
return vn_reference_eq (v, c);
return v == c || vn_reference_eq (v, c);
}
typedef hash_table<vn_reference_hasher> vn_reference_table_type;
......@@ -295,19 +295,14 @@ static obstack vn_tables_obstack;
/* Special obstack we never unwind. */
static obstack vn_tables_insert_obstack;
static vn_reference_t last_inserted_ref;
static vn_phi_t last_inserted_phi;
static vn_nary_op_t last_inserted_nary;
/* Valid hashtables storing information we have proven to be
correct. */
static vn_tables_t valid_info;
/* Optimistic hashtables storing information we are making assumptions about
during iterations. */
static vn_tables_t optimistic_info;
/* Pointer to the set of hashtables that is currently being used.
Should always point to either the optimistic_info, or the
valid_info. */
static vn_tables_t current_info;
/* Reverse post order index for each basic block. */
static int *rpo_numbers;
......@@ -1548,9 +1543,7 @@ vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
hashval_t hash;
hash = vr->hashcode;
slot = current_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
if (slot)
{
if (vnresult)
......@@ -1589,9 +1582,7 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse,
vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
hash = vr->hashcode;
slot = current_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
if (slot)
return *slot;
......@@ -1735,7 +1726,7 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
optimistic table gets cleared after each iteration).
We do not need to insert into the optimistic table, as
lookups there will fall back to the valid table. */
else if (current_info == optimistic_info)
else
{
unsigned int length = vn_nary_length_from_stmt (new_stmt);
vn_nary_op_t vno1
......@@ -1745,9 +1736,10 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
vno1->result = result;
init_vn_nary_op_from_stmt (vno1, new_stmt);
vn_nary_op_insert_into (vno1, valid_info->nary, true);
/* Also do not link it into the undo chain. */
last_inserted_nary = vno1->next;
vno1->next = (vn_nary_op_t)(void *)-1;
}
else
vn_nary_op_insert_stmt (new_stmt, result);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Inserting name ");
......@@ -2624,7 +2616,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
vr1->result_vdef = vdef;
slot = current_info->references->find_slot_with_hash (vr1, vr1->hashcode,
slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
INSERT);
/* Because we lookup stores using vuses, and value number failures
......@@ -2640,6 +2632,8 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
free_reference (*slot);
*slot = vr1;
vr1->next = last_inserted_ref;
last_inserted_ref = vr1;
return vr1;
}
......@@ -2667,7 +2661,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
result = SSA_VAL (result);
vr1->result = result;
slot = current_info->references->find_slot_with_hash (vr1, vr1->hashcode,
slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
INSERT);
/* At this point we should have all the things inserted that we have
......@@ -2678,6 +2672,8 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
free_reference (*slot);
*slot = vr1;
vr1->next = last_inserted_ref;
last_inserted_ref = vr1;
return vr1;
}
......@@ -2849,10 +2845,7 @@ vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
*vnresult = NULL;
vno->hashcode = vn_nary_op_compute_hash (vno);
slot = current_info->nary->find_slot_with_hash (vno, vno->hashcode,
NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode,
slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode,
NO_INSERT);
if (!slot)
return NULL_TREE;
......@@ -2956,6 +2949,8 @@ vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type *table,
gcc_assert (!*slot);
*slot = vno;
vno->next = last_inserted_nary;
last_inserted_nary = vno;
return vno;
}
......@@ -2970,7 +2965,7 @@ vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
{
vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id);
init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
return vn_nary_op_insert_into (vno1, current_info->nary, true);
return vn_nary_op_insert_into (vno1, valid_info->nary, true);
}
/* Insert OP into the current hash table with a value number of
......@@ -2985,7 +2980,7 @@ vn_nary_op_insert (tree op, tree result)
vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id);
init_vn_nary_op_from_op (vno1, op);
return vn_nary_op_insert_into (vno1, current_info->nary, true);
return vn_nary_op_insert_into (vno1, valid_info->nary, true);
}
/* Insert the rhs of STMT into the current hash table with a value number of
......@@ -2998,7 +2993,7 @@ vn_nary_op_insert_stmt (gimple *stmt, tree result)
= alloc_vn_nary_op (vn_nary_length_from_stmt (stmt),
result, VN_INFO (result)->value_id);
init_vn_nary_op_from_stmt (vno1, stmt);
return vn_nary_op_insert_into (vno1, current_info->nary, true);
return vn_nary_op_insert_into (vno1, valid_info->nary, true);
}
/* Compute a hashcode for PHI operation VP1 and return it. */
......@@ -3206,10 +3201,7 @@ vn_phi_lookup (gimple *phi)
vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
}
vp1->hashcode = vn_phi_compute_hash (vp1);
slot = current_info->phis->find_slot_with_hash (vp1, vp1->hashcode,
NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode,
slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode,
NO_INSERT);
if (!slot)
return NULL_TREE;
......@@ -3253,11 +3245,13 @@ vn_phi_insert (gimple *phi, tree result)
vp1->result = result;
vp1->hashcode = vn_phi_compute_hash (vp1);
slot = current_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT);
slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT);
/* Because we iterate over phi operations more than once, it's
possible the slot might already exist here, hence no assert.*/
*slot = vp1;
vp1->next = last_inserted_phi;
last_inserted_phi = vp1;
return vp1;
}
......@@ -3778,10 +3772,12 @@ visit_reference_op_call (tree lhs, gcall *stmt)
vr2->hashcode = vr1.hashcode;
vr2->result = lhs;
vr2->result_vdef = vdef_val;
slot = current_info->references->find_slot_with_hash (vr2, vr2->hashcode,
slot = valid_info->references->find_slot_with_hash (vr2, vr2->hashcode,
INSERT);
gcc_assert (!*slot);
*slot = vr2;
vr2->next = last_inserted_ref;
last_inserted_ref = vr2;
}
return changed;
......@@ -4312,12 +4308,6 @@ process_scc (vec<tree> scc)
unsigned int i;
unsigned int iterations = 0;
bool changed = true;
vn_nary_op_iterator_type hin;
vn_phi_iterator_type hip;
vn_reference_iterator_type hir;
vn_nary_op_t nary;
vn_phi_t phi;
vn_reference_t ref;
/* If the SCC has a single member, just visit it. */
if (scc.length () == 1)
......@@ -4344,7 +4334,6 @@ process_scc (vec<tree> scc)
/* Iterate over the SCC with the optimistic table until it stops
changing. */
current_info = optimistic_info;
while (changed)
{
changed = false;
......@@ -4354,10 +4343,10 @@ process_scc (vec<tree> scc)
/* As we are value-numbering optimistically we have to
clear the expression tables and the simplified expressions
in each iteration until we converge. */
gcc_assert (optimistic_info->nary->elements () == 0
&& optimistic_info->phis->elements () == 0
&& optimistic_info->references->elements () == 0);
void *ob_top = obstack_alloc (&vn_tables_obstack, 0);
vn_reference_t ref_top = last_inserted_ref;
vn_phi_t phi_top = last_inserted_phi;
vn_nary_op_t nary_top = last_inserted_nary;
FOR_EACH_VEC_ELT (scc, i, var)
gcc_assert (!VN_INFO (var)->needs_insertion
&& VN_INFO (var)->expr == NULL);
......@@ -4365,15 +4354,37 @@ process_scc (vec<tree> scc)
changed |= visit_use (var);
if (changed)
{
optimistic_info->nary->empty ();
optimistic_info->phis->empty ();
FOR_EACH_HASH_TABLE_ELEMENT (*optimistic_info->references,
ref, vn_reference_t, hir)
for (; last_inserted_nary != nary_top;
last_inserted_nary = last_inserted_nary->next)
{
vn_nary_op_t *slot;
slot = valid_info->nary->find_slot_with_hash (last_inserted_nary,
last_inserted_nary->hashcode,
NO_INSERT);
gcc_assert (slot);
valid_info->nary->clear_slot (slot);
}
for (; last_inserted_phi != phi_top;
last_inserted_phi = last_inserted_phi->next)
{
ref->operands.release ();
optimistic_info->references->clear_slot (&*hir);
vn_phi_t *slot;
slot = valid_info->phis->find_slot_with_hash (last_inserted_phi,
last_inserted_phi->hashcode,
NO_INSERT);
gcc_assert (slot);
valid_info->phis->clear_slot (slot);
}
for (; last_inserted_ref != ref_top;
last_inserted_ref = last_inserted_ref->next)
{
vn_reference_t *slot;
slot = valid_info->references->find_slot_with_hash (last_inserted_ref,
last_inserted_ref->hashcode,
NO_INSERT);
gcc_assert (slot);
(*slot)->operands.release ();
valid_info->references->clear_slot (slot);
}
optimistic_info->references->empty ();
obstack_free (&vn_tables_obstack, ob_top);
}
}
......@@ -4381,35 +4392,6 @@ process_scc (vec<tree> scc)
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Processing SCC needed %d iterations\n", iterations);
statistics_histogram_event (cfun, "SCC iterations", iterations);
/* Finally, move the contents of the no longer used optimistic
table to the valid table and clear the optimistic table. */
FOR_EACH_HASH_TABLE_ELEMENT (*optimistic_info->nary, nary, vn_nary_op_t, hin)
{
optimistic_info->nary->clear_slot (&*hin);
vn_nary_op_insert_into (nary, valid_info->nary, false);
}
FOR_EACH_HASH_TABLE_ELEMENT (*optimistic_info->phis, phi, vn_phi_t, hip)
{
optimistic_info->phis->clear_slot (&*hip);
vn_phi_s **slot
= valid_info->phis->find_slot_with_hash (phi, phi->hashcode, INSERT);
gcc_assert (!*slot);
*slot = phi;
}
FOR_EACH_HASH_TABLE_ELEMENT (*optimistic_info->references,
ref, vn_reference_t, hir)
{
optimistic_info->references->clear_slot (&*hir);
vn_reference_s **slot
= valid_info->references->find_slot_with_hash (ref, ref->hashcode,
INSERT);
if (*slot)
free_reference (*slot);
*slot = ref;
}
current_info = valid_info;
}
......@@ -4634,9 +4616,9 @@ init_scc_vn (void)
gcc_obstack_init (&vn_tables_insert_obstack);
valid_info = XCNEW (struct vn_tables_s);
allocate_vn_table (valid_info);
optimistic_info = XCNEW (struct vn_tables_s);
allocate_vn_table (optimistic_info);
current_info = valid_info;
last_inserted_ref = NULL;
last_inserted_phi = NULL;
last_inserted_nary = NULL;
/* Create the VN_INFO structures, and initialize value numbers to
TOP or VARYING for parameters. */
......@@ -4749,8 +4731,6 @@ free_scc_vn (void)
sccstack.release ();
free_vn_table (valid_info);
XDELETE (valid_info);
free_vn_table (optimistic_info);
XDELETE (optimistic_info);
obstack_free (&vn_tables_obstack, NULL);
obstack_free (&vn_tables_insert_obstack, NULL);
......@@ -4824,7 +4804,7 @@ sccvn_dom_walker::record_cond (basic_block bb,
tree ops[2] = { lhs, rhs };
vn_nary_op_t old = NULL;
if (vn_nary_op_lookup_pieces (2, code, boolean_type_node, ops, &old))
current_info->nary->remove_elt_with_hash (old, old->hashcode);
valid_info->nary->remove_elt_with_hash (old, old->hashcode);
vn_nary_op_t cond
= vn_nary_op_insert_pieces (2, code, boolean_type_node, ops,
value
......@@ -4890,9 +4870,9 @@ sccvn_dom_walker::after_dom_children (basic_block bb)
{
vn_nary_op_t cond = cond_stack.last ().second.first;
vn_nary_op_t old = cond_stack.last ().second.second;
current_info->nary->remove_elt_with_hash (cond, cond->hashcode);
valid_info->nary->remove_elt_with_hash (cond, cond->hashcode);
if (old)
vn_nary_op_insert_into (old, current_info->nary, false);
vn_nary_op_insert_into (old, valid_info->nary, false);
cond_stack.pop ();
}
}
......
......@@ -35,6 +35,7 @@ extern tree VN_TOP;
typedef struct vn_nary_op_s
{
vn_nary_op_s *next;
/* Unique identify that all expressions with the same value have. */
unsigned int value_id;
ENUM_BITFIELD(tree_code) opcode : 16;
......@@ -62,6 +63,7 @@ sizeof_vn_nary_op (unsigned int length)
typedef struct vn_phi_s
{
vn_phi_s *next;
/* Unique identifier that all expressions with the same value have. */
unsigned int value_id;
hashval_t hashcode;
......@@ -116,6 +118,7 @@ vn_ref_op_align_unit (vn_reference_op_t op)
typedef struct vn_reference_s
{
vn_reference_s *next;
/* Unique identifier that all expressions with the same value have. */
unsigned int value_id;
hashval_t hashcode;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment