From patchwork Fri Dec 14 04:08:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lawrence Crowl X-Patchwork-Id: 206287 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 5979F2C0089 for ; Fri, 14 Dec 2012 15:09:00 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1356062942; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Cc:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=47/6hMa s5Ijgg/m8FANEr5H/lFk=; b=nhLfXR+uKj74OPfrFzDpzL8ebD5NYZGEWjtusk/ wtBMXUsLuzTJsNw7RxhT992BmwGTQGHfL8uqVxhzOSZnu23yVK4YuDf3f0vRSDbY +f8nJzj+UI+NT1AAtQF3E5B084eUl5gbSCYlvj6ax3MF31QQTYS/O8bhwv0ZTcM/ +K74= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Google-DKIM-Signature:MIME-Version:Received:Received:Date:Message-ID:Subject:From:To:Cc:Content-Type:X-Gm-Message-State:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=LL1RIQ6X3apRoa7nSEiOmEQcyd0wjQVZlt48W+FHWm9W9dQJMu6jbmikDxLfay OSImQ5U7uZvUSgq1CZInGBM3uFVmZ5Pni65IxdlSLztn8sQo2398uHixv9Tjs6VL U3vM0Eqabfflf0fam8nTk4gZw/+G41kyO+RrFBJO977/o=; Received: (qmail 2851 invoked by alias); 14 Dec 2012 04:08:56 -0000 Received: (qmail 2825 invoked by uid 22791); 14 Dec 2012 04:08:55 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=AWL, BAYES_40, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, KAM_STOCKTIP, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD, TW_CP, TW_DF, TW_DV, TW_TM, TW_VC, TW_XT X-Spam-Check-By: sourceware.org Received: from mail-ie0-f175.google.com (HELO mail-ie0-f175.google.com) (209.85.223.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 14 Dec 2012 04:08:37 +0000 Received: by mail-ie0-f175.google.com with SMTP id qd14so5061123ieb.20 for ; Thu, 13 Dec 2012 20:08:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type :x-gm-message-state; bh=6JHCyDeotJdJ62lrs/yb7mW0s3bN/fI1+pKClU4xR+M=; b=QMJBTeVz4pRR2hVIjKQjgEqet9kmG9OnkQBXSHpDCBYO3nr6hW5BKC94hGiSNzNUxA PGQMNegKA/skMgnnWvXldAQqkv2UbJSUgXZZPc2idBlJa5g4WL/ccU7N24lHbqbbi4OF JNP2k40tAr0bXxWEx+Ny3xIRoVaf53erhA5T7PDWE3qSqHMByWdYZsuRClpqpb8+Cqeu 13IxplgjxDeNj8Y8/DclLQg9wqyAwc9siL70qerI5cFueRw65m+l9pdle8UgQlSriZQ/ t6MH8ZIxuAHmNOFKGm+5UBCFekXCaID451RHsG0dCUSUV01JRTs9+piAJO/mXJy/mhqu Awpw== MIME-Version: 1.0 Received: by 10.50.12.165 with SMTP id z5mr486621igb.17.1355458117071; Thu, 13 Dec 2012 20:08:37 -0800 (PST) Received: by 10.231.108.73 with HTTP; Thu, 13 Dec 2012 20:08:36 -0800 (PST) Date: Thu, 13 Dec 2012 20:08:36 -0800 Message-ID: Subject: [cxx-conversion] Iterator for hash_table, and associated conversions From: Lawrence Crowl To: gcc-patches List Cc: Diego Novillo X-Gm-Message-State: ALoCoQlkOsFE+FI9udd5hHF7BTUJhbX4Qvmm7QtieYQ8gCulueW9HZFLgQAsBP5e/e2g56O37uiUxIrDpZiYpKJmPMSAX1EYiRvlrcym4+ov6FCjvyHIHprRANQNlyWWzh54uUa91DrUYPMXhsfXN87iP2Ujz1mFvTMT9lGtu7Jbm61JRxoUjpMAymrL4+lYWvTbqsGWBIW3 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Add standard-style iterators to hash_table. Implement gcc-style FOR_EACH on top of those iterators. * hash-table.h'hash_table Add documentation. Add nested class iterator and methods to hash_table. Add FOR_EACH_HASH_TABLE_ELEMENT implemented with those iterators. Convert several uses of htab_t to use hash_table. Adjust types and calls to match. These files also use the iterators. Change uses of FOR_EACH_HTAB_ELEMENT to FOR_EACH_HASH_TABLE_ELEMENT. * tree-ssa-sccvn.c'vn_tables_s.nary Fold vn_nary_op_hash, vn_nary_op_eq into new struct vn_nary_op_hasher. Add typedef vn_nary_op_table_type. Add typedef vn_nary_op_iterator_type. * tree-ssa-sccvn.c'vn_tables_s.phis Fold vn_phi_hash, free_phi into new struct vn_phi_hasher. Add typedef vn_phi_table_type. Add typedef vn_phi_iterator_type. * tree-ssa-sccvn.c'vn_tables_s.references Fold vn_reference_hash, vn_reference_op_eq, free_reference into new struct vn_reference_hasher. Add typedef vn_reference_table_type. Add typedef vn_reference_iterator_type. * tree-ssa-sccvn.c'constant_value_ids Fold vn_constant_hash, vn_constant_eq into new struct vn_constant_hasher. * tree-into-ssa.c'var_infos Fold var_info_hash, var_info_eq into new struct var_info_hasher. * var-tracking.c'emit_note_data_def.vars * var-tracking.c'shared_hash_def.htab * var-tracking.c'changed_variables Fold variable_htab_hash, variable_htab_eq, variable_htab_free into new struct variable_hasher. Add typedef variable_table_type. Add typedef variable_iterator_type. * trans-mem.c'tm_log Fold tm_log_hash, tm_log_eq, tm_log_free into new struct log_entry_hasher. * trans-mem.c'tm_memopt_value_numbers Fold tm_memop_hash, tm_memop_eq into new struct tm_memop_hasher. Tested on x86-64. Okay for branch? Index: gcc/tree-into-ssa.c =================================================================== --- gcc/tree-into-ssa.c (revision 194487) +++ gcc/tree-into-ssa.c (working copy) @@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. #include "tree-flow.h" #include "gimple.h" #include "tree-inline.h" -#include "hashtab.h" +#include "hash-table.h" #include "tree-pass.h" #include "cfgloop.h" #include "domwalk.h" @@ -161,9 +161,32 @@ struct var_info_d typedef struct var_info_d *var_info_p; +/* VAR_INFOS hashtable helpers. */ + +struct var_info_hasher : typed_free_remove +{ + typedef var_info_d value_type; + typedef var_info_d compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +var_info_hasher::hash (const value_type *p) +{ + return DECL_UID (p->var); +} + +inline bool +var_info_hasher::equal (const value_type *p1, const compare_type *p2) +{ + return p1->var == p2->var; +} + + /* Each entry in VAR_INFOS contains an element of type STRUCT VAR_INFO_D. */ -static htab_t var_infos; +static hash_table var_infos; /* Information stored for SSA names. */ @@ -341,17 +364,17 @@ static inline var_info_p get_var_info (tree decl) { struct var_info_d vi; - void **slot; + var_info_d **slot; vi.var = decl; - slot = htab_find_slot_with_hash (var_infos, &vi, DECL_UID (decl), INSERT); + slot = var_infos.find_slot_with_hash (&vi, DECL_UID (decl), INSERT); if (*slot == NULL) { var_info_p v = XCNEW (struct var_info_d); v->var = decl; - *slot = (void *)v; + *slot = v; return v; } - return (var_info_p) *slot; + return *slot; } @@ -1039,15 +1062,15 @@ insert_phi_nodes_compare_var_infos (cons static void insert_phi_nodes (bitmap_head *dfs) { - htab_iterator hi; + hash_table ::iterator hi; unsigned i; var_info_p info; vec vars; timevar_push (TV_TREE_INSERT_PHI_NODES); - vars.create (htab_elements (var_infos)); - FOR_EACH_HTAB_ELEMENT (var_infos, info, var_info_p, hi) + vars.create (var_infos.elements ()); + FOR_EACH_HASH_TABLE_ELEMENT (var_infos, info, var_info_p, hi) if (info->info.need_phi_state != NEED_PHI_STATE_NO) vars.quick_push (info); @@ -1622,12 +1645,12 @@ debug_tree_ssa (void) /* Dump statistics for the hash table HTAB. */ static void -htab_statistics (FILE *file, htab_t htab) +htab_statistics (FILE *file, hash_table htab) { fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n", - (long) htab_size (htab), - (long) htab_elements (htab), - htab_collisions (htab)); + (long) htab.size (), + (long) htab.elements (), + htab.collisions ()); } @@ -1636,7 +1659,7 @@ htab_statistics (FILE *file, htab_t htab void dump_tree_ssa_stats (FILE *file) { - if (var_infos) + if (var_infos.is_created ()) { fprintf (file, "\nHash table statistics:\n"); fprintf (file, " var_infos: "); @@ -1655,29 +1678,12 @@ debug_tree_ssa_stats (void) } -/* Hashing and equality functions for VAR_INFOS. */ - -static hashval_t -var_info_hash (const void *p) -{ - return DECL_UID (((const struct var_info_d *)p)->var); -} - -static int -var_info_eq (const void *p1, const void *p2) -{ - return ((const struct var_info_d *)p1)->var - == ((const struct var_info_d *)p2)->var; -} - - /* Callback for htab_traverse to dump the VAR_INFOS hash table. */ -static int -debug_var_infos_r (void **slot, void *data) +int +debug_var_infos_r (var_info_d **slot, FILE *file) { - FILE *file = (FILE *) data; - struct var_info_d *info = (struct var_info_d *) *slot; + struct var_info_d *info = *slot; fprintf (file, "VAR: "); print_generic_expr (file, info->var, dump_flags); @@ -1698,8 +1704,8 @@ void dump_var_infos (FILE *file) { fprintf (file, "\n\nDefinition and live-in blocks:\n\n"); - if (var_infos) - htab_traverse (var_infos, debug_var_infos_r, file); + if (var_infos.is_created ()) + var_infos.traverse (file); } @@ -2200,7 +2206,7 @@ rewrite_blocks (basic_block entry, enum if (dump_file && (dump_flags & TDF_STATS)) { dump_dfa_stats (dump_file); - if (var_infos) + if (var_infos.is_created ()) dump_tree_ssa_stats (dump_file); } @@ -2280,9 +2286,8 @@ init_ssa_renamer (void) cfun->gimple_df->in_ssa_p = false; /* Allocate memory for the DEF_BLOCKS hash table. */ - gcc_assert (var_infos == NULL); - var_infos = htab_create (vec_safe_length (cfun->local_decls), - var_info_hash, var_info_eq, free); + gcc_assert (!var_infos.is_created ()); + var_infos.create (vec_safe_length (cfun->local_decls)); bitmap_obstack_initialize (&update_ssa_obstack); } @@ -2293,11 +2298,8 @@ init_ssa_renamer (void) static void fini_ssa_renamer (void) { - if (var_infos) - { - htab_delete (var_infos); - var_infos = NULL; - } + if (var_infos.is_created ()) + var_infos.dispose (); bitmap_obstack_release (&update_ssa_obstack); @@ -3162,7 +3164,7 @@ update_ssa (unsigned update_flags) { /* If we rename bare symbols initialize the mapping to auxiliar info we need to keep track of. */ - var_infos = htab_create (47, var_info_hash, var_info_eq, free); + var_infos.create (47); /* If we have to rename some symbols from scratch, we need to start the process at the root of the CFG. FIXME, it should Index: gcc/var-tracking.c =================================================================== --- gcc/var-tracking.c (revision 194487) +++ gcc/var-tracking.c (working copy) @@ -101,7 +101,7 @@ #include "sbitmap.h" #include "alloc-pool.h" #include "fibheap.h" -#include "hashtab.h" +#include "hash-table.h" #include "regs.h" #include "expr.h" #include "tree-pass.h" @@ -197,19 +197,43 @@ typedef struct micro_operation_def declaration. */ typedef void *decl_or_value; -/* Structure for passing some other parameters to function - emit_note_insn_var_location. */ -typedef struct emit_note_data_def +/* Return true if a decl_or_value DV is a DECL or NULL. */ +static inline bool +dv_is_decl_p (decl_or_value dv) { - /* The instruction which the note will be emitted before/after. */ - rtx insn; + return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE; +} - /* Where the note will be emitted (before/after insn)? */ - enum emit_note_where where; +/* Return true if a decl_or_value is a VALUE rtl. */ +static inline bool +dv_is_value_p (decl_or_value dv) +{ + return dv && !dv_is_decl_p (dv); +} + +/* Return the decl in the decl_or_value. */ +static inline tree +dv_as_decl (decl_or_value dv) +{ + gcc_checking_assert (dv_is_decl_p (dv)); + return (tree) dv; +} + +/* Return the value in the decl_or_value. */ +static inline rtx +dv_as_value (decl_or_value dv) +{ + gcc_checking_assert (dv_is_value_p (dv)); + return (rtx)dv; +} + +/* Return the opaque pointer in the decl_or_value. */ +static inline void * +dv_as_opaque (decl_or_value dv) +{ + return dv; +} - /* The variables and values active at this point. */ - htab_t vars; -} emit_note_data; /* Description of location of a part of a variable. The content of a physical register is described by a chain of these structures. @@ -230,58 +254,6 @@ typedef struct attrs_def HOST_WIDE_INT offset; } *attrs; -/* Structure holding a refcounted hash table. If refcount > 1, - it must be first unshared before modified. */ -typedef struct shared_hash_def -{ - /* Reference count. */ - int refcount; - - /* Actual hash table. */ - htab_t htab; -} *shared_hash; - -/* Structure holding the IN or OUT set for a basic block. */ -typedef struct dataflow_set_def -{ - /* Adjustment of stack offset. */ - HOST_WIDE_INT stack_adjust; - - /* Attributes for registers (lists of attrs). */ - attrs regs[FIRST_PSEUDO_REGISTER]; - - /* Variable locations. */ - shared_hash vars; - - /* Vars that is being traversed. */ - shared_hash traversed_vars; -} dataflow_set; - -/* The structure (one for each basic block) containing the information - needed for variable tracking. */ -typedef struct variable_tracking_info_def -{ - /* The vector of micro operations. */ - vec mos; - - /* The IN and OUT set for dataflow analysis. */ - dataflow_set in; - dataflow_set out; - - /* The permanent-in dataflow set for this block. This is used to - hold values for which we had to compute entry values. ??? This - should probably be dynamically allocated, to avoid using more - memory in non-debug builds. */ - dataflow_set *permp; - - /* Has the block been visited in DFS? */ - bool visited; - - /* Has the block been flooded in VTA? */ - bool flooded; - -} *variable_tracking_info; - /* Structure for chaining the locations. */ typedef struct location_chain_def { @@ -455,6 +427,146 @@ typedef const struct variable_def *const ? &VAR_LOC_1PAUX (var)->deps \ : NULL) + + +typedef unsigned int dvuid; + +/* Return the uid of DV. */ + +static inline dvuid +dv_uid (decl_or_value dv) +{ + if (dv_is_value_p (dv)) + return CSELIB_VAL_PTR (dv_as_value (dv))->uid; + else + return DECL_UID (dv_as_decl (dv)); +} + +/* Compute the hash from the uid. */ + +static inline hashval_t +dv_uid2hash (dvuid uid) +{ + return uid; +} + +/* The hash function for a mask table in a shared_htab chain. */ + +static inline hashval_t +dv_htab_hash (decl_or_value dv) +{ + return dv_uid2hash (dv_uid (dv)); +} + +static void variable_htab_free (void *); + +/* Variable hashtable helpers. */ + +struct variable_hasher +{ + typedef variable_def value_type; + typedef void compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; + +/* The hash function for variable_htab, computes the hash value + from the declaration of variable X. */ + +inline hashval_t +variable_hasher::hash (const value_type *v) +{ + return dv_htab_hash (v->dv); +} + +/* Compare the declaration of variable X with declaration Y. */ + +inline bool +variable_hasher::equal (const value_type *v, const compare_type *y) +{ + decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y); + + return (dv_as_opaque (v->dv) == dv_as_opaque (dv)); +} + +/* Free the element of VARIABLE_HTAB (its type is struct variable_def). */ + +inline void +variable_hasher::remove (value_type *var) +{ + variable_htab_free (var); +} + +typedef hash_table variable_table_type; +typedef variable_table_type::iterator variable_iterator_type; + +/* Structure for passing some other parameters to function + emit_note_insn_var_location. */ +typedef struct emit_note_data_def +{ + /* The instruction which the note will be emitted before/after. */ + rtx insn; + + /* Where the note will be emitted (before/after insn)? */ + enum emit_note_where where; + + /* The variables and values active at this point. */ + variable_table_type vars; +} emit_note_data; + +/* Structure holding a refcounted hash table. If refcount > 1, + it must be first unshared before modified. */ +typedef struct shared_hash_def +{ + /* Reference count. */ + int refcount; + + /* Actual hash table. */ + variable_table_type htab; +} *shared_hash; + +/* Structure holding the IN or OUT set for a basic block. */ +typedef struct dataflow_set_def +{ + /* Adjustment of stack offset. */ + HOST_WIDE_INT stack_adjust; + + /* Attributes for registers (lists of attrs). */ + attrs regs[FIRST_PSEUDO_REGISTER]; + + /* Variable locations. */ + shared_hash vars; + + /* Vars that is being traversed. */ + shared_hash traversed_vars; +} dataflow_set; + +/* The structure (one for each basic block) containing the information + needed for variable tracking. */ +typedef struct variable_tracking_info_def +{ + /* The vector of micro operations. */ + vec mos; + + /* The IN and OUT set for dataflow analysis. */ + dataflow_set in; + dataflow_set out; + + /* The permanent-in dataflow set for this block. This is used to + hold values for which we had to compute entry values. ??? This + should probably be dynamically allocated, to avoid using more + memory in non-debug builds. */ + dataflow_set *permp; + + /* Has the block been visited in DFS? */ + bool visited; + + /* Has the block been flooded in VTA? */ + bool flooded; + +} *variable_tracking_info; + /* Alloc pool for struct attrs_def. */ static alloc_pool attrs_pool; @@ -474,7 +586,7 @@ static alloc_pool shared_hash_pool; static alloc_pool loc_exp_dep_pool; /* Changed variables, notes will be emitted for them. */ -static htab_t changed_variables; +static variable_table_type changed_variables; /* Shall notes be emitted? */ static bool emit_notes; @@ -482,7 +594,7 @@ static bool emit_notes; /* Values whose dynamic location lists have gone empty, but whose cselib location lists are still usable. Use this to hold the current location, the backlinks, etc, during emit_notes. */ -static htab_t dropped_values; +static variable_table_type dropped_values; /* Empty shared hashtable. */ static shared_hash empty_shared_hash; @@ -510,9 +622,6 @@ static void stack_adjust_offset_pre_post static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *, HOST_WIDE_INT *); static bool vt_stack_adjustments (void); -static hashval_t variable_htab_hash (const void *); -static int variable_htab_eq (const void *, const void *); -static void variable_htab_free (void *); static void init_attrs_list_set (attrs *); static void attrs_list_clear (attrs *); @@ -521,9 +630,9 @@ static void attrs_list_insert (attrs *, static void attrs_list_copy (attrs *, attrs); static void attrs_list_union (attrs *, attrs); -static void **unshare_variable (dataflow_set *set, void **slot, variable var, - enum var_init_status); -static void vars_copy (htab_t, htab_t); +static variable_def **unshare_variable (dataflow_set *set, variable_def **slot, + variable var, enum var_init_status); +static void vars_copy (variable_table_type, variable_table_type); static tree var_debug_decl (tree); static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx); static void var_reg_delete_and_set (dataflow_set *, rtx, bool, @@ -540,7 +649,7 @@ static void dataflow_set_clear (dataflow static void dataflow_set_copy (dataflow_set *, dataflow_set *); static int variable_union_info_cmp_pos (const void *, const void *); static void dataflow_set_union (dataflow_set *, dataflow_set *); -static location_chain find_loc_in_1pdv (rtx, variable, htab_t); +static location_chain find_loc_in_1pdv (rtx, variable, variable_table_type); static bool canon_value_cmp (rtx, rtx); static int loc_cmp (rtx, rtx); static bool variable_part_different_p (variable_part *, variable_part *); @@ -559,32 +668,27 @@ static bool compute_bb_dataflow (basic_b static bool vt_find_locations (void); static void dump_attrs_list (attrs); -static int dump_var_slot (void **, void *); static void dump_var (variable); -static void dump_vars (htab_t); +static void dump_vars (variable_table_type); static void dump_dataflow_set (dataflow_set *); static void dump_dataflow_sets (void); static void set_dv_changed (decl_or_value, bool); static void variable_was_changed (variable, dataflow_set *); -static void **set_slot_part (dataflow_set *, rtx, void **, - decl_or_value, HOST_WIDE_INT, - enum var_init_status, rtx); +static variable_def **set_slot_part (dataflow_set *, rtx, variable_def **, + decl_or_value, HOST_WIDE_INT, + enum var_init_status, rtx); static void set_variable_part (dataflow_set *, rtx, decl_or_value, HOST_WIDE_INT, enum var_init_status, rtx, enum insert_option); -static void **clobber_slot_part (dataflow_set *, rtx, - void **, HOST_WIDE_INT, rtx); +static variable_def **clobber_slot_part (dataflow_set *, rtx, + variable_def **, HOST_WIDE_INT, rtx); static void clobber_variable_part (dataflow_set *, rtx, decl_or_value, HOST_WIDE_INT, rtx); -static void **delete_slot_part (dataflow_set *, rtx, void **, HOST_WIDE_INT); +static variable_def **delete_slot_part (dataflow_set *, rtx, variable_def **, + HOST_WIDE_INT); static void delete_variable_part (dataflow_set *, rtx, decl_or_value, HOST_WIDE_INT); -static int emit_note_insn_var_location (void **, void *); -static void emit_notes_for_changes (rtx, enum emit_note_where, shared_hash); -static int emit_notes_for_differences_1 (void **, void *); -static int emit_notes_for_differences_2 (void **, void *); -static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *); static void emit_notes_in_bb (basic_block, dataflow_set *); static void vt_emit_notes (void); @@ -1189,36 +1293,6 @@ adjust_insn (basic_block bb, rtx insn) } } -/* Return true if a decl_or_value DV is a DECL or NULL. */ -static inline bool -dv_is_decl_p (decl_or_value dv) -{ - return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE; -} - -/* Return true if a decl_or_value is a VALUE rtl. */ -static inline bool -dv_is_value_p (decl_or_value dv) -{ - return dv && !dv_is_decl_p (dv); -} - -/* Return the decl in the decl_or_value. */ -static inline tree -dv_as_decl (decl_or_value dv) -{ - gcc_checking_assert (dv_is_decl_p (dv)); - return (tree) dv; -} - -/* Return the value in the decl_or_value. */ -static inline rtx -dv_as_value (decl_or_value dv) -{ - gcc_checking_assert (dv_is_value_p (dv)); - return (rtx)dv; -} - /* Return the DEBUG_EXPR of a DEBUG_EXPR_DECL or the VALUE in DV. */ static inline rtx dv_as_rtx (decl_or_value dv) @@ -1234,13 +1308,6 @@ dv_as_rtx (decl_or_value dv) return DECL_RTL_KNOWN_SET (decl); } -/* Return the opaque pointer in the decl_or_value. */ -static inline void * -dv_as_opaque (decl_or_value dv) -{ - return dv; -} - /* Return nonzero if a decl_or_value must not have more than one variable part. The returned value discriminates among various kinds of one-part DVs ccording to enum onepart_enum. */ @@ -1328,57 +1395,6 @@ debug_dv (decl_or_value dv) debug_generic_stmt (dv_as_decl (dv)); } -typedef unsigned int dvuid; - -/* Return the uid of DV. */ - -static inline dvuid -dv_uid (decl_or_value dv) -{ - if (dv_is_value_p (dv)) - return CSELIB_VAL_PTR (dv_as_value (dv))->uid; - else - return DECL_UID (dv_as_decl (dv)); -} - -/* Compute the hash from the uid. */ - -static inline hashval_t -dv_uid2hash (dvuid uid) -{ - return uid; -} - -/* The hash function for a mask table in a shared_htab chain. */ - -static inline hashval_t -dv_htab_hash (decl_or_value dv) -{ - return dv_uid2hash (dv_uid (dv)); -} - -/* The hash function for variable_htab, computes the hash value - from the declaration of variable X. */ - -static hashval_t -variable_htab_hash (const void *x) -{ - const_variable const v = (const_variable) x; - - return dv_htab_hash (v->dv); -} - -/* Compare the declaration of variable X with declaration Y. */ - -static int -variable_htab_eq (const void *x, const void *y) -{ - const_variable const v = (const_variable) x; - decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y); - - return (dv_as_opaque (v->dv) == dv_as_opaque (dv)); -} - static void loc_exp_dep_clear (variable var); /* Free the element of VARIABLE_HTAB (its type is struct variable_def). */ @@ -1535,7 +1551,7 @@ shared_hash_shared (shared_hash vars) /* Return the hash table for VARS. */ -static inline htab_t +static inline variable_table_type shared_hash_htab (shared_hash vars) { return vars->htab; @@ -1559,9 +1575,7 @@ shared_hash_unshare (shared_hash vars) shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool); gcc_assert (vars->refcount > 1); new_vars->refcount = 1; - new_vars->htab - = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash, - variable_htab_eq, variable_htab_free); + new_vars->htab.create (vars->htab.elements () + 3); vars_copy (new_vars->htab, vars->htab); vars->refcount--; return new_vars; @@ -1585,7 +1599,7 @@ shared_hash_destroy (shared_hash vars) gcc_checking_assert (vars->refcount > 0); if (--vars->refcount == 0) { - htab_delete (vars->htab); + vars->htab.dispose (); pool_free (shared_hash_pool, vars); } } @@ -1593,16 +1607,16 @@ shared_hash_destroy (shared_hash vars) /* Unshare *PVARS if shared and return slot for DV. If INS is INSERT, insert it if not already present. */ -static inline void ** +static inline variable_def ** shared_hash_find_slot_unshare_1 (shared_hash *pvars, decl_or_value dv, hashval_t dvhash, enum insert_option ins) { if (shared_hash_shared (*pvars)) *pvars = shared_hash_unshare (*pvars); - return htab_find_slot_with_hash (shared_hash_htab (*pvars), dv, dvhash, ins); + return shared_hash_htab (*pvars).find_slot_with_hash (dv, dvhash, ins); } -static inline void ** +static inline variable_def ** shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv, enum insert_option ins) { @@ -1613,15 +1627,15 @@ shared_hash_find_slot_unshare (shared_ha If it is not present, insert it only VARS is not shared, otherwise return NULL. */ -static inline void ** +static inline variable_def ** shared_hash_find_slot_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash) { - return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash, - shared_hash_shared (vars) - ? NO_INSERT : INSERT); + return shared_hash_htab (vars).find_slot_with_hash (dv, dvhash, + shared_hash_shared (vars) + ? NO_INSERT : INSERT); } -static inline void ** +static inline variable_def ** shared_hash_find_slot (shared_hash vars, decl_or_value dv) { return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv)); @@ -1629,15 +1643,14 @@ shared_hash_find_slot (shared_hash vars, /* Return slot for DV only if it is already present in the hash table. */ -static inline void ** +static inline variable_def ** shared_hash_find_slot_noinsert_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash) { - return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash, - NO_INSERT); + return shared_hash_htab (vars).find_slot_with_hash (dv, dvhash, NO_INSERT); } -static inline void ** +static inline variable_def ** shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv) { return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv)); @@ -1649,7 +1662,7 @@ shared_hash_find_slot_noinsert (shared_h static inline variable shared_hash_find_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash) { - return (variable) htab_find_with_hash (shared_hash_htab (vars), dv, dvhash); + return shared_hash_htab (vars).find_with_hash (dv, dvhash); } static inline variable @@ -1678,8 +1691,8 @@ static bool dst_can_be_shared; /* Return a copy of a variable VAR and insert it to dataflow set SET. */ -static void ** -unshare_variable (dataflow_set *set, void **slot, variable var, +static variable_def ** +unshare_variable (dataflow_set *set, variable_def **slot, variable var, enum var_init_status initialized) { variable new_var; @@ -1745,8 +1758,8 @@ unshare_variable (dataflow_set *set, voi *slot = new_var; if (var->in_changed_variables) { - void **cslot - = htab_find_slot_with_hash (changed_variables, var->dv, + variable_def **cslot + = changed_variables.find_slot_with_hash (var->dv, dv_htab_hash (var->dv), NO_INSERT); gcc_assert (*cslot == (void *) var); var->in_changed_variables = false; @@ -1760,18 +1773,16 @@ unshare_variable (dataflow_set *set, voi /* Copy all variables from hash table SRC to hash table DST. */ static void -vars_copy (htab_t dst, htab_t src) +vars_copy (variable_table_type dst, variable_table_type src) { - htab_iterator hi; + variable_iterator_type hi; variable var; - FOR_EACH_HTAB_ELEMENT (src, var, variable, hi) + FOR_EACH_HASH_TABLE_ELEMENT (src, var, variable, hi) { - void **dstp; + variable_def **dstp; var->refcount++; - dstp = htab_find_slot_with_hash (dst, var->dv, - dv_htab_hash (var->dv), - INSERT); + dstp = dst.find_slot_with_hash (var->dv, dv_htab_hash (var->dv), INSERT); *dstp = var; } } @@ -2015,8 +2026,7 @@ vt_canonicalize_addr (dataflow_set *set, } dv = dv_from_rtx (x); - var = (variable) htab_find_with_hash (shared_hash_htab (set->vars), - dv, dv_htab_hash (dv)); + var = shared_hash_htab (set->vars).find_with_hash (dv, dv_htab_hash (dv)); if (!var) break; @@ -2101,13 +2111,12 @@ struct overlapping_mems canonicalized form of COMS->LOC's address, and COMS->LOC must be canonicalized itself. */ -static int -drop_overlapping_mem_locs (void **slot, void *data) +int +drop_overlapping_mem_locs (variable_def **slot, overlapping_mems *coms) { - struct overlapping_mems *coms = (struct overlapping_mems *)data; dataflow_set *set = coms->set; rtx mloc = coms->loc, addr = coms->addr; - variable var = (variable) *slot; + variable var = *slot; if (var->onepart == ONEPART_VALUE) { @@ -2127,7 +2136,7 @@ drop_overlapping_mem_locs (void **slot, return 1; slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN); - var = (variable)*slot; + var = *slot; gcc_assert (var->n_var_parts == 1); } @@ -2183,8 +2192,8 @@ clobber_overlapping_mems (dataflow_set * coms.addr = vt_canonicalize_addr (set, XEXP (loc, 0)); set->traversed_vars = set->vars; - htab_traverse (shared_hash_htab (set->vars), - drop_overlapping_mem_locs, &coms); + shared_hash_htab (set->vars) + .traverse (&coms); set->traversed_vars = NULL; } @@ -2569,7 +2578,7 @@ static int variable_union (variable src, dataflow_set *set) { variable dst; - void **dstp; + variable_def **dstp; int i, j, k; dstp = shared_hash_find_slot (set->vars, src->dv); @@ -2587,7 +2596,7 @@ variable_union (variable src, dataflow_s return 1; } else - dst = (variable) *dstp; + dst = *dstp; gcc_assert (src->n_var_parts); gcc_checking_assert (src->onepart == dst->onepart); @@ -2621,7 +2630,7 @@ variable_union (variable src, dataflow_s { dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_INITIALIZED); - dst = (variable)*dstp; + dst = *dstp; goto restart_onepart_unshared; } @@ -2674,7 +2683,7 @@ variable_union (variable src, dataflow_s if (dst->n_var_parts != k && shared_var_p (dst, set->vars)) { dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN); - dst = (variable)*dstp; + dst = *dstp; } i = src->n_var_parts - 1; @@ -2949,10 +2958,11 @@ dataflow_set_union (dataflow_set *dst, d } else { - htab_iterator hi; + variable_iterator_type hi; variable var; - FOR_EACH_HTAB_ELEMENT (shared_hash_htab (src->vars), var, variable, hi) + FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (src->vars), + var, variable, hi) variable_union (var, dst); } } @@ -3015,7 +3025,7 @@ dv_changed_p (decl_or_value dv) be in star-canonical form. */ static location_chain -find_loc_in_1pdv (rtx loc, variable var, htab_t vars) +find_loc_in_1pdv (rtx loc, variable var, variable_table_type vars) { location_chain node; enum rtx_code loc_code; @@ -3072,7 +3082,7 @@ find_loc_in_1pdv (rtx loc, variable var, gcc_checking_assert (!node->next); dv = dv_from_value (node->loc); - rvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv)); + rvar = vars.find_with_hash (dv, dv_htab_hash (dv)); return find_loc_in_1pdv (loc, rvar, vars); } @@ -3388,10 +3398,11 @@ loc_cmp (rtx x, rtx y) #if ENABLE_CHECKING /* Check the order of entries in one-part variables. */ -static int -canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED) +int +canonicalize_loc_order_check (variable_def **slot, + dataflow_set *data ATTRIBUTE_UNUSED) { - variable var = (variable) *slot; + variable var = *slot; location_chain node, next; #ifdef ENABLE_RTL_CHECKING @@ -3423,11 +3434,10 @@ canonicalize_loc_order_check (void **slo Ensure less likely values can reach more likely neighbors, making the connections bidirectional. */ -static int -canonicalize_values_mark (void **slot, void *data) +int +canonicalize_values_mark (variable_def **slot, dataflow_set *set) { - dataflow_set *set = (dataflow_set *)data; - variable var = (variable) *slot; + variable var = *slot; decl_or_value dv = var->dv; rtx val; location_chain node; @@ -3447,7 +3457,8 @@ canonicalize_values_mark (void **slot, v else { decl_or_value odv = dv_from_value (node->loc); - void **oslot = shared_hash_find_slot_noinsert (set->vars, odv); + variable_def **oslot; + oslot = shared_hash_find_slot_noinsert (set->vars, odv); set_slot_part (set, val, oslot, odv, 0, node->init, NULL_RTX); @@ -3462,16 +3473,15 @@ canonicalize_values_mark (void **slot, v /* Remove redundant entries from equivalence lists in onepart variables, canonicalizing equivalence sets into star shapes. */ -static int -canonicalize_values_star (void **slot, void *data) +int +canonicalize_values_star (variable_def **slot, dataflow_set *set) { - dataflow_set *set = (dataflow_set *)data; - variable var = (variable) *slot; + variable var = *slot; decl_or_value dv = var->dv; location_chain node; decl_or_value cdv; rtx val, cval; - void **cslot; + variable_def **cslot; bool has_value; bool has_marks; @@ -3537,7 +3547,7 @@ canonicalize_values_star (void **slot, v clobber_variable_part (set, NULL, var->dv, 0, NULL); return 1; } - var = (variable)*slot; + var = *slot; gcc_assert (dv_is_value_p (var->dv)); if (var->n_var_parts == 0) return 1; @@ -3667,7 +3677,7 @@ canonicalize_values_star (void **slot, v slot = clobber_slot_part (set, cval, slot, 0, NULL); /* Variable may have been unshared. */ - var = (variable)*slot; + var = *slot; gcc_checking_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval && var->var_part[0].loc_chain->next == NULL); @@ -3684,16 +3694,15 @@ canonicalize_values_star (void **slot, v have determined or even seen the canonical value of a set when we get to a variable that references another member of the set. */ -static int -canonicalize_vars_star (void **slot, void *data) +int +canonicalize_vars_star (variable_def **slot, dataflow_set *set) { - dataflow_set *set = (dataflow_set *)data; - variable var = (variable) *slot; + variable var = *slot; decl_or_value dv = var->dv; location_chain node; rtx cval; decl_or_value cdv; - void **cslot; + variable_def **cslot; variable cvar; location_chain cnode; @@ -3715,7 +3724,7 @@ canonicalize_vars_star (void **slot, voi cslot = shared_hash_find_slot_noinsert (set->vars, cdv); if (!cslot) return 1; - cvar = (variable)*cslot; + cvar = *cslot; gcc_assert (cvar->n_var_parts == 1); cnode = cvar->var_part[0].loc_chain; @@ -3747,7 +3756,7 @@ static int variable_merge_over_cur (variable s1var, struct dfset_merge *dsm) { dataflow_set *dst = dsm->dst; - void **dstslot; + variable_def **dstslot; variable s2var, dvar = NULL; decl_or_value dv = s1var->dv; onepart_enum_t onepart = s1var->onepart; @@ -3787,7 +3796,7 @@ variable_merge_over_cur (variable s1var, dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash); if (dstslot) { - dvar = (variable)*dstslot; + dvar = *dstslot; gcc_assert (dvar->refcount == 1 && dvar->onepart == onepart && dvar->n_var_parts == 1); @@ -3885,8 +3894,8 @@ variable_merge_over_cur (variable s1var, nodep = nextp; } - if (dvar != (variable)*dstslot) - dvar = (variable)*dstslot; + if (dvar != *dstslot) + dvar = *dstslot; nodep = &dvar->var_part[0].loc_chain; if (val) @@ -3908,7 +3917,7 @@ variable_merge_over_cur (variable s1var, gcc_checking_assert (dstslot == shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash)); - dvar = (variable)*dstslot; + dvar = *dstslot; } else { @@ -3944,7 +3953,7 @@ variable_merge_over_cur (variable s1var, if (GET_CODE (node->loc) == VALUE) { decl_or_value dv = dv_from_value (node->loc); - void **slot = NULL; + variable_def **slot = NULL; if (shared_hash_shared (dst->vars)) slot = shared_hash_find_slot_noinsert (dst->vars, dv); @@ -3976,7 +3985,7 @@ variable_merge_over_cur (variable s1var, gcc_checking_assert (dstslot == shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash)); - dvar = (variable)*dstslot; + dvar = *dstslot; } } @@ -4012,7 +4021,7 @@ variable_merge_over_src (variable s2var, if (!s2var->onepart) { - void **dstp = shared_hash_find_slot (dst->vars, dv); + variable_def **dstp = shared_hash_find_slot (dst->vars, dv); *dstp = s2var; s2var->refcount++; return 1; @@ -4033,19 +4042,17 @@ dataflow_set_merge (dataflow_set *dst, d struct dfset_merge dsm; int i; size_t src1_elems, src2_elems; - htab_iterator hi; + variable_iterator_type hi; variable var; - src1_elems = htab_elements (shared_hash_htab (src1->vars)); - src2_elems = htab_elements (shared_hash_htab (src2->vars)); + src1_elems = shared_hash_htab (src1->vars).elements (); + src2_elems = shared_hash_htab (src2->vars).elements (); dataflow_set_init (dst); dst->stack_adjust = cur.stack_adjust; shared_hash_destroy (dst->vars); dst->vars = (shared_hash) pool_alloc (shared_hash_pool); dst->vars->refcount = 1; - dst->vars->htab - = htab_create (MAX (src1_elems, src2_elems), variable_htab_hash, - variable_htab_eq, variable_htab_free); + dst->vars->htab.create (MAX (src1_elems, src2_elems)); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]); @@ -4055,9 +4062,11 @@ dataflow_set_merge (dataflow_set *dst, d dsm.cur = src1; dsm.src_onepart_cnt = 0; - FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.src->vars), var, variable, hi) + FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.src->vars), + var, variable, hi) variable_merge_over_src (var, &dsm); - FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.cur->vars), var, variable, hi) + FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.cur->vars), + var, variable, hi) variable_merge_over_cur (var, &dsm); if (dsm.src_onepart_cnt) @@ -4127,7 +4136,7 @@ dataflow_set_equiv_regs (dataflow_set *s if (list->offset == 0 && dv_onepart_p (list->dv)) { rtx cval = canon[(int)GET_MODE (list->loc)]; - void **slot; + variable_def **slot; if (!cval) continue; @@ -4198,12 +4207,11 @@ struct dfset_post_merge /* Create values for incoming expressions associated with one-part variables that don't have value numbers for them. */ -static int -variable_post_merge_new_vals (void **slot, void *info) +int +variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm) { - struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info; dataflow_set *set = dfpm->set; - variable var = (variable)*slot; + variable var = *slot; location_chain node; if (!var->onepart || !var->n_var_parts) @@ -4228,7 +4236,7 @@ variable_post_merge_new_vals (void **slo { slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_INITIALIZED); - var = (variable)*slot; + var = *slot; goto restart; } @@ -4335,12 +4343,11 @@ variable_post_merge_new_vals (void **slo /* Reset values in the permanent set that are not associated with the chosen expression. */ -static int -variable_post_merge_perm_vals (void **pslot, void *info) +int +variable_post_merge_perm_vals (variable_def **pslot, dfset_post_merge *dfpm) { - struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info; dataflow_set *set = dfpm->set; - variable pvar = (variable)*pslot, var; + variable pvar = *pslot, var; location_chain pnode; decl_or_value dv; attrs att; @@ -4404,13 +4411,15 @@ dataflow_post_merge_adjust (dataflow_set dfpm.set = set; dfpm.permp = permp; - htab_traverse (shared_hash_htab (set->vars), variable_post_merge_new_vals, - &dfpm); + shared_hash_htab (set->vars) + .traverse (&dfpm); if (*permp) - htab_traverse (shared_hash_htab ((*permp)->vars), - variable_post_merge_perm_vals, &dfpm); - htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set); - htab_traverse (shared_hash_htab (set->vars), canonicalize_vars_star, set); + shared_hash_htab ((*permp)->vars) + .traverse (&dfpm); + shared_hash_htab (set->vars) + .traverse (set); + shared_hash_htab (set->vars) + .traverse (set); } /* Return a node whose loc is a MEM that refers to EXPR in the @@ -4418,7 +4427,7 @@ dataflow_post_merge_adjust (dataflow_set any values recursively mentioned in the location lists. */ static location_chain -find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars) +find_mem_expr_in_1pdv (tree expr, rtx val, variable_table_type vars) { location_chain node; decl_or_value dv; @@ -4432,7 +4441,7 @@ find_mem_expr_in_1pdv (tree expr, rtx va && !VALUE_RECURSED_INTO (val)); dv = dv_from_value (val); - var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv)); + var = vars.find_with_hash (dv, dv_htab_hash (dv)); if (!var) return NULL; @@ -4489,11 +4498,10 @@ mem_dies_at_call (rtx mem) one-part variable, except those whose MEM attributes map back to the variable itself, directly or within a VALUE. */ -static int -dataflow_set_preserve_mem_locs (void **slot, void *data) +int +dataflow_set_preserve_mem_locs (variable_def **slot, dataflow_set *set) { - dataflow_set *set = (dataflow_set *) data; - variable var = (variable) *slot; + variable var = *slot; if (var->onepart == ONEPART_VDECL || var->onepart == ONEPART_DEXPR) { @@ -4527,7 +4535,7 @@ dataflow_set_preserve_mem_locs (void **s return 1; slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN); - var = (variable)*slot; + var = *slot; gcc_assert (var->n_var_parts == 1); } @@ -4599,11 +4607,10 @@ dataflow_set_preserve_mem_locs (void **s /* Remove all MEMs from the location list of a hash table entry for a value. */ -static int -dataflow_set_remove_mem_locs (void **slot, void *data) +int +dataflow_set_remove_mem_locs (variable_def **slot, dataflow_set *set) { - dataflow_set *set = (dataflow_set *) data; - variable var = (variable) *slot; + variable var = *slot; if (var->onepart == ONEPART_VALUE) { @@ -4624,7 +4631,7 @@ dataflow_set_remove_mem_locs (void **slo return 1; slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN); - var = (variable)*slot; + var = *slot; gcc_assert (var->n_var_parts == 1); } @@ -4684,11 +4691,11 @@ dataflow_set_clear_at_call (dataflow_set if (MAY_HAVE_DEBUG_INSNS) { set->traversed_vars = set->vars; - htab_traverse (shared_hash_htab (set->vars), - dataflow_set_preserve_mem_locs, set); + shared_hash_htab (set->vars) + .traverse (set); set->traversed_vars = set->vars; - htab_traverse (shared_hash_htab (set->vars), dataflow_set_remove_mem_locs, - set); + shared_hash_htab (set->vars) + .traverse (set); set->traversed_vars = NULL; } } @@ -4787,21 +4794,21 @@ variable_different_p (variable var1, var static bool dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set) { - htab_iterator hi; + variable_iterator_type hi; variable var1; if (old_set->vars == new_set->vars) return false; - if (htab_elements (shared_hash_htab (old_set->vars)) - != htab_elements (shared_hash_htab (new_set->vars))) + if (shared_hash_htab (old_set->vars).elements () + != shared_hash_htab (new_set->vars).elements ()) return true; - FOR_EACH_HTAB_ELEMENT (shared_hash_htab (old_set->vars), var1, variable, hi) + FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (old_set->vars), + var1, variable, hi) { - htab_t htab = shared_hash_htab (new_set->vars); - variable var2 = (variable) htab_find_with_hash (htab, var1->dv, - dv_htab_hash (var1->dv)); + variable_table_type htab = shared_hash_htab (new_set->vars); + variable var2 = htab.find_with_hash (var1->dv, dv_htab_hash (var1->dv)); if (!var2) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -6698,13 +6705,13 @@ compute_bb_dataflow (basic_block bb) if (MAY_HAVE_DEBUG_INSNS) { dataflow_set_equiv_regs (out); - htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark, - out); - htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star, - out); + shared_hash_htab (out->vars) + .traverse (out); + shared_hash_htab (out->vars) + .traverse (out); #if ENABLE_CHECKING - htab_traverse (shared_hash_htab (out->vars), - canonicalize_loc_order_check, out); + shared_hash_htab (out->vars) + .traverse (out); #endif } changed = dataflow_set_different (&old_out, out); @@ -6776,12 +6783,10 @@ vt_find_locations (void) if (VTI (bb)->in.vars) { htabsz - -= (htab_size (shared_hash_htab (VTI (bb)->in.vars)) - + htab_size (shared_hash_htab (VTI (bb)->out.vars))); - oldinsz - = htab_elements (shared_hash_htab (VTI (bb)->in.vars)); - oldoutsz - = htab_elements (shared_hash_htab (VTI (bb)->out.vars)); + -= shared_hash_htab (VTI (bb)->in.vars).size () + + shared_hash_htab (VTI (bb)->out.vars).size (); + oldinsz = shared_hash_htab (VTI (bb)->in.vars).elements (); + oldoutsz = shared_hash_htab (VTI (bb)->out.vars).elements (); } else oldinsz = oldoutsz = 0; @@ -6819,9 +6824,9 @@ vt_find_locations (void) #if ENABLE_CHECKING /* Merge and merge_adjust should keep entries in canonical order. */ - htab_traverse (shared_hash_htab (in->vars), - canonicalize_loc_order_check, - in); + shared_hash_htab (in->vars) + .traverse (in); #endif if (dst_can_be_shared) { @@ -6841,8 +6846,8 @@ vt_find_locations (void) } changed = compute_bb_dataflow (bb); - htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars)) - + htab_size (shared_hash_htab (VTI (bb)->out.vars))); + htabsz += shared_hash_htab (VTI (bb)->in.vars).size () + + shared_hash_htab (VTI (bb)->out.vars).size (); if (htabmax && htabsz > htabmax) { @@ -6889,9 +6894,9 @@ vt_find_locations (void) fprintf (dump_file, "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n", bb->index, - (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)), + (int)shared_hash_htab (VTI (bb)->in.vars).size (), oldinsz, - (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)), + (int)shared_hash_htab (VTI (bb)->out.vars).size (), oldoutsz, (int)worklist->nodes, (int)pending->nodes, htabsz); @@ -6939,10 +6944,10 @@ dump_attrs_list (attrs list) /* Print the information about variable *SLOT to dump file. */ -static int -dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED) +int +dump_var_tracking_slot (variable_def **slot, void *data ATTRIBUTE_UNUSED) { - variable var = (variable) *slot; + variable var = *slot; dump_var (var); @@ -6998,12 +7003,12 @@ dump_var (variable var) /* Print the information about variables from hash table VARS to dump file. */ static void -dump_vars (htab_t vars) +dump_vars (variable_table_type vars) { - if (htab_elements (vars) > 0) + if (vars.elements () > 0) { fprintf (dump_file, "Variables:\n"); - htab_traverse (vars, dump_var_slot, NULL); + vars.traverse (NULL); } } @@ -7051,18 +7056,17 @@ dump_dataflow_sets (void) static inline variable variable_from_dropped (decl_or_value dv, enum insert_option insert) { - void **slot; + variable_def **slot; variable empty_var; onepart_enum_t onepart; - slot = htab_find_slot_with_hash (dropped_values, dv, dv_htab_hash (dv), - insert); + slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv), insert); if (!slot) return NULL; if (*slot) - return (variable) *slot; + return *slot; gcc_checking_assert (insert == INSERT); @@ -7122,18 +7126,16 @@ variable_was_changed (variable var, data if (emit_notes) { - void **slot; + variable_def **slot; /* Remember this decl or VALUE has been added to changed_variables. */ set_dv_changed (var->dv, true); - slot = htab_find_slot_with_hash (changed_variables, - var->dv, - hash, INSERT); + slot = changed_variables.find_slot_with_hash (var->dv, hash, INSERT); if (*slot) { - variable old_var = (variable) *slot; + variable old_var = *slot; gcc_assert (old_var->in_changed_variables); old_var->in_changed_variables = false; if (var != old_var && var->onepart) @@ -7152,14 +7154,14 @@ variable_was_changed (variable var, data { onepart_enum_t onepart = var->onepart; variable empty_var = NULL; - void **dslot = NULL; + variable_def **dslot = NULL; if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR) { - dslot = htab_find_slot_with_hash (dropped_values, var->dv, + dslot = dropped_values.find_slot_with_hash (var->dv, dv_htab_hash (var->dv), INSERT); - empty_var = (variable) *dslot; + empty_var = *dslot; if (empty_var) { @@ -7214,7 +7216,7 @@ variable_was_changed (variable var, data gcc_assert (set); if (var->n_var_parts == 0) { - void **slot; + variable_def **slot; drop_var: slot = shared_hash_find_slot_noinsert (set->vars, var->dv); @@ -7223,7 +7225,7 @@ variable_was_changed (variable var, data if (shared_hash_shared (set->vars)) slot = shared_hash_find_slot_unshare (&set->vars, var->dv, NO_INSERT); - htab_clear_slot (shared_hash_htab (set->vars), slot); + shared_hash_htab (set->vars).clear_slot (slot); } } } @@ -7273,8 +7275,8 @@ find_variable_location_part (variable va return -1; } -static void ** -set_slot_part (dataflow_set *set, rtx loc, void **slot, +static variable_def ** +set_slot_part (dataflow_set *set, rtx loc, variable_def **slot, decl_or_value dv, HOST_WIDE_INT offset, enum var_init_status initialized, rtx set_src) { @@ -7284,7 +7286,7 @@ set_slot_part (dataflow_set *set, rtx lo variable var; onepart_enum_t onepart; - var = (variable) *slot; + var = *slot; if (var) onepart = var->onepart; @@ -7407,7 +7409,7 @@ set_slot_part (dataflow_set *set, rtx lo if (shared_var_p (var, set->vars)) { slot = unshare_variable (set, slot, var, initialized); - var = (variable)*slot; + var = *slot; for (nextp = &var->var_part[0].loc_chain; c; nextp = &(*nextp)->next) c--; @@ -7446,7 +7448,7 @@ set_slot_part (dataflow_set *set, rtx lo if (shared_var_p (var, set->vars)) { slot = unshare_variable (set, slot, var, initialized); - var = (variable)*slot; + var = *slot; } } } @@ -7458,7 +7460,7 @@ set_slot_part (dataflow_set *set, rtx lo if (shared_var_p (var, set->vars)) { slot = unshare_variable (set, slot, var, initialized); - var = (variable)*slot; + var = *slot; } /* We track only variables whose size is <= MAX_VAR_PARTS bytes @@ -7533,7 +7535,7 @@ set_variable_part (dataflow_set *set, rt enum var_init_status initialized, rtx set_src, enum insert_option iopt) { - void **slot; + variable_def **slot; if (iopt == NO_INSERT) slot = shared_hash_find_slot_noinsert (set->vars, dv); @@ -7551,11 +7553,11 @@ set_variable_part (dataflow_set *set, rt The variable part is specified by variable's declaration or value DV and offset OFFSET. */ -static void ** -clobber_slot_part (dataflow_set *set, rtx loc, void **slot, +static variable_def ** +clobber_slot_part (dataflow_set *set, rtx loc, variable_def **slot, HOST_WIDE_INT offset, rtx set_src) { - variable var = (variable) *slot; + variable var = *slot; int pos = find_variable_location_part (var, offset, NULL); if (pos >= 0) @@ -7614,7 +7616,7 @@ static void clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv, HOST_WIDE_INT offset, rtx set_src) { - void **slot; + variable_def **slot; if (!dv_as_opaque (dv) || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv)))) @@ -7631,11 +7633,11 @@ clobber_variable_part (dataflow_set *set variable part is specified by its SET->vars slot SLOT and offset OFFSET and the part's location by LOC. */ -static void ** -delete_slot_part (dataflow_set *set, rtx loc, void **slot, +static variable_def ** +delete_slot_part (dataflow_set *set, rtx loc, variable_def **slot, HOST_WIDE_INT offset) { - variable var = (variable) *slot; + variable var = *slot; int pos = find_variable_location_part (var, offset, NULL); if (pos >= 0) @@ -7658,7 +7660,7 @@ delete_slot_part (dataflow_set *set, rtx { slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN); - var = (variable)*slot; + var = *slot; break; } } @@ -7722,7 +7724,7 @@ static void delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv, HOST_WIDE_INT offset) { - void **slot = shared_hash_find_slot_noinsert (set->vars, dv); + variable_def **slot = shared_hash_find_slot_noinsert (set->vars, dv); if (!slot) return; @@ -7735,7 +7737,7 @@ delete_variable_part (dataflow_set *set, struct expand_loc_callback_data { /* The variables and values active at this point. */ - htab_t vars; + variable_table_type vars; /* Stack of values and debug_exprs under expansion, and their children. */ @@ -7824,7 +7826,7 @@ loc_exp_dep_clear (variable var) back-links in VARS. */ static void -loc_exp_insert_dep (variable var, rtx x, htab_t vars) +loc_exp_insert_dep (variable var, rtx x, variable_table_type vars) { decl_or_value dv; variable xvar; @@ -7834,7 +7836,7 @@ loc_exp_insert_dep (variable var, rtx x, /* ??? Build a vector of variables parallel to EXPANDING, to avoid an additional look up? */ - xvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv)); + xvar = vars.find_with_hash (dv, dv_htab_hash (dv)); if (!xvar) { @@ -7874,7 +7876,8 @@ loc_exp_insert_dep (variable var, rtx x, true if we found any pending-recursion results. */ static bool -loc_exp_dep_set (variable var, rtx result, rtx *value, int count, htab_t vars) +loc_exp_dep_set (variable var, rtx result, rtx *value, int count, + variable_table_type vars) { bool pending_recursion = false; @@ -7903,7 +7906,7 @@ loc_exp_dep_set (variable var, rtx resul attempt to compute a current location. */ static void -notify_dependents_of_resolved_value (variable ivar, htab_t vars) +notify_dependents_of_resolved_value (variable ivar, variable_table_type vars) { loc_exp_dep *led, *next; @@ -7941,7 +7944,7 @@ notify_dependents_of_resolved_value (var continue; } - var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv)); + var = vars.find_with_hash (dv, dv_htab_hash (dv)); if (!var) var = variable_from_dropped (dv, NO_INSERT); @@ -8185,7 +8188,7 @@ vt_expand_loc_callback (rtx x, bitmap re return NULL; } - var = (variable) htab_find_with_hash (elcd->vars, dv, dv_htab_hash (dv)); + var = elcd->vars.find_with_hash (dv, dv_htab_hash (dv)); if (!var) { @@ -8294,7 +8297,7 @@ resolve_expansions_pending_recursion (ve equivalences in VARS, updating their CUR_LOCs in the process. */ static rtx -vt_expand_loc (rtx loc, htab_t vars) +vt_expand_loc (rtx loc, variable_table_type vars) { struct expand_loc_callback_data data; rtx result; @@ -8316,7 +8319,7 @@ vt_expand_loc (rtx loc, htab_t vars) in VARS, updating their CUR_LOCs in the process. */ static rtx -vt_expand_1pvar (variable var, htab_t vars) +vt_expand_1pvar (variable var, variable_table_type vars) { struct expand_loc_callback_data data; rtx loc; @@ -8341,13 +8344,13 @@ vt_expand_1pvar (variable var, htab_t va additional parameters: WHERE specifies whether the note shall be emitted before or after instruction INSN. */ -static int -emit_note_insn_var_location (void **varp, void *data) +int +emit_note_insn_var_location (variable_def **varp, emit_note_data *data) { - variable var = (variable) *varp; - rtx insn = ((emit_note_data *)data)->insn; - enum emit_note_where where = ((emit_note_data *)data)->where; - htab_t vars = ((emit_note_data *)data)->vars; + variable var = *varp; + rtx insn = data->insn; + enum emit_note_where where = data->where; + variable_table_type vars = data->vars; rtx note, note_vl; int i, j, n_var_parts; bool complete; @@ -8585,7 +8588,7 @@ emit_note_insn_var_location (void **varp set_dv_changed (var->dv, false); gcc_assert (var->in_changed_variables); var->in_changed_variables = false; - htab_clear_slot (changed_variables, varp); + changed_variables.clear_slot (varp); /* Continue traversing the hash table. */ return 1; @@ -8594,11 +8597,11 @@ emit_note_insn_var_location (void **varp /* While traversing changed_variables, push onto DATA (a stack of RTX values) entries that aren't user variables. */ -static int -values_to_stack (void **slot, void *data) +int +var_track_values_to_stack (variable_def **slot, + vec *changed_values_stack) { - vec *changed_values_stack = (vec *) data; - variable var = (variable) *slot; + variable var = *slot; if (var->onepart == ONEPART_VALUE) changed_values_stack->safe_push (dv_as_value (var->dv)); @@ -8614,14 +8617,14 @@ static void remove_value_from_changed_variables (rtx val) { decl_or_value dv = dv_from_rtx (val); - void **slot; + variable_def **slot; variable var; - slot = htab_find_slot_with_hash (changed_variables, - dv, dv_htab_hash (dv), NO_INSERT); - var = (variable) *slot; + slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv), + NO_INSERT); + var = *slot; var->in_changed_variables = false; - htab_clear_slot (changed_variables, slot); + changed_variables.clear_slot (slot); } /* If VAL (a value or debug_expr) has backlinks to variables actively @@ -8630,23 +8633,22 @@ remove_value_from_changed_variables (rtx have dependencies of their own to notify. */ static void -notify_dependents_of_changed_value (rtx val, htab_t htab, +notify_dependents_of_changed_value (rtx val, variable_table_type htab, vec *changed_values_stack) { - void **slot; + variable_def **slot; variable var; loc_exp_dep *led; decl_or_value dv = dv_from_rtx (val); - slot = htab_find_slot_with_hash (changed_variables, - dv, dv_htab_hash (dv), NO_INSERT); + slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv), + NO_INSERT); if (!slot) - slot = htab_find_slot_with_hash (htab, - dv, dv_htab_hash (dv), NO_INSERT); + slot = htab.find_slot_with_hash (dv, dv_htab_hash (dv), NO_INSERT); if (!slot) - slot = htab_find_slot_with_hash (dropped_values, - dv, dv_htab_hash (dv), NO_INSERT); - var = (variable) *slot; + slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv), + NO_INSERT); + var = *slot; while ((led = VAR_LOC_DEP_LST (var))) { @@ -8676,14 +8678,14 @@ notify_dependents_of_changed_value (rtx break; case ONEPART_VDECL: - ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv)); + ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv)); gcc_checking_assert (!VAR_LOC_DEP_LST (ivar)); variable_was_changed (ivar, NULL); break; case NOT_ONEPART: pool_free (loc_exp_dep_pool, led); - ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv)); + ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv)); if (ivar) { int i = ivar->n_var_parts; @@ -8713,7 +8715,7 @@ notify_dependents_of_changed_value (rtx CHANGED_VARIABLES. */ static void -process_changed_values (htab_t htab) +process_changed_values (variable_table_type htab) { int i, n; rtx val; @@ -8722,7 +8724,9 @@ process_changed_values (htab_t htab) vec_stack_alloc (rtx, changed_values_stack, 20); /* Move values from changed_variables to changed_values_stack. */ - htab_traverse (changed_variables, values_to_stack, &changed_values_stack); + changed_variables + .traverse *, var_track_values_to_stack> + (&changed_values_stack); /* Back-propagate change notifications in values while popping them from the stack. */ @@ -8755,9 +8759,9 @@ emit_notes_for_changes (rtx insn, enum e shared_hash vars) { emit_note_data data; - htab_t htab = shared_hash_htab (vars); + variable_table_type htab = shared_hash_htab (vars); - if (!htab_elements (changed_variables)) + if (!changed_variables.elements ()) return; if (MAY_HAVE_DEBUG_INSNS) @@ -8767,21 +8771,20 @@ emit_notes_for_changes (rtx insn, enum e data.where = where; data.vars = htab; - htab_traverse (changed_variables, emit_note_insn_var_location, &data); + changed_variables + .traverse (&data); } /* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the same variable in hash table DATA or is not there at all. */ -static int -emit_notes_for_differences_1 (void **slot, void *data) +int +emit_notes_for_differences_1 (variable_def **slot, variable_table_type new_vars) { - htab_t new_vars = (htab_t) data; variable old_var, new_var; - old_var = (variable) *slot; - new_var = (variable) htab_find_with_hash (new_vars, old_var->dv, - dv_htab_hash (old_var->dv)); + old_var = *slot; + new_var = new_vars.find_with_hash (old_var->dv, dv_htab_hash (old_var->dv)); if (!new_var) { @@ -8847,15 +8850,13 @@ emit_notes_for_differences_1 (void **slo /* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash table DATA. */ -static int -emit_notes_for_differences_2 (void **slot, void *data) +int +emit_notes_for_differences_2 (variable_def **slot, variable_table_type old_vars) { - htab_t old_vars = (htab_t) data; variable old_var, new_var; - new_var = (variable) *slot; - old_var = (variable) htab_find_with_hash (old_vars, new_var->dv, - dv_htab_hash (new_var->dv)); + new_var = *slot; + old_var = old_vars.find_with_hash (new_var->dv, dv_htab_hash (new_var->dv)); if (!old_var) { int i; @@ -8875,12 +8876,12 @@ static void emit_notes_for_differences (rtx insn, dataflow_set *old_set, dataflow_set *new_set) { - htab_traverse (shared_hash_htab (old_set->vars), - emit_notes_for_differences_1, - shared_hash_htab (new_set->vars)); - htab_traverse (shared_hash_htab (new_set->vars), - emit_notes_for_differences_2, - shared_hash_htab (old_set->vars)); + shared_hash_htab (old_set->vars) + .traverse + (shared_hash_htab (new_set->vars)); + shared_hash_htab (new_set->vars) + .traverse + (shared_hash_htab (old_set->vars)); emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars); } @@ -9240,7 +9241,7 @@ vt_emit_notes (void) basic_block bb; dataflow_set cur; - gcc_assert (!htab_elements (changed_variables)); + gcc_assert (!changed_variables.elements ()); /* Free memory occupied by the out hash tables, as they aren't used anymore. */ @@ -9253,9 +9254,7 @@ vt_emit_notes (void) if (MAY_HAVE_DEBUG_INSNS) { - dropped_values = htab_create (cselib_get_next_uid () * 2, - variable_htab_hash, variable_htab_eq, - variable_htab_free); + dropped_values.create (cselib_get_next_uid () * 2); loc_exp_dep_pool = create_alloc_pool ("loc_exp_dep pool", sizeof (loc_exp_dep), 64); } @@ -9276,14 +9275,14 @@ vt_emit_notes (void) dataflow_set_clear (&VTI (bb)->in); } #ifdef ENABLE_CHECKING - htab_traverse (shared_hash_htab (cur.vars), - emit_notes_for_differences_1, - shared_hash_htab (empty_shared_hash)); + shared_hash_htab (cur.vars) + .traverse + (shared_hash_htab (empty_shared_hash)); #endif dataflow_set_destroy (&cur); if (MAY_HAVE_DEBUG_INSNS) - htab_delete (dropped_values); + dropped_values.dispose (); emit_notes = false; } @@ -9616,11 +9615,8 @@ vt_initialize (void) sizeof (struct shared_hash_def), 256); empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool); empty_shared_hash->refcount = 1; - empty_shared_hash->htab - = htab_create (1, variable_htab_hash, variable_htab_eq, - variable_htab_free); - changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq, - variable_htab_free); + empty_shared_hash->htab.create (1); + changed_variables.create (10); /* Init the IN and OUT sets. */ FOR_ALL_BB (bb) @@ -9971,8 +9967,8 @@ vt_finalize (void) } } free_aux_for_blocks (); - htab_delete (empty_shared_hash->htab); - htab_delete (changed_variables); + empty_shared_hash->htab.dispose (); + changed_variables.dispose (); free_alloc_pool (attrs_pool); free_alloc_pool (var_pool); free_alloc_pool (loc_chain_pool); Index: gcc/trans-mem.c =================================================================== --- gcc/trans-mem.c (revision 194487) +++ gcc/trans-mem.c (working copy) @@ -880,8 +880,62 @@ typedef struct tm_log_entry tree save_var; } *tm_log_entry_t; + +/* Log entry hashtable helpers. */ + +struct log_entry_hasher +{ + typedef tm_log_entry value_type; + typedef tm_log_entry compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; + +/* Htab support. Return hash value for a `tm_log_entry'. */ +inline hashval_t +log_entry_hasher::hash (const value_type *log) +{ + return iterative_hash_expr (log->addr, 0); +} + +/* Htab support. Return true if two log entries are the same. */ +inline bool +log_entry_hasher::equal (const value_type *log1, const compare_type *log2) +{ + /* FIXME: + + rth: I suggest that we get rid of the component refs etc. + I.e. resolve the reference to base + offset. + + We may need to actually finish a merge with mainline for this, + since we'd like to be presented with Richi's MEM_REF_EXPRs more + often than not. But in the meantime your tm_log_entry could save + the results of get_inner_reference. + + See: g++.dg/tm/pr46653.C + */ + + /* Special case plain equality because operand_equal_p() below will + return FALSE if the addresses are equal but they have + side-effects (e.g. a volatile address). */ + if (log1->addr == log2->addr) + return true; + + return operand_equal_p (log1->addr, log2->addr, 0); +} + +/* Htab support. Free one tm_log_entry. */ +inline void +log_entry_hasher::remove (value_type *lp) +{ + lp->stmts.release (); + free (lp); +} + + /* The actual log. */ -static htab_t tm_log; +static hash_table tm_log; /* Addresses to log with a save/restore sequence. These should be in dominator order. */ @@ -928,57 +982,11 @@ tm_mem_map_hasher::equal (const value_ty of memory (malloc, alloc, etc). */ static hash_table tm_new_mem_hash; -/* Htab support. Return hash value for a `tm_log_entry'. */ -static hashval_t -tm_log_hash (const void *p) -{ - const struct tm_log_entry *log = (const struct tm_log_entry *) p; - return iterative_hash_expr (log->addr, 0); -} - -/* Htab support. Return true if two log entries are the same. */ -static int -tm_log_eq (const void *p1, const void *p2) -{ - const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1; - const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2; - - /* FIXME: - - rth: I suggest that we get rid of the component refs etc. - I.e. resolve the reference to base + offset. - - We may need to actually finish a merge with mainline for this, - since we'd like to be presented with Richi's MEM_REF_EXPRs more - often than not. But in the meantime your tm_log_entry could save - the results of get_inner_reference. - - See: g++.dg/tm/pr46653.C - */ - - /* Special case plain equality because operand_equal_p() below will - return FALSE if the addresses are equal but they have - side-effects (e.g. a volatile address). */ - if (log1->addr == log2->addr) - return true; - - return operand_equal_p (log1->addr, log2->addr, 0); -} - -/* Htab support. Free one tm_log_entry. */ -static void -tm_log_free (void *p) -{ - struct tm_log_entry *lp = (struct tm_log_entry *) p; - lp->stmts.release (); - free (lp); -} - /* Initialize logging data structures. */ static void tm_log_init (void) { - tm_log = htab_create (10, tm_log_hash, tm_log_eq, tm_log_free); + tm_log.create (10); tm_new_mem_hash.create (5); tm_log_save_addresses.create (5); } @@ -987,7 +995,7 @@ tm_log_init (void) static void tm_log_delete (void) { - htab_delete (tm_log); + tm_log.dispose (); tm_new_mem_hash.dispose (); tm_log_save_addresses.release (); } @@ -1029,11 +1037,11 @@ transaction_invariant_address_p (const_t static void tm_log_add (basic_block entry_block, tree addr, gimple stmt) { - void **slot; + tm_log_entry **slot; struct tm_log_entry l, *lp; l.addr = addr; - slot = htab_find_slot (tm_log, &l, INSERT); + slot = tm_log.find_slot (&l, INSERT); if (!*slot) { tree type = TREE_TYPE (addr); @@ -1074,7 +1082,7 @@ tm_log_add (basic_block entry_block, tre size_t i; gimple oldstmt; - lp = (struct tm_log_entry *) *slot; + lp = *slot; /* If we're generating a save/restore sequence, we don't care about statements. */ @@ -1176,10 +1184,10 @@ tm_log_emit_stmt (tree addr, gimple stmt static void tm_log_emit (void) { - htab_iterator hi; + hash_table ::iterator hi; struct tm_log_entry *lp; - FOR_EACH_HTAB_ELEMENT (tm_log, lp, tm_log_entry_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (tm_log, lp, tm_log_entry_t, hi) { size_t i; gimple stmt; @@ -1221,7 +1229,7 @@ tm_log_emit_saves (basic_block entry_blo for (i = 0; i < tm_log_save_addresses.length (); ++i) { l.addr = tm_log_save_addresses[i]; - lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT); + lp = *(tm_log.find_slot (&l, NO_INSERT)); gcc_assert (lp->save_var != NULL); /* We only care about variables in the current transaction. */ @@ -1257,7 +1265,7 @@ tm_log_emit_restores (basic_block entry_ for (i = tm_log_save_addresses.length () - 1; i >= 0; i--) { l.addr = tm_log_save_addresses[i]; - lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT); + lp = *(tm_log.find_slot (&l, NO_INSERT)); gcc_assert (lp->save_var != NULL); /* We only care about variables in the current transaction. */ @@ -3153,6 +3161,35 @@ typedef struct tm_memop tree addr; } *tm_memop_t; +/* TM memory operation hashtable helpers. */ + +struct tm_memop_hasher : typed_free_remove +{ + typedef tm_memop value_type; + typedef tm_memop compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Htab support. Return a hash value for a `tm_memop'. */ +inline hashval_t +tm_memop_hasher::hash (const value_type *mem) +{ + tree addr = mem->addr; + /* We drill down to the SSA_NAME/DECL for the hash, but equality is + actually done with operand_equal_p (see tm_memop_eq). */ + if (TREE_CODE (addr) == ADDR_EXPR) + addr = TREE_OPERAND (addr, 0); + return iterative_hash_expr (addr, 0); +} + +/* Htab support. Return true if two tm_memop's are the same. */ +inline bool +tm_memop_hasher::equal (const value_type *mem1, const compare_type *mem2) +{ + return operand_equal_p (mem1->addr, mem2->addr, 0); +} + /* Sets for solving data flow equations in the memory optimization pass. */ struct tm_memopt_bitmaps { @@ -3185,7 +3222,7 @@ static bitmap_obstack tm_memopt_obstack; /* Unique counter for TM loads and stores. Loads and stores of the same address get the same ID. */ static unsigned int tm_memopt_value_id; -static htab_t tm_memopt_value_numbers; +static hash_table tm_memopt_value_numbers; #define STORE_AVAIL_IN(BB) \ ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in @@ -3208,29 +3245,6 @@ static htab_t tm_memopt_value_numbers; #define BB_VISITED_P(BB) \ ((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p -/* Htab support. Return a hash value for a `tm_memop'. */ -static hashval_t -tm_memop_hash (const void *p) -{ - const struct tm_memop *mem = (const struct tm_memop *) p; - tree addr = mem->addr; - /* We drill down to the SSA_NAME/DECL for the hash, but equality is - actually done with operand_equal_p (see tm_memop_eq). */ - if (TREE_CODE (addr) == ADDR_EXPR) - addr = TREE_OPERAND (addr, 0); - return iterative_hash_expr (addr, 0); -} - -/* Htab support. Return true if two tm_memop's are the same. */ -static int -tm_memop_eq (const void *p1, const void *p2) -{ - const struct tm_memop *mem1 = (const struct tm_memop *) p1; - const struct tm_memop *mem2 = (const struct tm_memop *) p2; - - return operand_equal_p (mem1->addr, mem2->addr, 0); -} - /* Given a TM load/store in STMT, return the value number for the address it accesses. */ @@ -3238,13 +3252,13 @@ static unsigned int tm_memopt_value_number (gimple stmt, enum insert_option op) { struct tm_memop tmpmem, *mem; - void **slot; + tm_memop **slot; gcc_assert (is_tm_load (stmt) || is_tm_store (stmt)); tmpmem.addr = gimple_call_arg (stmt, 0); - slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op); + slot = tm_memopt_value_numbers.find_slot (&tmpmem, op); if (*slot) - mem = (struct tm_memop *) *slot; + mem = *slot; else if (op == INSERT) { mem = XNEW (struct tm_memop); @@ -3302,11 +3316,11 @@ dump_tm_memopt_set (const char *set_name fprintf (dump_file, "TM memopt: %s: [", set_name); EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi) { - htab_iterator hi; - struct tm_memop *mem; + hash_table ::iterator hi; + struct tm_memop *mem = NULL; /* Yeah, yeah, yeah. Whatever. This is just for debugging. */ - FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi) if (mem->value_id == i) break; gcc_assert (mem->value_id == i); @@ -3741,7 +3755,7 @@ execute_tm_memopt (void) vec bbs; tm_memopt_value_id = 0; - tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free); + tm_memopt_value_numbers.create (10); for (region = all_tm_regions; region; region = region->next) { @@ -3775,10 +3789,10 @@ execute_tm_memopt (void) tm_memopt_free_sets (bbs); bbs.release (); bitmap_obstack_release (&tm_memopt_obstack); - htab_empty (tm_memopt_value_numbers); + tm_memopt_value_numbers.empty (); } - htab_delete (tm_memopt_value_numbers); + tm_memopt_value_numbers.dispose (); return 0; } Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 194487) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. #include "tree-flow.h" #include "gimple.h" #include "dumpfile.h" -#include "hashtab.h" +#include "hash-table.h" #include "alloc-pool.h" #include "flags.h" #include "bitmap.h" @@ -97,19 +97,187 @@ along with GCC; see the file COPYING3. structure copies. */ + +/* vn_nary_op hashtable helpers. */ + +struct vn_nary_op_hasher : typed_noop_remove +{ + typedef vn_nary_op_s value_type; + typedef vn_nary_op_s compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Return the computed hashcode for nary operation P1. */ + +inline hashval_t +vn_nary_op_hasher::hash (const value_type *vno1) +{ + return vno1->hashcode; +} + +/* Compare nary operations P1 and P2 and return true if they are + equivalent. */ + +inline bool +vn_nary_op_hasher::equal (const value_type *vno1, const compare_type *vno2) +{ + return vn_nary_op_eq (vno1, vno2); +} + +typedef hash_table vn_nary_op_table_type; +typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type; + + +/* vn_phi hashtable helpers. */ + +static int +vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2); + +struct vn_phi_hasher +{ + typedef vn_phi_s value_type; + typedef vn_phi_s compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; + +/* Return the computed hashcode for phi operation P1. */ + +inline hashval_t +vn_phi_hasher::hash (const value_type *vp1) +{ + return vp1->hashcode; +} + +/* Compare two phi entries for equality, ignoring VN_TOP arguments. */ + +inline bool +vn_phi_hasher::equal (const value_type *vp1, const compare_type *vp2) +{ + return vn_phi_eq (vp1, vp2); +} + +/* Free a phi operation structure VP. */ + +inline void +vn_phi_hasher::remove (value_type *phi) +{ + phi->phiargs.release (); +} + +typedef hash_table vn_phi_table_type; +typedef vn_phi_table_type::iterator vn_phi_iterator_type; + + +/* Compare two reference operands P1 and P2 for equality. Return true if + they are equal, and false otherwise. */ + +static int +vn_reference_op_eq (const void *p1, const void *p2) +{ + const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1; + const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2; + + return (vro1->opcode == vro2->opcode + /* We do not care for differences in type qualification. */ + && (vro1->type == vro2->type + || (vro1->type && vro2->type + && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type), + TYPE_MAIN_VARIANT (vro2->type)))) + && expressions_equal_p (vro1->op0, vro2->op0) + && expressions_equal_p (vro1->op1, vro2->op1) + && expressions_equal_p (vro1->op2, vro2->op2)); +} + +/* Free a reference operation structure VP. */ + +static inline void +free_reference (vn_reference_s *vr) +{ + vr->operands.release (); +} + + +/* vn_reference hashtable helpers. */ + +struct vn_reference_hasher +{ + typedef vn_reference_s value_type; + typedef vn_reference_s compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; + +/* Return the hashcode for a given reference operation P1. */ + +inline hashval_t +vn_reference_hasher::hash (const value_type *vr1) +{ + return vr1->hashcode; +} + +inline bool +vn_reference_hasher::equal (const value_type *v, const compare_type *c) +{ + return vn_reference_eq (v, c); +} + +inline void +vn_reference_hasher::remove (value_type *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. */ typedef struct vn_tables_s { - htab_t nary; - htab_t phis; - htab_t references; + vn_nary_op_table_type nary; + vn_phi_table_type phis; + vn_reference_table_type references; struct obstack nary_obstack; alloc_pool phis_pool; alloc_pool references_pool; } *vn_tables_t; -static htab_t constant_to_value_id; + +/* vn_constant hashtable helpers. */ + +struct vn_constant_hasher : typed_free_remove +{ + typedef vn_constant_s value_type; + typedef vn_constant_s compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Hash table hash function for vn_constant_t. */ + +inline hashval_t +vn_constant_hasher::hash (const value_type *vc1) +{ + return vc1->hashcode; +} + +/* Hash table equality function for vn_constant_t. */ + +inline bool +vn_constant_hasher::equal (const value_type *vc1, const compare_type *vc2) +{ + if (vc1->hashcode != vc2->hashcode) + return false; + + return vn_constant_eq_with_type (vc1->constant, vc2->constant); +} + +static hash_table constant_to_value_id; static bitmap constant_value_ids; @@ -339,62 +507,20 @@ vn_get_stmt_kind (gimple stmt) } } -/* Free a phi operation structure VP. */ - -static void -free_phi (void *vp) -{ - vn_phi_t phi = (vn_phi_t) vp; - phi->phiargs.release (); -} - -/* Free a reference operation structure VP. */ - -static void -free_reference (void *vp) -{ - vn_reference_t vr = (vn_reference_t) vp; - vr->operands.release (); -} - -/* Hash table equality function for vn_constant_t. */ - -static int -vn_constant_eq (const void *p1, const void *p2) -{ - const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1; - const struct vn_constant_s *vc2 = (const struct vn_constant_s *) p2; - - if (vc1->hashcode != vc2->hashcode) - return false; - - return vn_constant_eq_with_type (vc1->constant, vc2->constant); -} - -/* Hash table hash function for vn_constant_t. */ - -static hashval_t -vn_constant_hash (const void *p1) -{ - const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1; - return vc1->hashcode; -} - /* Lookup a value id for CONSTANT and return it. If it does not exist returns 0. */ unsigned int get_constant_value_id (tree constant) { - void **slot; + vn_constant_s **slot; struct vn_constant_s vc; vc.hashcode = vn_hash_constant_with_type (constant); vc.constant = constant; - slot = htab_find_slot_with_hash (constant_to_value_id, &vc, - vc.hashcode, NO_INSERT); + slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, NO_INSERT); if (slot) - return ((vn_constant_t)*slot)->value_id; + return (*slot)->value_id; return 0; } @@ -404,22 +530,21 @@ get_constant_value_id (tree constant) unsigned int get_or_alloc_constant_value_id (tree constant) { - void **slot; + vn_constant_s **slot; struct vn_constant_s vc; vn_constant_t vcp; vc.hashcode = vn_hash_constant_with_type (constant); vc.constant = constant; - slot = htab_find_slot_with_hash (constant_to_value_id, &vc, - vc.hashcode, INSERT); + slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, INSERT); if (*slot) - return ((vn_constant_t)*slot)->value_id; + return (*slot)->value_id; vcp = XNEW (struct vn_constant_s); vcp->hashcode = vc.hashcode; vcp->constant = constant; vcp->value_id = get_next_value_id (); - *slot = (void *) vcp; + *slot = vcp; bitmap_set_bit (constant_value_ids, vcp->value_id); return vcp->value_id; } @@ -432,26 +557,6 @@ value_id_constant_p (unsigned int v) return bitmap_bit_p (constant_value_ids, v); } -/* Compare two reference operands P1 and P2 for equality. Return true if - they are equal, and false otherwise. */ - -static int -vn_reference_op_eq (const void *p1, const void *p2) -{ - const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1; - const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2; - - return (vro1->opcode == vro2->opcode - /* We do not care for differences in type qualification. */ - && (vro1->type == vro2->type - || (vro1->type && vro2->type - && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type), - TYPE_MAIN_VARIANT (vro2->type)))) - && expressions_equal_p (vro1->op0, vro2->op0) - && expressions_equal_p (vro1->op1, vro2->op1) - && expressions_equal_p (vro1->op2, vro2->op2)); -} - /* Compute the hash for a reference operand VRO1. */ static hashval_t @@ -467,15 +572,6 @@ vn_reference_op_compute_hash (const vn_r return result; } -/* Return the hashcode for a given reference operation P1. */ - -static hashval_t -vn_reference_hash (const void *p1) -{ - const_vn_reference_t const vr1 = (const_vn_reference_t) p1; - return vr1->hashcode; -} - /* Compute a hash for the reference operation VR1 and return it. */ hashval_t @@ -525,16 +621,14 @@ vn_reference_compute_hash (const vn_refe return result; } -/* Return true if reference operations P1 and P2 are equivalent. This +/* Return true if reference operations VR1 and VR2 are equivalent. This means they have the same set of operands and vuses. */ -int -vn_reference_eq (const void *p1, const void *p2) +bool +vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2) { unsigned i, j; - const_vn_reference_t const vr1 = (const_vn_reference_t) p1; - const_vn_reference_t const vr2 = (const_vn_reference_t) p2; if (vr1->hashcode != vr2->hashcode) return false; @@ -1347,15 +1441,13 @@ valueize_shared_reference_ops_from_call static tree vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult) { - void **slot; + vn_reference_s **slot; hashval_t hash; hash = vr->hashcode; - slot = htab_find_slot_with_hash (current_info->references, vr, - hash, NO_INSERT); + slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT); if (!slot && current_info == optimistic_info) - slot = htab_find_slot_with_hash (valid_info->references, vr, - hash, NO_INSERT); + slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT); if (slot) { if (vnresult) @@ -1378,7 +1470,7 @@ vn_reference_lookup_2 (ao_ref *op ATTRIB unsigned int cnt, void *vr_) { vn_reference_t vr = (vn_reference_t)vr_; - void **slot; + vn_reference_s **slot; hashval_t hash; /* This bounds the stmt walks we perform on reference lookups @@ -1398,11 +1490,9 @@ vn_reference_lookup_2 (ao_ref *op ATTRIB vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse); hash = vr->hashcode; - slot = htab_find_slot_with_hash (current_info->references, vr, - hash, NO_INSERT); + slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT); if (!slot && current_info == optimistic_info) - slot = htab_find_slot_with_hash (valid_info->references, vr, - hash, NO_INSERT); + slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT); if (slot) return *slot; @@ -2005,7 +2095,7 @@ vn_reference_lookup (tree op, tree vuse, vn_reference_t vn_reference_insert (tree op, tree result, tree vuse, tree vdef) { - void **slot; + vn_reference_s **slot; vn_reference_t vr1; vr1 = (vn_reference_t) pool_alloc (current_info->references_pool); @@ -2021,8 +2111,8 @@ vn_reference_insert (tree op, tree resul vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result; vr1->result_vdef = vdef; - slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode, - INSERT); + slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode, + INSERT); /* Because we lookup stores using vuses, and value number failures using the vdefs (see visit_reference_op_store for how and why), @@ -2050,7 +2140,7 @@ vn_reference_insert_pieces (tree vuse, a tree result, unsigned int value_id) { - void **slot; + vn_reference_s **slot; vn_reference_t vr1; vr1 = (vn_reference_t) pool_alloc (current_info->references_pool); @@ -2064,8 +2154,8 @@ vn_reference_insert_pieces (tree vuse, a result = SSA_VAL (result); vr1->result = result; - slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode, - INSERT); + slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode, + INSERT); /* At this point we should have all the things inserted that we have seen before, and we should never try inserting something that @@ -2106,23 +2196,12 @@ vn_nary_op_compute_hash (const vn_nary_o return hash; } -/* Return the computed hashcode for nary operation P1. */ - -static hashval_t -vn_nary_op_hash (const void *p1) -{ - const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1; - return vno1->hashcode; -} - -/* Compare nary operations P1 and P2 and return true if they are +/* Compare nary operations VNO1 and VNO2 and return true if they are equivalent. */ -int -vn_nary_op_eq (const void *p1, const void *p2) +bool +vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2) { - const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1; - const_vn_nary_op_t const vno2 = (const_vn_nary_op_t) p2; unsigned i; if (vno1->hashcode != vno2->hashcode) @@ -2239,22 +2318,20 @@ init_vn_nary_op_from_stmt (vn_nary_op_t static tree vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult) { - void **slot; + vn_nary_op_s **slot; if (vnresult) *vnresult = NULL; vno->hashcode = vn_nary_op_compute_hash (vno); - slot = htab_find_slot_with_hash (current_info->nary, vno, vno->hashcode, - NO_INSERT); + slot = current_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT); if (!slot && current_info == optimistic_info) - slot = htab_find_slot_with_hash (valid_info->nary, vno, vno->hashcode, - NO_INSERT); + slot = valid_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT); if (!slot) return NULL_TREE; if (vnresult) - *vnresult = (vn_nary_op_t)*slot; - return ((vn_nary_op_t)*slot)->result; + *vnresult = *slot; + return (*slot)->result; } /* Lookup a n-ary operation by its pieces and return the resulting value @@ -2332,14 +2409,15 @@ alloc_vn_nary_op (unsigned int length, t VNO->HASHCODE first. */ static vn_nary_op_t -vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash) +vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type table, + bool compute_hash) { - void **slot; + vn_nary_op_s **slot; if (compute_hash) vno->hashcode = vn_nary_op_compute_hash (vno); - slot = htab_find_slot_with_hash (table, vno, vno->hashcode, INSERT); + slot = table.find_slot_with_hash (vno, vno->hashcode, INSERT); gcc_assert (!*slot); *slot = vno; @@ -2417,23 +2495,11 @@ vn_phi_compute_hash (vn_phi_t vp1) return result; } -/* Return the computed hashcode for phi operation P1. */ - -static hashval_t -vn_phi_hash (const void *p1) -{ - const_vn_phi_t const vp1 = (const_vn_phi_t) p1; - return vp1->hashcode; -} - /* Compare two phi entries for equality, ignoring VN_TOP arguments. */ static int -vn_phi_eq (const void *p1, const void *p2) +vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2) { - const_vn_phi_t const vp1 = (const_vn_phi_t) p1; - const_vn_phi_t const vp2 = (const_vn_phi_t) p2; - if (vp1->hashcode != vp2->hashcode) return false; @@ -2472,7 +2538,7 @@ static vec shared_lookup_phiargs; static tree vn_phi_lookup (gimple phi) { - void **slot; + vn_phi_s **slot; struct vn_phi_s vp1; unsigned i; @@ -2488,14 +2554,12 @@ vn_phi_lookup (gimple phi) vp1.phiargs = shared_lookup_phiargs; vp1.block = gimple_bb (phi); vp1.hashcode = vn_phi_compute_hash (&vp1); - slot = htab_find_slot_with_hash (current_info->phis, &vp1, vp1.hashcode, - NO_INSERT); + slot = current_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT); if (!slot && current_info == optimistic_info) - slot = htab_find_slot_with_hash (valid_info->phis, &vp1, vp1.hashcode, - NO_INSERT); + slot = valid_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT); if (!slot) return NULL_TREE; - return ((vn_phi_t)*slot)->result; + return (*slot)->result; } /* Insert PHI into the current hash table with a value number of @@ -2504,7 +2568,7 @@ vn_phi_lookup (gimple phi) static vn_phi_t vn_phi_insert (gimple phi, tree result) { - void **slot; + vn_phi_s **slot; vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool); unsigned i; vec args = vNULL; @@ -2522,8 +2586,7 @@ vn_phi_insert (gimple phi, tree result) vp1->result = result; vp1->hashcode = vn_phi_compute_hash (vp1); - slot = htab_find_slot_with_hash (current_info->phis, vp1, vp1->hashcode, - INSERT); + slot = current_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.*/ @@ -2731,7 +2794,7 @@ visit_reference_op_call (tree lhs, gimpl } else { - void **slot; + vn_reference_s **slot; vn_reference_t vr2; if (vdef) changed |= set_ssa_val_to (vdef, vdef); @@ -2745,8 +2808,8 @@ visit_reference_op_call (tree lhs, gimpl vr2->hashcode = vr1.hashcode; vr2->result = lhs; vr2->result_vdef = vdef; - slot = htab_find_slot_with_hash (current_info->references, - vr2, vr2->hashcode, INSERT); + slot = current_info->references.find_slot_with_hash (vr2, vr2->hashcode, + INSERT); if (*slot) free_reference (*slot); *slot = vr2; @@ -3566,10 +3629,10 @@ static void copy_phi (vn_phi_t ophi, vn_tables_t info) { vn_phi_t phi = (vn_phi_t) pool_alloc (info->phis_pool); - void **slot; + vn_phi_s **slot; memcpy (phi, ophi, sizeof (*phi)); ophi->phiargs.create (0); - slot = htab_find_slot_with_hash (info->phis, phi, phi->hashcode, INSERT); + slot = info->phis.find_slot_with_hash (phi, phi->hashcode, INSERT); gcc_assert (!*slot); *slot = phi; } @@ -3580,12 +3643,11 @@ static void copy_reference (vn_reference_t oref, vn_tables_t info) { vn_reference_t ref; - void **slot; + vn_reference_s **slot; ref = (vn_reference_t) pool_alloc (info->references_pool); memcpy (ref, oref, sizeof (*ref)); oref->operands.create (0); - slot = htab_find_slot_with_hash (info->references, ref, ref->hashcode, - INSERT); + slot = info->references.find_slot_with_hash (ref, ref->hashcode, INSERT); if (*slot) free_reference (*slot); *slot = ref; @@ -3600,7 +3662,9 @@ process_scc (vec scc) unsigned int i; unsigned int iterations = 0; bool changed = true; - htab_iterator hi; + 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; @@ -3637,9 +3701,9 @@ 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. */ - htab_empty (optimistic_info->nary); - htab_empty (optimistic_info->phis); - htab_empty (optimistic_info->references); + 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); empty_alloc_pool (optimistic_info->phis_pool); @@ -3654,11 +3718,12 @@ process_scc (vec scc) /* Finally, copy the contents of the no longer used optimistic table to the valid table. */ - FOR_EACH_HTAB_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hin) copy_nary (nary, valid_info); - FOR_EACH_HTAB_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hip) copy_phi (phi, valid_info); - FOR_EACH_HTAB_ELEMENT (optimistic_info->references, ref, vn_reference_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->references, + ref, vn_reference_t, hir) copy_reference (ref, valid_info); current_info = valid_info; @@ -3818,10 +3883,9 @@ continue_walking: static void allocate_vn_table (vn_tables_t table) { - table->phis = htab_create (23, vn_phi_hash, vn_phi_eq, free_phi); - table->nary = htab_create (23, vn_nary_op_hash, vn_nary_op_eq, NULL); - table->references = htab_create (23, vn_reference_hash, vn_reference_eq, - free_reference); + table->phis.create (23); + table->nary.create (23); + table->references.create (23); gcc_obstack_init (&table->nary_obstack); table->phis_pool = create_alloc_pool ("VN phis", @@ -3837,9 +3901,9 @@ allocate_vn_table (vn_tables_t table) static void free_vn_table (vn_tables_t table) { - htab_delete (table->phis); - htab_delete (table->nary); - htab_delete (table->references); + table->phis.dispose (); + table->nary.dispose (); + table->references.dispose (); obstack_free (&table->nary_obstack, NULL); free_alloc_pool (table->phis_pool); free_alloc_pool (table->references_pool); @@ -3854,8 +3918,7 @@ init_scc_vn (void) calculate_dominance_info (CDI_DOMINATORS); sccstack.create (0); - constant_to_value_id = htab_create (23, vn_constant_hash, vn_constant_eq, - free); + constant_to_value_id.create (23); constant_value_ids = BITMAP_ALLOC (NULL); @@ -3911,7 +3974,7 @@ free_scc_vn (void) { size_t i; - htab_delete (constant_to_value_id); + constant_to_value_id.dispose (); BITMAP_FREE (constant_value_ids); shared_lookup_phiargs.release (); shared_lookup_references.release (); @@ -3953,7 +4016,9 @@ set_value_id_for_result (tree result, un static void set_hashtable_value_ids (void) { - htab_iterator hi; + vn_nary_op_iterator_type hin; + vn_phi_iterator_type hip; + vn_reference_iterator_type hir; vn_nary_op_t vno; vn_reference_t vr; vn_phi_t vp; @@ -3961,16 +4026,13 @@ set_hashtable_value_ids (void) /* Now set the value ids of the things we had put in the hash table. */ - FOR_EACH_HTAB_ELEMENT (valid_info->nary, - vno, vn_nary_op_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (valid_info->nary, vno, vn_nary_op_t, hin) set_value_id_for_result (vno->result, &vno->value_id); - FOR_EACH_HTAB_ELEMENT (valid_info->phis, - vp, vn_phi_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (valid_info->phis, vp, vn_phi_t, hip) set_value_id_for_result (vp->result, &vp->value_id); - FOR_EACH_HTAB_ELEMENT (valid_info->references, - vr, vn_reference_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (valid_info->references, vr, vn_reference_t, hir) set_value_id_for_result (vr->result, &vr->value_id); } Index: gcc/tree-ssa-sccvn.h =================================================================== --- gcc/tree-ssa-sccvn.h (revision 194487) +++ gcc/tree-ssa-sccvn.h (working copy) @@ -207,10 +207,11 @@ vn_reference_t vn_reference_insert_piece tree, unsigned int); hashval_t vn_nary_op_compute_hash (const vn_nary_op_t); -int vn_nary_op_eq (const void *, const void *); +bool vn_nary_op_eq (const_vn_nary_op_t const vno1, + const_vn_nary_op_t const vno2); bool vn_nary_may_trap (vn_nary_op_t); hashval_t vn_reference_compute_hash (const vn_reference_t); -int vn_reference_eq (const void *, const void *); +bool vn_reference_eq (const_vn_reference_t const, const_vn_reference_t const); unsigned int get_max_value_id (void); unsigned int get_next_value_id (void); unsigned int get_constant_value_id (tree); Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 194487) +++ gcc/Makefile.in (working copy) @@ -2269,7 +2269,7 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_CORE_H) \ $(FUNCTION_H) $(TM_H) coretypes.h \ langhooks.h domwalk.h $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) \ - $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASHTAB_H) \ + $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h dumpfile.h \ @@ -2367,7 +2367,7 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_F tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \ $(TM_H) coretypes.h dumpfile.h $(FLAGS_H) $(CFGLOOP_H) \ - alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) $(GIMPLE_H) \ + alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASH_TABLE_H) $(GIMPLE_H) \ $(TREE_INLINE_H) tree-ssa-propagate.h tree-ssa-sccvn.h \ $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h gimple-ssa-strength-reduction.o : gimple-ssa-strength-reduction.c $(CONFIG_H) \ @@ -3077,7 +3077,7 @@ valtrack.o : valtrack.c $(VALTRACK_H) $( coretypes.h $(TM_H) $(FUNCTION_H) $(REGS_H) $(EMIT_RTL_H) var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \ - $(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \ + $(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASH_TABLE_H) \ $(REGS_H) $(EXPR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \ cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) \ pointer-set.h $(RECOG_H) $(TM_P_H) $(TREE_PRETTY_PRINT_H) $(ALIAS_H) Index: gcc/hash-table.h =================================================================== --- gcc/hash-table.h (revision 194487) +++ gcc/hash-table.h (working copy) @@ -156,6 +156,47 @@ along with GCC; see the file COPYING3. hash_table > whatever_type_hash_table; + + HASH TABLE ITERATORS + + The hash table provides standard C++ iterators. For example, consider a + hash table of some_info. We wish to consume each element of the table: + + extern void consume (some_info *); + + We define a convenience typedef and the hash table: + + typedef hash_table info_table_type; + info_table_type info_table; + + Then we write the loop in typical C++ style: + + for (info_table_type::iterator iter = info_table.begin (); + iter != info_table.end (); + ++iter) + if ((*iter).status == INFO_READY) + consume (&*iter); + + Or with common sub-expression elimination: + + for (info_table_type::iterator iter = info_table.begin (); + iter != info_table.end (); + ++iter) + { + some_info &elem = *iter; + if (elem.status == INFO_READY) + consume (&elem); + } + + One can also use a more typical GCC style: + + typedef some_info *some_info_p; + some_info *elem_ptr; + info_table_type::iterator iter; + FOR_EACH_HASH_TABLE_ELEMENT (info_table, elem_ptr, some_info_p, iter) + if (elem_ptr->status == INFO_READY) + consume (elem_ptr); + */ @@ -369,6 +410,20 @@ public: typedef typename Descriptor::value_type value_type; typedef typename Descriptor::compare_type compare_type; + class iterator + { + public: + inline iterator (); + inline iterator (value_type **, value_type **); + inline value_type &operator * (); + void slide (); + inline iterator &operator ++ (); + inline bool operator != (const iterator &) const; + private: + value_type **slot_; + value_type **limit_; + }; + private: hash_table_control *htab; @@ -401,6 +456,9 @@ public: template void traverse (Argument argument); + + iterator begin(); + iterator end(); }; @@ -893,4 +951,114 @@ hash_table ::trav traverse_noresize (argument); } + +/* Iterator definitions. */ + +/* The default constructor produces the end value. */ + +template class Allocator> +inline +hash_table ::iterator::iterator () +: slot_ (NULL), limit_ (NULL) +{ +} + +/* The parameterized constructor produces the begin value. */ + +template class Allocator> +inline +hash_table ::iterator::iterator + (value_type **slot, value_type **limit) +: slot_ (slot), limit_ (limit) +{ +} + +/* Obtain the element. */ + +template class Allocator> +inline typename hash_table ::value_type & +hash_table ::iterator::operator * () +{ + return **slot_; +} + +/* Slide down the iterator slots until an active entry is found. */ + +template class Allocator> +void +hash_table ::iterator::slide () +{ + for ( ; slot_ < limit_; ++slot_ ) + { + value_type *x = *slot_; + if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) + return; + } + slot_ = NULL; + limit_ = NULL; +} + +/* Bump the iterator. */ + +template class Allocator> +inline typename hash_table ::iterator & +hash_table ::iterator::operator ++ () +{ + ++slot_; + slide (); + return *this; +} + +/* Compare iterators. */ + +template class Allocator> +inline bool +hash_table ::iterator:: + operator != (const iterator &other) const +{ + return slot_ != other.slot_ || limit_ != other.limit_; +} + +/* Hash table iterator producers. */ + +/* The beginning of a hash table iteration. */ + +template class Allocator> +inline typename hash_table ::iterator +hash_table ::begin () +{ + iterator hti (htab->entries, htab->entries + htab->size); + hti.slide (); + return hti; +} + +/* The end of a hash table iteration. */ + +template class Allocator> +inline typename hash_table ::iterator +hash_table ::end () +{ + return iterator (); +} + +/* Iterate through the elements of hash_table HTAB, + using hash_table <....>::iterator ITER, + storing each element in RESULT, which is of type TYPE. + + This macro has this form for compatibility with the + FOR_EACH_HTAB_ELEMENT currently defined in tree-flow.h. */ + +#define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \ + for ((ITER) = (HTAB).begin (); \ + (ITER) != (HTAB).end () ? (RESULT = &*(ITER) , true) : false; \ + ++(ITER)) + #endif /* TYPED_HASHTAB_H */