aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-02-14 14:51:48 +0100
committerRichard Biener <rguenther@suse.de>2023-02-14 16:18:57 +0100
commite72c2770b6d913c82a56d45a306c4cb2ed88fba5 (patch)
tree064d8ce01b29c10c8d578295c2a58e4210a60f6b
parent1434eee54e57ad4839c0697f1294f9e8fe0a3044 (diff)
downloadgcc-e72c2770b6d913c82a56d45a306c4cb2ed88fba5.zip
gcc-e72c2770b6d913c82a56d45a306c4cb2ed88fba5.tar.gz
gcc-e72c2770b6d913c82a56d45a306c4cb2ed88fba5.tar.bz2
Improve VN PHI hash table handling
The hash function of PHIs is weak since we want to be able to CSE them even across basic-blocks in some cases. The following avoids weakening the hash for cases we are never going to CSE, reducing the number of collisions and avoiding redundant work in the hash and equality functions. * tree-ssa-sccvn.cc (vn_phi_compute_hash): Key skipping basic block index hashing on the availability of ->cclhs. (vn_phi_eq): Avoid re-doing sanity checks for CSE but rely on ->cclhs availability. (vn_phi_lookup): Set ->cclhs only when we are eventually going to CSE the PHI. (vn_phi_insert): Likewise.
-rw-r--r--gcc/tree-ssa-sccvn.cc77
1 files changed, 43 insertions, 34 deletions
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index e5bb278..8ee77fd 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -4629,9 +4629,9 @@ vn_phi_compute_hash (vn_phi_t vp1)
case 1:
break;
case 2:
- if (vp1->block->loop_father->header == vp1->block)
- ;
- else
+ /* When this is a PHI node subject to CSE for different blocks
+ avoid hashing the block index. */
+ if (vp1->cclhs)
break;
/* Fallthru. */
default:
@@ -4715,32 +4715,33 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
case 2:
{
- /* Rule out backedges into the PHI. */
- if (vp1->block->loop_father->header == vp1->block
- || vp2->block->loop_father->header == vp2->block)
+ /* Make sure both PHIs are classified as CSEable. */
+ if (! vp1->cclhs || ! vp2->cclhs)
return false;
+ /* Rule out backedges into the PHI. */
+ gcc_checking_assert
+ (vp1->block->loop_father->header != vp1->block
+ && vp2->block->loop_father->header != vp2->block);
+
/* If the PHI nodes do not have compatible types
they are not the same. */
if (!types_compatible_p (vp1->type, vp2->type))
return false;
+ /* If the immediate dominator end in switch stmts multiple
+ values may end up in the same PHI arg via intermediate
+ CFG merges. */
basic_block idom1
= get_immediate_dominator (CDI_DOMINATORS, vp1->block);
basic_block idom2
= get_immediate_dominator (CDI_DOMINATORS, vp2->block);
- /* If the immediate dominator end in switch stmts multiple
- values may end up in the same PHI arg via intermediate
- CFG merges. */
- if (EDGE_COUNT (idom1->succs) != 2
- || EDGE_COUNT (idom2->succs) != 2)
- return false;
+ gcc_checking_assert (EDGE_COUNT (idom1->succs) == 2
+ && EDGE_COUNT (idom2->succs) == 2);
/* Verify the controlling stmt is the same. */
- gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1));
- gcond *last2 = safe_dyn_cast <gcond *> (last_stmt (idom2));
- if (! last1 || ! last2)
- return false;
+ gcond *last1 = as_a <gcond *> (last_stmt (idom1));
+ gcond *last2 = as_a <gcond *> (last_stmt (idom2));
bool inverted_p;
if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
last2, vp2->cclhs, vp2->ccrhs,
@@ -4835,15 +4836,19 @@ vn_phi_lookup (gimple *phi, bool backedges_varying_p)
/* Extract values of the controlling condition. */
vp1->cclhs = NULL_TREE;
vp1->ccrhs = NULL_TREE;
- basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
- if (EDGE_COUNT (idom1->succs) == 2)
- if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
- {
- /* ??? We want to use SSA_VAL here. But possibly not
- allow VN_TOP. */
- vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
- vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
- }
+ if (EDGE_COUNT (vp1->block->preds) == 2
+ && vp1->block->loop_father->header != vp1->block)
+ {
+ basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
+ if (EDGE_COUNT (idom1->succs) == 2)
+ if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
+ {
+ /* ??? We want to use SSA_VAL here. But possibly not
+ allow VN_TOP. */
+ vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
+ vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
+ }
+ }
vp1->hashcode = vn_phi_compute_hash (vp1);
slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, NO_INSERT);
if (!slot)
@@ -4885,15 +4890,19 @@ vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p)
/* Extract values of the controlling condition. */
vp1->cclhs = NULL_TREE;
vp1->ccrhs = NULL_TREE;
- basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
- if (EDGE_COUNT (idom1->succs) == 2)
- if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
- {
- /* ??? We want to use SSA_VAL here. But possibly not
- allow VN_TOP. */
- vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
- vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
- }
+ if (EDGE_COUNT (vp1->block->preds) == 2
+ && vp1->block->loop_father->header != vp1->block)
+ {
+ basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
+ if (EDGE_COUNT (idom1->succs) == 2)
+ if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
+ {
+ /* ??? We want to use SSA_VAL here. But possibly not
+ allow VN_TOP. */
+ vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
+ vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
+ }
+ }
vp1->result = result;
vp1->hashcode = vn_phi_compute_hash (vp1);