Add ty::new_ty_hash, clean up comparing of ty::t's

This commit is contained in:
Marijn Haverbeke 2011-12-22 14:24:36 +01:00
parent e2e077c831
commit 3ee630bbee
4 changed files with 30 additions and 49 deletions

View File

@ -653,7 +653,7 @@ fn encode_hash(ebml_w: ebml::writer, hash: str) {
fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str { fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str {
let abbrevs = map::mk_hashmap(ty::hash_ty, ty::eq_ty); let abbrevs = ty::new_ty_hash();
let ecx = @{ccx: cx, type_abbrevs: abbrevs}; let ecx = @{ccx: cx, type_abbrevs: abbrevs};
let string_w = io::string_writer(); let string_w = io::string_writer();

View File

@ -267,8 +267,7 @@ fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: @ast::ty)
let cache = get_cache(cx); let cache = get_cache(cx);
let tg = BasicTypeDescriptorTag; let tg = BasicTypeDescriptorTag;
alt cached_metadata::<@metadata<tydesc_md>>( alt cached_metadata::<@metadata<tydesc_md>>(
cache, tg, cache, tg, {|md| t == md.data.hash}) {
{|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) {
option::some(md) { ret md; } option::some(md) { ret md; }
option::none. {} option::none. {}
} }
@ -311,7 +310,7 @@ fn create_basic_type(cx: @crate_ctxt, t: ty::t, ty: @ast::ty)
lli32(0), //XXX flags? lli32(0), //XXX flags?
lli32(encoding)]; lli32(encoding)];
let llnode = llmdnode(lldata); let llnode = llmdnode(lldata);
let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; let mdval = @{node: llnode, data: {hash: t}};
update_cache(cache, tg, tydesc_metadata(mdval)); update_cache(cache, tg, tydesc_metadata(mdval));
add_named_metadata(cx, "llvm.dbg.ty", llnode); add_named_metadata(cx, "llvm.dbg.ty", llnode);
ret mdval; ret mdval;
@ -333,7 +332,7 @@ fn create_pointer_type(cx: @crate_ctxt, t: ty::t, span: codemap::span,
//let cu_node = create_compile_unit(cx, fname); //let cu_node = create_compile_unit(cx, fname);
let llnode = create_derived_type(tg, file_node.node, "", 0, size * 8, let llnode = create_derived_type(tg, file_node.node, "", 0, size * 8,
align * 8, 0, pointee.node); align * 8, 0, pointee.node);
let mdval = @{node: llnode, data: {hash: ty::hash_ty(t)}}; let mdval = @{node: llnode, data: {hash: t}};
//update_cache(cache, tg, tydesc_metadata(mdval)); //update_cache(cache, tg, tydesc_metadata(mdval));
add_named_metadata(cx, "llvm.dbg.ty", llnode); add_named_metadata(cx, "llvm.dbg.ty", llnode);
ret mdval; ret mdval;

View File

@ -4348,7 +4348,7 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, sp: span, llfndecl: ValueRef,
lllocals: new_int_hash::<local_val>(), lllocals: new_int_hash::<local_val>(),
llupvars: new_int_hash::<ValueRef>(), llupvars: new_int_hash::<ValueRef>(),
mutable lltydescs: [], mutable lltydescs: [],
derived_tydescs: map::mk_hashmap(ty::hash_ty, ty::eq_ty), derived_tydescs: ty::new_ty_hash(),
id: id, id: id,
ret_style: rstyle, ret_style: rstyle,
sp: sp, sp: sp,
@ -5642,13 +5642,6 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
tn.associate("taskptr", taskptr_type); tn.associate("taskptr", taskptr_type);
let tydesc_type = T_tydesc(targ_cfg); let tydesc_type = T_tydesc(targ_cfg);
tn.associate("tydesc", tydesc_type); tn.associate("tydesc", tydesc_type);
let hasher = ty::hash_ty;
let eqer = ty::eq_ty;
let tag_sizes = map::mk_hashmap::<ty::t, uint>(hasher, eqer);
let tydescs = map::mk_hashmap::<ty::t, @tydesc_info>(hasher, eqer);
let lltypes = map::mk_hashmap::<ty::t, TypeRef>(hasher, eqer);
let sha1s = map::mk_hashmap::<ty::t, str>(hasher, eqer);
let short_names = map::mk_hashmap::<ty::t, str>(hasher, eqer);
let crate_map = decl_crate_map(sess, link_meta.name, llmod); let crate_map = decl_crate_map(sess, link_meta.name, llmod);
let dbg_cx = if sess.get_opts().debuginfo { let dbg_cx = if sess.get_opts().debuginfo {
option::some(@{llmetadata: map::new_int_hash(), option::some(@{llmetadata: map::new_int_hash(),
@ -5669,18 +5662,18 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
item_symbols: new_int_hash::<str>(), item_symbols: new_int_hash::<str>(),
mutable main_fn: none::<ValueRef>, mutable main_fn: none::<ValueRef>,
link_meta: link_meta, link_meta: link_meta,
tag_sizes: tag_sizes, tag_sizes: ty::new_ty_hash(),
discrims: ast_util::new_def_id_hash::<ValueRef>(), discrims: ast_util::new_def_id_hash::<ValueRef>(),
discrim_symbols: new_int_hash::<str>(), discrim_symbols: new_int_hash::<str>(),
consts: new_int_hash::<ValueRef>(), consts: new_int_hash::<ValueRef>(),
obj_methods: new_int_hash::<()>(), obj_methods: new_int_hash::<()>(),
tydescs: tydescs, tydescs: ty::new_ty_hash(),
module_data: new_str_hash::<ValueRef>(), module_data: new_str_hash::<ValueRef>(),
lltypes: lltypes, lltypes: ty::new_ty_hash(),
names: namegen(0), names: namegen(0),
sha: sha, sha: sha,
type_sha1s: sha1s, type_sha1s: ty::new_ty_hash(),
type_short_names: short_names, type_short_names: ty::new_ty_hash(),
tcx: tcx, tcx: tcx,
mut_map: mut_map, mut_map: mut_map,
copy_map: copy_map, copy_map: copy_map,

View File

@ -36,7 +36,6 @@ export constr_table;
export count_ty_params; export count_ty_params;
export ctxt; export ctxt;
export def_has_ty_params; export def_has_ty_params;
export eq_ty;
export expr_has_ty_params; export expr_has_ty_params;
export expr_ty; export expr_ty;
export expr_ty_params_and_ty; export expr_ty_params_and_ty;
@ -47,7 +46,6 @@ export field_idx;
export get_field; export get_field;
export fm_general; export fm_general;
export get_element_type; export get_element_type;
export hash_ty;
export idx_nil; export idx_nil;
export is_binopable; export is_binopable;
export is_pred_ty; export is_pred_ty;
@ -103,6 +101,7 @@ export stmt_node_id;
export sty; export sty;
export substitute_type_params; export substitute_type_params;
export t; export t;
export new_ty_hash;
export tag_variants; export tag_variants;
export tag_variant_with_id; export tag_variant_with_id;
export ty_param_substs_opt_and_ty; export ty_param_substs_opt_and_ty;
@ -398,12 +397,16 @@ fn mk_rcache() -> creader_cache {
ret map::mk_hashmap(hash_cache_entry, eq_cache_entries); ret map::mk_hashmap(hash_cache_entry, eq_cache_entries);
} }
fn new_ty_hash<copy V>() -> map::hashmap<t, V> { map::new_uint_hash() }
fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
freevars: freevars::freevar_map) -> ctxt { freevars: freevars::freevar_map) -> ctxt {
let ntt: node_type_table = let ntt: node_type_table =
@smallintmap::mk::<ty::ty_param_substs_opt_and_ty>(); @smallintmap::mk::<ty::ty_param_substs_opt_and_ty>();
let tcache = new_def_hash::<ty::ty_param_kinds_and_ty>(); let tcache = new_def_hash::<ty::ty_param_kinds_and_ty>();
fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool {
ret a.hash == b.hash && a.struct == b.struct;
}
let ts = @interner::mk::<@raw_t>(hash_raw_ty, eq_raw_ty); let ts = @interner::mk::<@raw_t>(hash_raw_ty, eq_raw_ty);
let cx = let cx =
@{ts: ts, @{ts: ts,
@ -414,9 +417,9 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
freevars: freevars, freevars: freevars,
tcache: tcache, tcache: tcache,
rcache: mk_rcache(), rcache: mk_rcache(),
short_names_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty), short_names_cache: new_ty_hash(),
needs_drop_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty), needs_drop_cache: new_ty_hash(),
kind_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty), kind_cache: new_ty_hash(),
ast_ty_to_ty_cache: ast_ty_to_ty_cache:
map::mk_hashmap(ast_util::hash_ty, ast_util::eq_ty), map::mk_hashmap(ast_util::hash_ty, ast_util::eq_ty),
tag_var_cache: @smallintmap::mk()}; tag_var_cache: @smallintmap::mk()};
@ -1233,8 +1236,7 @@ fn type_autoderef(cx: ctxt, t: ty::t) -> ty::t {
ret t1; ret t1;
} }
// Type hashing. This function is private to this module (and slow); external // Type hashing.
// users should use `hash_ty()` instead.
fn hash_type_structure(st: sty) -> uint { fn hash_type_structure(st: sty) -> uint {
fn hash_uint(id: uint, n: uint) -> uint { fn hash_uint(id: uint, n: uint) -> uint {
let h = id; let h = id;
@ -1249,7 +1251,7 @@ fn hash_type_structure(st: sty) -> uint {
} }
fn hash_subty(id: uint, subty: t) -> uint { fn hash_subty(id: uint, subty: t) -> uint {
let h = id; let h = id;
h += (h << 5u) + hash_ty(subty); h += (h << 5u) + subty;
ret h; ret h;
} }
fn hash_subtys(id: uint, subtys: [t]) -> uint { fn hash_subtys(id: uint, subtys: [t]) -> uint {
@ -1284,8 +1286,8 @@ fn hash_type_structure(st: sty) -> uint {
fn hash_fn(id: uint, args: [arg], rty: t) -> uint { fn hash_fn(id: uint, args: [arg], rty: t) -> uint {
let h = id; let h = id;
for a: arg in args { h += (h << 5u) + hash_ty(a.ty); } for a: arg in args { h += (h << 5u) + a.ty; }
h += (h << 5u) + hash_ty(rty); h += (h << 5u) + rty;
ret h; ret h;
} }
alt st { alt st {
@ -1308,14 +1310,14 @@ fn hash_type_structure(st: sty) -> uint {
ty_str. { ret 17u; } ty_str. { ret 17u; }
ty_tag(did, tys) { ty_tag(did, tys) {
let h = hash_def(18u, did); let h = hash_def(18u, did);
for typ: t in tys { h += (h << 5u) + hash_ty(typ); } for typ: t in tys { h += (h << 5u) + typ; }
ret h; ret h;
} }
ty_box(mt) { ret hash_subty(19u, mt.ty); } ty_box(mt) { ret hash_subty(19u, mt.ty); }
ty_vec(mt) { ret hash_subty(21u, mt.ty); } ty_vec(mt) { ret hash_subty(21u, mt.ty); }
ty_rec(fields) { ty_rec(fields) {
let h = 26u; let h = 26u;
for f: field in fields { h += (h << 5u) + hash_ty(f.mt.ty); } for f: field in fields { h += (h << 5u) + f.mt.ty; }
ret h; ret h;
} }
ty_tup(ts) { ret hash_subtys(25u, ts); } ty_tup(ts) { ret hash_subtys(25u, ts); }
@ -1354,13 +1356,6 @@ fn hash_type_structure(st: sty) -> uint {
fn hash_raw_ty(&&rt: @raw_t) -> uint { ret rt.hash; } fn hash_raw_ty(&&rt: @raw_t) -> uint { ret rt.hash; }
fn hash_ty(&&typ: t) -> uint { ret typ; }
// Type equality. This function is private to this module (and slow); external
// users should use `eq_ty()` instead.
fn eq_int(&&x: uint, &&y: uint) -> bool { ret x == y; }
fn arg_eq<T>(eq: fn(T, T) -> bool, a: @sp_constr_arg<T>, b: @sp_constr_arg<T>) fn arg_eq<T>(eq: fn(T, T) -> bool, a: @sp_constr_arg<T>, b: @sp_constr_arg<T>)
-> bool { -> bool {
alt a.node { alt a.node {
@ -1389,6 +1384,7 @@ fn args_eq<T>(eq: fn(T, T) -> bool, a: [@sp_constr_arg<T>],
} }
fn constr_eq(c: @constr, d: @constr) -> bool { fn constr_eq(c: @constr, d: @constr) -> bool {
fn eq_int(&&x: uint, &&y: uint) -> bool { ret x == y; }
ret path_to_str(c.node.path) == path_to_str(d.node.path) && ret path_to_str(c.node.path) == path_to_str(d.node.path) &&
// FIXME: hack // FIXME: hack
args_eq(eq_int, c.node.args, d.node.args); args_eq(eq_int, c.node.args, d.node.args);
@ -1401,16 +1397,6 @@ fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool {
ret true; ret true;
} }
// This function is private to this module.
fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool {
ret a.hash == b.hash && a.struct == b.struct;
}
// This is the equality function the public should use. It works as long as
// the types are interned.
fn eq_ty(&&a: t, &&b: t) -> bool { a == b }
// Type lookups // Type lookups
fn node_id_to_ty_param_substs_opt_and_ty(cx: ctxt, id: ast::node_id) -> fn node_id_to_ty_param_substs_opt_and_ty(cx: ctxt, id: ast::node_id) ->
ty_param_substs_opt_and_ty { ty_param_substs_opt_and_ty {
@ -2088,12 +2074,15 @@ mod unify {
fn unify_step(cx: @ctxt, expected: t, actual: t, fn unify_step(cx: @ctxt, expected: t, actual: t,
variance: variance) -> result { variance: variance) -> result {
// TODO: rewrite this using tuple pattern matching when available, to // FIXME: rewrite this using tuple pattern matching when available, to
// avoid all this rightward drift and spikiness. // avoid all this rightward drift and spikiness.
// NOTE: we have tuple matching now, but that involves copying the
// matched elements into a tuple first, which is expensive, since sty
// holds vectors, which are currently unique
// Fast path. // Fast path.
if expected == actual { ret ures_ok(expected); }
if eq_ty(expected, actual) { ret ures_ok(expected); }
// Stage 1: Handle the cases in which one side or another is a type // Stage 1: Handle the cases in which one side or another is a type
// variable. // variable.