From: Richard Biener Date: Thu, 19 Jul 2018 12:19:07 +0000 (+0000) Subject: tree-ssa-sccvn.h (struct vn_phi_s): Make phiargs member a trailing array. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=851fd3661346f314bf33d846bb9b88194523857e;p=gcc.git tree-ssa-sccvn.h (struct vn_phi_s): Make phiargs member a trailing array. 2018-07-19 Richard Biener * tree-ssa-sccvn.h (struct vn_phi_s): Make phiargs member a trailing array. * tree-ssa-sccvn.c: Remove alloc-pool.h use. (vn_phi_hasher): Derive from nofree_ptr_hash and remove remove method. (vn_reference_hasher): Likewise. (struct vn_tables_s): Remove obstack and alloc-pool members. (vn_tables_obstack, vn_tables_insert_obstack): New global obstacks. (vn_nary_build_or_lookup_1): Manually build in vn_tables_insert_obstack. (vn_reference_insert): Allocate from obstack instead of from alloc-pool. (vn_reference_insert_pieces): Likewise. (alloc_vn_nary_op_noinit): Adjust. (vn_nary_op_insert_stmt): Allocate phiargs in-place. (vn_phi_eq): Adjust. (shared_lookup_phiargs): Remove. (vn_phi_lookup): Allocate temporary vn_phi_s on the stack. (vn_phi_insert): Allocate from obstack instead of from alloc-pool. (visit_reference_op_call): Likewise. (copy_nary, copy_phi, copy_reference): Remove. (process_scc): Rewind the obstack when iterating. Do not copy the elements to valid_info but just move them from one hashtable to the other. (allocate_vn_table): Adjust. (free_vn_table): Likewise. (init_scc_vn): Likewise. (free_scc_vn): Likewise. From-SVN: r262879 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78b8d39ab2b..164f1e549a7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2018-07-19 Richard Biener + + * tree-ssa-sccvn.h (struct vn_phi_s): Make phiargs member + a trailing array. + * tree-ssa-sccvn.c: Remove alloc-pool.h use. + (vn_phi_hasher): Derive from nofree_ptr_hash and remove remove method. + (vn_reference_hasher): Likewise. + (struct vn_tables_s): Remove obstack and alloc-pool members. + (vn_tables_obstack, vn_tables_insert_obstack): New global obstacks. + (vn_nary_build_or_lookup_1): Manually build in vn_tables_insert_obstack. + (vn_reference_insert): Allocate from obstack instead of from alloc-pool. + (vn_reference_insert_pieces): Likewise. + (alloc_vn_nary_op_noinit): Adjust. + (vn_nary_op_insert_stmt): Allocate phiargs in-place. + (vn_phi_eq): Adjust. + (shared_lookup_phiargs): Remove. + (vn_phi_lookup): Allocate temporary vn_phi_s on the stack. + (vn_phi_insert): Allocate from obstack instead of from alloc-pool. + (visit_reference_op_call): Likewise. + (copy_nary, copy_phi, copy_reference): Remove. + (process_scc): Rewind the obstack when iterating. Do not + copy the elements to valid_info but just move them from one + hashtable to the other. + (allocate_vn_table): Adjust. + (free_vn_table): Likewise. + (init_scc_vn): Likewise. + (free_scc_vn): Likewise. + 2018-07-19 H.J. Lu PR target/86560 diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 4a2f70293b8..b3ed4d60c70 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -25,7 +25,6 @@ along with GCC; see the file COPYING3. If not see #include "rtl.h" #include "tree.h" #include "gimple.h" -#include "alloc-pool.h" #include "ssa.h" #include "expmed.h" #include "insn-config.h" @@ -169,11 +168,10 @@ typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type; static int vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2); -struct vn_phi_hasher : pointer_hash +struct vn_phi_hasher : nofree_ptr_hash { static inline hashval_t hash (const vn_phi_s *); static inline bool equal (const vn_phi_s *, const vn_phi_s *); - static inline void remove (vn_phi_s *); }; /* Return the computed hashcode for phi operation P1. */ @@ -192,14 +190,6 @@ vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2) return vn_phi_eq (vp1, vp2); } -/* Free a phi operation structure VP. */ - -inline void -vn_phi_hasher::remove (vn_phi_s *phi) -{ - phi->phiargs.release (); -} - typedef hash_table vn_phi_table_type; typedef vn_phi_table_type::iterator vn_phi_iterator_type; @@ -235,11 +225,10 @@ free_reference (vn_reference_s *vr) /* vn_reference hashtable helpers. */ -struct vn_reference_hasher : pointer_hash +struct vn_reference_hasher : nofree_ptr_hash { static inline hashval_t hash (const vn_reference_s *); static inline bool equal (const vn_reference_s *, const vn_reference_s *); - static inline void remove (vn_reference_s *); }; /* Return the hashcode for a given reference operation P1. */ @@ -256,26 +245,17 @@ vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c) return vn_reference_eq (v, c); } -inline void -vn_reference_hasher::remove (vn_reference_s *v) -{ - free_reference (v); -} - typedef hash_table vn_reference_table_type; typedef vn_reference_table_type::iterator vn_reference_iterator_type; -/* The set of hashtables and alloc_pool's for their items. */ +/* The set of VN hashtables. */ typedef struct vn_tables_s { vn_nary_op_table_type *nary; vn_phi_table_type *phis; vn_reference_table_type *references; - struct obstack nary_obstack; - object_allocator *phis_pool; - object_allocator *references_pool; } *vn_tables_t; @@ -310,25 +290,26 @@ static hash_table *constant_to_value_id; static bitmap constant_value_ids; +/* Obstack we allocate the vn-tables elements from. */ +static obstack vn_tables_obstack; +/* Special obstack we never unwind. */ +static obstack vn_tables_insert_obstack; + /* 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; #define SSA_VAL(x) (VN_INFO ((x))->valnum) @@ -1647,7 +1628,12 @@ vn_reference_lookup_or_insert_for_pieces (tree vuse, operands.copy (), value, value_id); } -static vn_nary_op_t vn_nary_op_insert_stmt (gimple *stmt, tree result); +static vn_nary_op_t vn_nary_op_insert_stmt (gimple *, tree); +static unsigned int vn_nary_length_from_stmt (gimple *); +static vn_nary_op_t alloc_vn_nary_op_noinit (unsigned int, obstack *); +static vn_nary_op_t vn_nary_op_insert_into (vn_nary_op_t, + vn_nary_op_table_type *, bool); +static void init_vn_nary_op_from_stmt (vn_nary_op_t, gimple *); /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */ @@ -1751,9 +1737,14 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert) lookups there will fall back to the valid table. */ else if (current_info == optimistic_info) { - current_info = valid_info; - vn_nary_op_insert_stmt (new_stmt, result); - current_info = optimistic_info; + unsigned int length = vn_nary_length_from_stmt (new_stmt); + vn_nary_op_t vno1 + = alloc_vn_nary_op_noinit (length, &vn_tables_insert_obstack); + vno1->value_id = VN_INFO (result)->value_id; + vno1->length = length; + vno1->result = result; + init_vn_nary_op_from_stmt (vno1, new_stmt); + vn_nary_op_insert_into (vno1, valid_info->nary, true); } else vn_nary_op_insert_stmt (new_stmt, result); @@ -2620,7 +2611,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef) vn_reference_t vr1; bool tem; - vr1 = current_info->references_pool->allocate (); + vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s); if (TREE_CODE (result) == SSA_NAME) vr1->value_id = VN_INFO (result)->value_id; else @@ -2665,7 +2656,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type, vn_reference_s **slot; vn_reference_t vr1; - vr1 = current_info->references_pool->allocate (); + vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s); vr1->value_id = value_id; vr1->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE; vr1->operands = valueize_refs (operands); @@ -2931,8 +2922,7 @@ alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack) static vn_nary_op_t alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id) { - vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, - ¤t_info->nary_obstack); + vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, &vn_tables_obstack); vno1->value_id = value_id; vno1->length = length; @@ -3016,8 +3006,8 @@ vn_nary_op_insert_stmt (gimple *stmt, tree result) static inline hashval_t vn_phi_compute_hash (vn_phi_t vp1) { - inchash::hash hstate (vp1->phiargs.length () > 2 - ? vp1->block->index : vp1->phiargs.length ()); + inchash::hash hstate (EDGE_COUNT (vp1->block->preds) > 2 + ? vp1->block->index : EDGE_COUNT (vp1->block->preds)); tree phi1op; tree type; edge e; @@ -3089,10 +3079,10 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2) if (vp1->block != vp2->block) { - if (vp1->phiargs.length () != vp2->phiargs.length ()) + if (EDGE_COUNT (vp1->block->preds) != EDGE_COUNT (vp2->block->preds)) return false; - switch (vp1->phiargs.length ()) + switch (EDGE_COUNT (vp1->block->preds)) { case 1: /* Single-arg PHIs are just copies. */ @@ -3167,10 +3157,9 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2) /* Any phi in the same block will have it's arguments in the same edge order, because of how we store phi nodes. */ - int i; - tree phi1op; - FOR_EACH_VEC_ELT (vp1->phiargs, i, phi1op) + for (unsigned i = 0; i < EDGE_COUNT (vp1->block->preds); ++i) { + tree phi1op = vp1->phiargs[i]; tree phi2op = vp2->phiargs[i]; if (phi1op == VN_TOP || phi2op == VN_TOP) continue; @@ -3181,8 +3170,6 @@ vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2) return true; } -static vec shared_lookup_phiargs; - /* Lookup PHI in the current hash table, and return the resulting value number if it exists in the hash table. Return NULL_TREE if it does not exist in the hash table. */ @@ -3191,38 +3178,38 @@ static tree vn_phi_lookup (gimple *phi) { vn_phi_s **slot; - struct vn_phi_s vp1; + struct vn_phi_s *vp1; edge e; edge_iterator ei; - shared_lookup_phiargs.truncate (0); - shared_lookup_phiargs.safe_grow (gimple_phi_num_args (phi)); + vp1 = XALLOCAVAR (struct vn_phi_s, + sizeof (struct vn_phi_s) + + (gimple_phi_num_args (phi) - 1) * sizeof (tree)); /* Canonicalize the SSA_NAME's to their value number. */ FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) { tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def; - shared_lookup_phiargs[e->dest_idx] = def; + vp1->phiargs[e->dest_idx] = def; } - vp1.type = TREE_TYPE (gimple_phi_result (phi)); - vp1.phiargs = shared_lookup_phiargs; - vp1.block = gimple_bb (phi); + vp1->type = TREE_TYPE (gimple_phi_result (phi)); + vp1->block = gimple_bb (phi); /* Extract values of the controlling condition. */ - vp1.cclhs = NULL_TREE; - vp1.ccrhs = NULL_TREE; - basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1.block); + 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 (last_stmt (idom1))) { - vp1.cclhs = vn_valueize (gimple_cond_lhs (last1)); - vp1.ccrhs = vn_valueize (gimple_cond_rhs (last1)); + vp1->cclhs = vn_valueize (gimple_cond_lhs (last1)); + 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, + 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; @@ -3236,23 +3223,22 @@ static vn_phi_t vn_phi_insert (gimple *phi, tree result) { vn_phi_s **slot; - vn_phi_t vp1 = current_info->phis_pool->allocate (); - vec args = vNULL; + vn_phi_t vp1 = (vn_phi_t) obstack_alloc (&vn_tables_obstack, + sizeof (vn_phi_s) + + ((gimple_phi_num_args (phi) - 1) + * sizeof (tree))); edge e; edge_iterator ei; - args.safe_grow (gimple_phi_num_args (phi)); - /* Canonicalize the SSA_NAME's to their value number. */ FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) { tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def; - args[e->dest_idx] = def; + vp1->phiargs[e->dest_idx] = def; } vp1->value_id = VN_INFO (result)->value_id; vp1->type = TREE_TYPE (gimple_phi_result (phi)); - vp1->phiargs = args; vp1->block = gimple_bb (phi); /* Extract values of the controlling condition. */ vp1->cclhs = NULL_TREE; @@ -3781,7 +3767,7 @@ visit_reference_op_call (tree lhs, gcall *stmt) } if (lhs) changed |= set_ssa_val_to (lhs, lhs); - vr2 = current_info->references_pool->allocate (); + vr2 = XOBNEW (&vn_tables_obstack, vn_reference_s); vr2->vuse = vr1.vuse; /* As we are not walking the virtual operand chain we know the shared_lookup_references are still original so we can re-use @@ -4317,48 +4303,6 @@ sort_scc (vec scc) scc.qsort (compare_ops); } -/* Insert the no longer used nary ONARY to the hash INFO. */ - -static void -copy_nary (vn_nary_op_t onary, vn_tables_t info) -{ - size_t size = sizeof_vn_nary_op (onary->length); - vn_nary_op_t nary = alloc_vn_nary_op_noinit (onary->length, - &info->nary_obstack); - memcpy (nary, onary, size); - vn_nary_op_insert_into (nary, info->nary, false); -} - -/* Insert the no longer used phi OPHI to the hash INFO. */ - -static void -copy_phi (vn_phi_t ophi, vn_tables_t info) -{ - vn_phi_t phi = info->phis_pool->allocate (); - vn_phi_s **slot; - memcpy (phi, ophi, sizeof (*phi)); - ophi->phiargs.create (0); - slot = info->phis->find_slot_with_hash (phi, phi->hashcode, INSERT); - gcc_assert (!*slot); - *slot = phi; -} - -/* Insert the no longer used reference OREF to the hash INFO. */ - -static void -copy_reference (vn_reference_t oref, vn_tables_t info) -{ - vn_reference_t ref; - vn_reference_s **slot; - ref = info->references_pool->allocate (); - memcpy (ref, oref, sizeof (*ref)); - oref->operands.create (0); - slot = info->references->find_slot_with_hash (ref, ref->hashcode, INSERT); - if (*slot) - free_reference (*slot); - *slot = ref; -} - /* Process a strongly connected component in the SSA graph. */ static void @@ -4410,33 +4354,60 @@ process_scc (vec scc) /* As we are value-numbering optimistically we have to clear the expression tables and the simplified expressions in each iteration until we converge. */ - optimistic_info->nary->empty (); - optimistic_info->phis->empty (); - optimistic_info->references->empty (); - obstack_free (&optimistic_info->nary_obstack, NULL); - gcc_obstack_init (&optimistic_info->nary_obstack); - optimistic_info->phis_pool->release (); - optimistic_info->references_pool->release (); + 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); FOR_EACH_VEC_ELT (scc, i, var) gcc_assert (!VN_INFO (var)->needs_insertion && VN_INFO (var)->expr == NULL); FOR_EACH_VEC_ELT (scc, i, var) 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) + { + ref->operands.release (); + optimistic_info->references->clear_slot (&*hir); + } + optimistic_info->references->empty (); + obstack_free (&vn_tables_obstack, ob_top); + } } 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, copy the contents of the no longer used optimistic - table to the valid table. */ + /* 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) - copy_nary (nary, valid_info); + { + 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) - copy_phi (phi, valid_info); + { + 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) - copy_reference (ref, valid_info); + { + 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; } @@ -4596,11 +4567,6 @@ allocate_vn_table (vn_tables_t table) table->phis = new vn_phi_table_type (23); table->nary = new vn_nary_op_table_type (23); table->references = new vn_reference_table_type (23); - - gcc_obstack_init (&table->nary_obstack); - table->phis_pool = new object_allocator ("VN phis"); - table->references_pool = new object_allocator - ("VN references"); } /* Free a value number table. */ @@ -4608,15 +4574,17 @@ allocate_vn_table (vn_tables_t table) static void free_vn_table (vn_tables_t table) { + /* Walk over elements and release vectors. */ + vn_reference_iterator_type hir; + vn_reference_t vr; + FOR_EACH_HASH_TABLE_ELEMENT (*table->references, vr, vn_reference_t, hir) + vr->operands.release (); delete table->phis; table->phis = NULL; delete table->nary; table->nary = NULL; delete table->references; table->references = NULL; - obstack_free (&table->nary_obstack, NULL); - delete table->phis_pool; - delete table->references_pool; } static void @@ -4642,7 +4610,6 @@ init_scc_vn (void) vn_ssa_aux_table.safe_grow_cleared (num_ssa_names + 1); gcc_obstack_init (&vn_ssa_aux_obstack); - shared_lookup_phiargs.create (0); shared_lookup_references.create (0); rpo_numbers = XNEWVEC (int, last_basic_block_for_fn (cfun)); rpo_numbers_temp = @@ -4663,6 +4630,8 @@ init_scc_vn (void) renumber_gimple_stmt_uids (); /* Create the valid and optimistic value numbering tables. */ + gcc_obstack_init (&vn_tables_obstack); + 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); @@ -4765,7 +4734,6 @@ free_scc_vn (void) delete constant_to_value_id; constant_to_value_id = NULL; BITMAP_FREE (constant_value_ids); - shared_lookup_phiargs.release (); shared_lookup_references.release (); XDELETEVEC (rpo_numbers); @@ -4783,6 +4751,8 @@ free_scc_vn (void) XDELETE (valid_info); free_vn_table (optimistic_info); XDELETE (optimistic_info); + obstack_free (&vn_tables_obstack, NULL); + obstack_free (&vn_tables_insert_obstack, NULL); BITMAP_FREE (const_parms); } diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 5857cfc1c8a..4a3bdae5c8a 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -65,13 +65,14 @@ typedef struct vn_phi_s /* Unique identifier that all expressions with the same value have. */ unsigned int value_id; hashval_t hashcode; - vec phiargs; basic_block block; /* Controlling condition lhs/rhs. */ tree cclhs; tree ccrhs; tree type; tree result; + /* The number of args is determined by EDGE_COUT (block->preds). */ + tree phiargs[1]; } *vn_phi_t; typedef const struct vn_phi_s *const_vn_phi_t;