Commit 84baa4b9 by Trevor Saunders Committed by Trevor Saunders

allow storing values directly in hash tables

gcc/

	* hash-table.h: Add a template arg to choose between storing values
	and storing pointers to values, and then provide partial
	specializations for both.
	* tree-browser.c (tree_upper_hasher): Provide the type the hash table
	should store, not the type values should point to.
	* tree-into-ssa.c (var_info_hasher): Likewise.
	* tree-ssa-dom.c (expr_elt_hasher): Likewise.
	* tree-complex.c: Adjust.
	* tree-hasher.h (int_tree_hasher): store int_tree_map in the hash
	table instead of int_tree_map *.
	* tree-parloops.c: Adjust.
	* tree-ssa-reassoc.c (ocount_hasher): Don't lie to hash_map about what
	type is being stored.
	* tree-vectorizer.c: Adjust.

From-SVN: r211937
parent c203e8a7
2014-06-24 Trevor Saunders <tsaunders@mozilla.com> 2014-06-24 Trevor Saunders <tsaunders@mozilla.com>
* hash-table.h: Add a template arg to choose between storing values
and storing pointers to values, and then provide partial
specializations for both.
* tree-browser.c (tree_upper_hasher): Provide the type the hash table
should store, not the type values should point to.
* tree-into-ssa.c (var_info_hasher): Likewise.
* tree-ssa-dom.c (expr_elt_hasher): Likewise.
* tree-complex.c: Adjust.
* tree-hasher.h (int_tree_hasher): store int_tree_map in the hash
table instead of int_tree_map *.
* tree-parloops.c: Adjust.
* tree-ssa-reassoc.c (ocount_hasher): Don't lie to hash_map about what
type is being stored.
* tree-vectorizer.c: Adjust.
2014-06-24 Trevor Saunders <tsaunders@mozilla.com>
* hash-table.h: Remove a layer of indirection from hash_table so that * hash-table.h: Remove a layer of indirection from hash_table so that
it contains the hash table's data instead of a pointer to the data. it contains the hash table's data instead of a pointer to the data.
* alloc-pool.c, asan.c, attribs.c, bitmap.c, cfg.c, * alloc-pool.c, asan.c, attribs.c, bitmap.c, cfg.c,
......
...@@ -102,22 +102,13 @@ static tree TB_history_prev (void); ...@@ -102,22 +102,13 @@ static tree TB_history_prev (void);
void browse_tree (tree); void browse_tree (tree);
/* Hashtable helpers. */ /* Hashtable helpers. */
struct tree_upper_hasher : typed_noop_remove <tree_node> struct tree_upper_hasher : pointer_hash<tree_node>
{ {
typedef tree_node value_type; static inline bool equal (const value_type &, const compare_type &);
typedef tree_node compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
}; };
inline hashval_t
tree_upper_hasher::hash (const value_type *v)
{
return pointer_hash <value_type>::hash (v);
}
inline bool inline bool
tree_upper_hasher::equal (const value_type *parent, const compare_type *node) tree_upper_hasher::equal (const value_type &parent, const compare_type &node)
{ {
if (parent == NULL || node == NULL) if (parent == NULL || node == NULL)
return 0; return 0;
......
...@@ -83,10 +83,9 @@ static vec<tree> complex_ssa_name_components; ...@@ -83,10 +83,9 @@ static vec<tree> complex_ssa_name_components;
static tree static tree
cvc_lookup (unsigned int uid) cvc_lookup (unsigned int uid)
{ {
struct int_tree_map *h, in; struct int_tree_map in;
in.uid = uid; in.uid = uid;
h = complex_variable_components->find_with_hash (&in, uid); return complex_variable_components->find_with_hash (in, uid).to;
return h ? h->to : NULL;
} }
/* Insert the pair UID, TO into the complex_variable_components hashtable. */ /* Insert the pair UID, TO into the complex_variable_components hashtable. */
...@@ -94,14 +93,13 @@ cvc_lookup (unsigned int uid) ...@@ -94,14 +93,13 @@ cvc_lookup (unsigned int uid)
static void static void
cvc_insert (unsigned int uid, tree to) cvc_insert (unsigned int uid, tree to)
{ {
struct int_tree_map *h; int_tree_map h;
int_tree_map **loc; int_tree_map *loc;
h = XNEW (struct int_tree_map); h.uid = uid;
h->uid = uid;
h->to = to;
loc = complex_variable_components->find_slot_with_hash (h, uid, INSERT); loc = complex_variable_components->find_slot_with_hash (h, uid, INSERT);
*loc = h; loc->uid = uid;
loc->to = to;
} }
/* Return true if T is not a zero constant. In the case of real values, /* Return true if T is not a zero constant. In the case of real values,
......
...@@ -30,28 +30,37 @@ struct int_tree_map { ...@@ -30,28 +30,37 @@ struct int_tree_map {
/* Hashtable helpers. */ /* Hashtable helpers. */
struct int_tree_hasher : typed_free_remove <int_tree_map> struct int_tree_hasher
{ {
typedef int_tree_map value_type; typedef int_tree_map value_type;
typedef int_tree_map compare_type; typedef int_tree_map compare_type;
static inline hashval_t hash (const value_type *); typedef int store_values_directly;
static inline bool equal (const value_type *, const compare_type *); static inline hashval_t hash (const value_type &);
static inline bool equal (const value_type &, const compare_type &);
static bool is_deleted (const value_type &v)
{
return v.to == reinterpret_cast<tree> (1);
}
static void mark_deleted (value_type &v) { v.to = reinterpret_cast<tree> (0x1); }
static bool is_empty (const value_type &v) { return v.to == NULL; }
static void mark_empty (value_type &v) { v.to = NULL; }
static void remove (value_type &) {}
}; };
/* Hash a UID in a int_tree_map. */ /* Hash a UID in a int_tree_map. */
inline hashval_t inline hashval_t
int_tree_hasher::hash (const value_type *item) int_tree_hasher::hash (const value_type &item)
{ {
return item->uid; return item.uid;
} }
/* Return true if the uid in both int tree maps are equal. */ /* Return true if the uid in both int tree maps are equal. */
inline bool inline bool
int_tree_hasher::equal (const value_type *a, const compare_type *b) int_tree_hasher::equal (const value_type &a, const compare_type &b)
{ {
return (a->uid == b->uid); return (a.uid == b.uid);
} }
typedef hash_table <int_tree_hasher> int_tree_htab_type; typedef hash_table <int_tree_hasher> int_tree_htab_type;
......
...@@ -203,20 +203,21 @@ typedef struct var_info_d *var_info_p; ...@@ -203,20 +203,21 @@ typedef struct var_info_d *var_info_p;
struct var_info_hasher : typed_free_remove <var_info_d> struct var_info_hasher : typed_free_remove <var_info_d>
{ {
typedef var_info_d value_type; typedef var_info_d *value_type;
typedef var_info_d compare_type; typedef var_info_d *compare_type;
static inline hashval_t hash (const value_type *); typedef int store_values_directly;
static inline bool equal (const value_type *, const compare_type *); static inline hashval_t hash (const value_type &);
static inline bool equal (const value_type &, const compare_type &);
}; };
inline hashval_t inline hashval_t
var_info_hasher::hash (const value_type *p) var_info_hasher::hash (const value_type &p)
{ {
return DECL_UID (p->var); return DECL_UID (p->var);
} }
inline bool inline bool
var_info_hasher::equal (const value_type *p1, const compare_type *p2) var_info_hasher::equal (const value_type &p1, const compare_type &p2)
{ {
return p1->var == p2->var; return p1->var == p2->var;
} }
......
...@@ -489,8 +489,6 @@ take_address_of (tree obj, tree type, edge entry, ...@@ -489,8 +489,6 @@ take_address_of (tree obj, tree type, edge entry,
int_tree_htab_type *decl_address, gimple_stmt_iterator *gsi) int_tree_htab_type *decl_address, gimple_stmt_iterator *gsi)
{ {
int uid; int uid;
int_tree_map **dslot;
struct int_tree_map ielt, *nielt;
tree *var_p, name, addr; tree *var_p, name, addr;
gimple stmt; gimple stmt;
gimple_seq stmts; gimple_seq stmts;
...@@ -511,9 +509,10 @@ take_address_of (tree obj, tree type, edge entry, ...@@ -511,9 +509,10 @@ take_address_of (tree obj, tree type, edge entry,
in the address and share it for all accesses and addresses based in the address and share it for all accesses and addresses based
on it. */ on it. */
uid = DECL_UID (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0)); uid = DECL_UID (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0));
ielt.uid = uid; int_tree_map elt;
dslot = decl_address->find_slot_with_hash (&ielt, uid, INSERT); elt.uid = uid;
if (!*dslot) int_tree_map *slot = decl_address->find_slot (elt, INSERT);
if (!slot->to)
{ {
if (gsi == NULL) if (gsi == NULL)
return NULL; return NULL;
...@@ -527,13 +526,11 @@ take_address_of (tree obj, tree type, edge entry, ...@@ -527,13 +526,11 @@ take_address_of (tree obj, tree type, edge entry,
stmt = gimple_build_assign (name, addr); stmt = gimple_build_assign (name, addr);
gsi_insert_on_edge_immediate (entry, stmt); gsi_insert_on_edge_immediate (entry, stmt);
nielt = XNEW (struct int_tree_map); slot->uid = uid;
nielt->uid = uid; slot->to = name;
nielt->to = name;
*dslot = nielt;
} }
else else
name = (*dslot)->to; name = slot->to;
/* Express the address in terms of the canonical SSA name. */ /* Express the address in terms of the canonical SSA name. */
TREE_OPERAND (*var_p, 0) = name; TREE_OPERAND (*var_p, 0) = name;
...@@ -822,10 +819,10 @@ separate_decls_in_region_name (tree name, name_to_copy_table_type *name_copies, ...@@ -822,10 +819,10 @@ separate_decls_in_region_name (tree name, name_to_copy_table_type *name_copies,
{ {
tree copy, var, var_copy; tree copy, var, var_copy;
unsigned idx, uid, nuid; unsigned idx, uid, nuid;
struct int_tree_map ielt, *nielt; struct int_tree_map ielt;
struct name_to_copy_elt elt, *nelt; struct name_to_copy_elt elt, *nelt;
name_to_copy_elt **slot; name_to_copy_elt **slot;
int_tree_map **dslot; int_tree_map *dslot;
if (TREE_CODE (name) != SSA_NAME) if (TREE_CODE (name) != SSA_NAME)
return name; return name;
...@@ -858,29 +855,25 @@ separate_decls_in_region_name (tree name, name_to_copy_table_type *name_copies, ...@@ -858,29 +855,25 @@ separate_decls_in_region_name (tree name, name_to_copy_table_type *name_copies,
uid = DECL_UID (var); uid = DECL_UID (var);
ielt.uid = uid; ielt.uid = uid;
dslot = decl_copies->find_slot_with_hash (&ielt, uid, INSERT); dslot = decl_copies->find_slot_with_hash (ielt, uid, INSERT);
if (!*dslot) if (!dslot->to)
{ {
var_copy = create_tmp_var (TREE_TYPE (var), get_name (var)); var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
DECL_GIMPLE_REG_P (var_copy) = DECL_GIMPLE_REG_P (var); DECL_GIMPLE_REG_P (var_copy) = DECL_GIMPLE_REG_P (var);
nielt = XNEW (struct int_tree_map); dslot->uid = uid;
nielt->uid = uid; dslot->to = var_copy;
nielt->to = var_copy;
*dslot = nielt;
/* Ensure that when we meet this decl next time, we won't duplicate /* Ensure that when we meet this decl next time, we won't duplicate
it again. */ it again. */
nuid = DECL_UID (var_copy); nuid = DECL_UID (var_copy);
ielt.uid = nuid; ielt.uid = nuid;
dslot = decl_copies->find_slot_with_hash (&ielt, nuid, INSERT); dslot = decl_copies->find_slot_with_hash (ielt, nuid, INSERT);
gcc_assert (!*dslot); gcc_assert (!dslot->to);
nielt = XNEW (struct int_tree_map); dslot->uid = nuid;
nielt->uid = nuid; dslot->to = var_copy;
nielt->to = var_copy;
*dslot = nielt;
} }
else else
var_copy = ((struct int_tree_map *) *dslot)->to; var_copy = dslot->to;
replace_ssa_name_symbol (copy, var_copy); replace_ssa_name_symbol (copy, var_copy);
return copy; return copy;
...@@ -944,7 +937,7 @@ separate_decls_in_region_debug (gimple stmt, ...@@ -944,7 +937,7 @@ separate_decls_in_region_debug (gimple stmt,
struct int_tree_map ielt; struct int_tree_map ielt;
struct name_to_copy_elt elt; struct name_to_copy_elt elt;
name_to_copy_elt **slot; name_to_copy_elt **slot;
int_tree_map **dslot; int_tree_map *dslot;
if (gimple_debug_bind_p (stmt)) if (gimple_debug_bind_p (stmt))
var = gimple_debug_bind_get_var (stmt); var = gimple_debug_bind_get_var (stmt);
...@@ -956,13 +949,13 @@ separate_decls_in_region_debug (gimple stmt, ...@@ -956,13 +949,13 @@ separate_decls_in_region_debug (gimple stmt,
return true; return true;
gcc_assert (DECL_P (var) && SSA_VAR_P (var)); gcc_assert (DECL_P (var) && SSA_VAR_P (var));
ielt.uid = DECL_UID (var); ielt.uid = DECL_UID (var);
dslot = decl_copies->find_slot_with_hash (&ielt, ielt.uid, NO_INSERT); dslot = decl_copies->find_slot_with_hash (ielt, ielt.uid, NO_INSERT);
if (!dslot) if (!dslot)
return true; return true;
if (gimple_debug_bind_p (stmt)) if (gimple_debug_bind_p (stmt))
gimple_debug_bind_set_var (stmt, ((struct int_tree_map *) *dslot)->to); gimple_debug_bind_set_var (stmt, dslot->to);
else if (gimple_debug_source_bind_p (stmt)) else if (gimple_debug_source_bind_p (stmt))
gimple_debug_source_bind_set_var (stmt, ((struct int_tree_map *) *dslot)->to); gimple_debug_source_bind_set_var (stmt, dslot->to);
FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE) FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE)
{ {
......
...@@ -158,21 +158,22 @@ static void free_expr_hash_elt (void *); ...@@ -158,21 +158,22 @@ static void free_expr_hash_elt (void *);
struct expr_elt_hasher struct expr_elt_hasher
{ {
typedef expr_hash_elt value_type; typedef expr_hash_elt *value_type;
typedef expr_hash_elt compare_type; typedef expr_hash_elt *compare_type;
static inline hashval_t hash (const value_type *); typedef int store_values_directly;
static inline bool equal (const value_type *, const compare_type *); static inline hashval_t hash (const value_type &);
static inline void remove (value_type *); static inline bool equal (const value_type &, const compare_type &);
static inline void remove (value_type &);
}; };
inline hashval_t inline hashval_t
expr_elt_hasher::hash (const value_type *p) expr_elt_hasher::hash (const value_type &p)
{ {
return p->hash; return p->hash;
} }
inline bool inline bool
expr_elt_hasher::equal (const value_type *p1, const compare_type *p2) expr_elt_hasher::equal (const value_type &p1, const compare_type &p2)
{ {
gimple stmt1 = p1->stmt; gimple stmt1 = p1->stmt;
const struct hashable_expr *expr1 = &p1->expr; const struct hashable_expr *expr1 = &p1->expr;
...@@ -211,7 +212,7 @@ expr_elt_hasher::equal (const value_type *p1, const compare_type *p2) ...@@ -211,7 +212,7 @@ expr_elt_hasher::equal (const value_type *p1, const compare_type *p2)
/* Delete an expr_hash_elt and reclaim its storage. */ /* Delete an expr_hash_elt and reclaim its storage. */
inline void inline void
expr_elt_hasher::remove (value_type *element) expr_elt_hasher::remove (value_type &element)
{ {
free_expr_hash_elt (element); free_expr_hash_elt (element);
} }
......
...@@ -1023,32 +1023,36 @@ static vec<oecount> cvec; ...@@ -1023,32 +1023,36 @@ static vec<oecount> cvec;
/* Oecount hashtable helpers. */ /* Oecount hashtable helpers. */
struct oecount_hasher : typed_noop_remove <void> struct oecount_hasher
{ {
/* Note that this hash table stores integers, not pointers. typedef int value_type;
So, observe the casting in the member functions. */ typedef int compare_type;
typedef void value_type; typedef int store_values_directly;
typedef void compare_type; static inline hashval_t hash (const value_type &);
static inline hashval_t hash (const value_type *); static inline bool equal (const value_type &, const compare_type &);
static inline bool equal (const value_type *, const compare_type *); static bool is_deleted (int &v) { return v == 1; }
static void mark_deleted (int &e) { e = 1; }
static bool is_empty (int &v) { return v == 0; }
static void mark_empty (int &e) { e = 0; }
static void remove (int &) {}
}; };
/* Hash function for oecount. */ /* Hash function for oecount. */
inline hashval_t inline hashval_t
oecount_hasher::hash (const value_type *p) oecount_hasher::hash (const value_type &p)
{ {
const oecount *c = &cvec[(size_t)p - 42]; const oecount *c = &cvec[p - 42];
return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode; return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode;
} }
/* Comparison function for oecount. */ /* Comparison function for oecount. */
inline bool inline bool
oecount_hasher::equal (const value_type *p1, const compare_type *p2) oecount_hasher::equal (const value_type &p1, const compare_type &p2)
{ {
const oecount *c1 = &cvec[(size_t)p1 - 42]; const oecount *c1 = &cvec[p1 - 42];
const oecount *c2 = &cvec[(size_t)p2 - 42]; const oecount *c2 = &cvec[p2 - 42];
return (c1->oecode == c2->oecode return (c1->oecode == c2->oecode
&& c1->op == c2->op); && c1->op == c2->op);
} }
...@@ -1473,23 +1477,23 @@ undistribute_ops_list (enum tree_code opcode, ...@@ -1473,23 +1477,23 @@ undistribute_ops_list (enum tree_code opcode,
FOR_EACH_VEC_ELT (subops[i], j, oe1) FOR_EACH_VEC_ELT (subops[i], j, oe1)
{ {
oecount c; oecount c;
void **slot; int *slot;
size_t idx; int idx;
c.oecode = oecode; c.oecode = oecode;
c.cnt = 1; c.cnt = 1;
c.id = next_oecount_id++; c.id = next_oecount_id++;
c.op = oe1->op; c.op = oe1->op;
cvec.safe_push (c); cvec.safe_push (c);
idx = cvec.length () + 41; idx = cvec.length () + 41;
slot = ctable.find_slot ((void *)idx, INSERT); slot = ctable.find_slot (idx, INSERT);
if (!*slot) if (!*slot)
{ {
*slot = (void *)idx; *slot = idx;
} }
else else
{ {
cvec.pop (); cvec.pop ();
cvec[(size_t)*slot - 42].cnt++; cvec[*slot - 42].cnt++;
} }
} }
} }
......
...@@ -550,14 +550,14 @@ vectorize_loops (void) ...@@ -550,14 +550,14 @@ vectorize_loops (void)
for (hash_table<simd_array_to_simduid>::iterator iter for (hash_table<simd_array_to_simduid>::iterator iter
= simd_array_to_simduid_htab->begin (); = simd_array_to_simduid_htab->begin ();
iter != simd_array_to_simduid_htab->end (); ++iter) iter != simd_array_to_simduid_htab->end (); ++iter)
if ((*iter).simduid != -1U) if ((*iter)->simduid != -1U)
{ {
tree decl = (*iter).decl; tree decl = (*iter)->decl;
int vf = 1; int vf = 1;
if (simduid_to_vf_htab) if (simduid_to_vf_htab)
{ {
simduid_to_vf *p = NULL, data; simduid_to_vf *p = NULL, data;
data.simduid = (*iter).simduid; data.simduid = (*iter)->simduid;
p = simduid_to_vf_htab->find (&data); p = simduid_to_vf_htab->find (&data);
if (p) if (p)
vf = p->vf; vf = p->vf;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment