Skip to content

Commit bec7b76

Browse files
committed
rustc: Move to FNV hashing for node/def ids
This leverages the new hashing framework and hashmap implementation to provide a much speedier hashing algorithm for node ids and def ids. The hash algorithm used is currentl FNV hashing, but it's quite easy to swap out. I originally implemented hashing as the identity function, but this actually ended up in slowing down rustc compiling libstd from 8s to 13s. I would suspect that this is a result of a large number of collisions. With FNV hashing, we get these timings (compiling with --no-trans, in seconds): | | before | after | |-----------|---------:|--------:| | libstd | 8.324 | 6.703 | | stdtest | 47.674 | 46.857 | | libsyntax | 9.918 | 8.400 |
1 parent 0e95b08 commit bec7b76

27 files changed

+364
-195
lines changed

src/librustc/driver/driver.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use middle::{trans, freevars, kind, ty, typeck, lint, astencode, reachable};
2727
use middle;
2828
use util::common::time;
2929
use util::ppaux;
30+
use util::nodemap::NodeSet;
3031

3132
use serialize::{json, Encodable};
3233

@@ -38,7 +39,7 @@ use std::os;
3839
use std::vec;
3940
use std::vec_ng::Vec;
4041
use std::vec_ng;
41-
use collections::{HashMap, HashSet};
42+
use collections::HashMap;
4243
use getopts::{optopt, optmulti, optflag, optflagopt, opt};
4344
use MaybeHasArg = getopts::Maybe;
4445
use OccurOptional = getopts::Optional;
@@ -258,7 +259,7 @@ pub struct CrateAnalysis {
258259
public_items: middle::privacy::PublicItems,
259260
ty_cx: ty::ctxt,
260261
maps: astencode::Maps,
261-
reachable: @RefCell<HashSet<ast::NodeId>>
262+
reachable: @RefCell<NodeSet>,
262263
}
263264

264265
/// Run the resolution, typechecking, region checking and other

src/librustc/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ This API is completely unstable and subject to change.
2929

3030
#[allow(deprecated)];
3131
#[feature(macro_rules, globs, struct_variant, managed_boxes)];
32-
#[feature(quote)];
32+
#[feature(quote, default_type_params)];
3333

3434
extern crate extra;
3535
extern crate flate;
@@ -125,6 +125,7 @@ pub mod util {
125125
pub mod common;
126126
pub mod ppaux;
127127
pub mod sha2;
128+
pub mod nodemap;
128129
}
129130

130131
pub mod lib {

src/librustc/metadata/encoder.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use middle::astencode;
2323
use middle::ty;
2424
use middle::typeck;
2525
use middle;
26+
use util::nodemap::{NodeMap, NodeSet};
2627

2728
use serialize::Encodable;
2829
use std::cast;
@@ -31,7 +32,7 @@ use std::hash;
3132
use std::hash::Hash;
3233
use std::io::MemWriter;
3334
use std::str;
34-
use collections::{HashMap, HashSet};
35+
use collections::HashMap;
3536
use syntax::abi::AbiSet;
3637
use syntax::ast::*;
3738
use syntax::ast;
@@ -69,8 +70,8 @@ pub struct EncodeParams<'a> {
6970
diag: @SpanHandler,
7071
tcx: ty::ctxt,
7172
reexports2: middle::resolve::ExportMap2,
72-
item_symbols: &'a RefCell<HashMap<ast::NodeId, ~str>>,
73-
non_inlineable_statics: &'a RefCell<HashSet<ast::NodeId>>,
73+
item_symbols: &'a RefCell<NodeMap<~str>>,
74+
non_inlineable_statics: &'a RefCell<NodeSet>,
7475
link_meta: &'a LinkMeta,
7576
cstore: @cstore::CStore,
7677
encode_inlined_item: EncodeInlinedItem<'a>,
@@ -97,8 +98,8 @@ pub struct EncodeContext<'a> {
9798
tcx: ty::ctxt,
9899
stats: @Stats,
99100
reexports2: middle::resolve::ExportMap2,
100-
item_symbols: &'a RefCell<HashMap<ast::NodeId, ~str>>,
101-
non_inlineable_statics: &'a RefCell<HashSet<ast::NodeId>>,
101+
item_symbols: &'a RefCell<NodeMap<~str>>,
102+
non_inlineable_statics: &'a RefCell<NodeSet>,
102103
link_meta: &'a LinkMeta,
103104
cstore: &'a cstore::CStore,
104105
encode_inlined_item: EncodeInlinedItem<'a>,

src/librustc/middle/cfg/construct.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ use middle::cfg::*;
1212
use middle::graph;
1313
use middle::typeck;
1414
use middle::ty;
15-
use collections::HashMap;
1615
use syntax::ast;
1716
use syntax::ast_util;
1817
use syntax::opt_vec;
18+
use util::nodemap::NodeMap;
1919

2020
struct CFGBuilder {
2121
tcx: ty::ctxt,
2222
method_map: typeck::MethodMap,
23-
exit_map: HashMap<ast::NodeId, CFGIndex>,
23+
exit_map: NodeMap<CFGIndex>,
2424
graph: CFGGraph,
2525
loop_scopes: ~[LoopScope],
2626
}
@@ -35,7 +35,7 @@ pub fn construct(tcx: ty::ctxt,
3535
method_map: typeck::MethodMap,
3636
blk: &ast::Block) -> CFG {
3737
let mut cfg_builder = CFGBuilder {
38-
exit_map: HashMap::new(),
38+
exit_map: NodeMap::new(),
3939
graph: graph::Graph::new(),
4040
tcx: tcx,
4141
method_map: method_map,

src/librustc/middle/cfg/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ Uses `Graph` as the underlying representation.
1818
use middle::graph;
1919
use middle::ty;
2020
use middle::typeck;
21-
use collections::HashMap;
2221
use syntax::ast;
2322
use syntax::opt_vec::OptVec;
23+
use util::nodemap::NodeMap;
2424

2525
mod construct;
2626

2727
pub struct CFG {
28-
exit_map: HashMap<ast::NodeId, CFGIndex>,
28+
exit_map: NodeMap<CFGIndex>,
2929
graph: CFGGraph,
3030
entry: CFGIndex,
3131
exit: CFGIndex,

src/librustc/middle/const_eval.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use middle::astencode;
1616
use middle::ty;
1717
use middle::typeck::astconv;
1818
use middle;
19+
use util::nodemap::{DefIdMap, NodeMap};
1920

2021
use syntax::ast::*;
2122
use syntax::parse::token::InternedString;
@@ -66,7 +67,7 @@ pub enum constness {
6667
non_const
6768
}
6869

69-
type constness_cache = HashMap<ast::DefId, constness>;
70+
type constness_cache = DefIdMap<constness>;
7071

7172
pub fn join(a: constness, b: constness) -> constness {
7273
match (a, b) {
@@ -134,9 +135,9 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt,
134135
}
135136
let maps = astencode::Maps {
136137
root_map: @RefCell::new(HashMap::new()),
137-
method_map: @RefCell::new(HashMap::new()),
138-
vtable_map: @RefCell::new(HashMap::new()),
139-
capture_map: @RefCell::new(HashMap::new())
138+
method_map: @RefCell::new(NodeMap::new()),
139+
vtable_map: @RefCell::new(NodeMap::new()),
140+
capture_map: @RefCell::new(NodeMap::new())
140141
};
141142
let e = match csearch::maybe_get_item_ast(tcx, enum_def,
142143
|a, b, c, d| astencode::decode_inlined_item(a, b,
@@ -184,9 +185,9 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::DefId)
184185
}
185186
let maps = astencode::Maps {
186187
root_map: @RefCell::new(HashMap::new()),
187-
method_map: @RefCell::new(HashMap::new()),
188-
vtable_map: @RefCell::new(HashMap::new()),
189-
capture_map: @RefCell::new(HashMap::new())
188+
method_map: @RefCell::new(NodeMap::new()),
189+
vtable_map: @RefCell::new(NodeMap::new()),
190+
capture_map: @RefCell::new(NodeMap::new())
190191
};
191192
let e = match csearch::maybe_get_item_ast(tcx, def_id,
192193
|a, b, c, d| astencode::decode_inlined_item(a, b, maps, c, d)) {
@@ -305,7 +306,7 @@ pub fn process_crate(krate: &ast::Crate,
305306
tcx: ty::ctxt) {
306307
let mut v = ConstEvalVisitor {
307308
tcx: tcx,
308-
ccache: HashMap::new(),
309+
ccache: DefIdMap::new(),
309310
};
310311
visit::walk_crate(&mut v, krate, ());
311312
tcx.sess.abort_if_errors();

src/librustc/middle/dataflow.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@
2020
use std::io;
2121
use std::uint;
2222
use std::vec;
23-
use collections::HashMap;
2423
use syntax::ast;
2524
use syntax::ast_util;
2625
use syntax::ast_util::IdRange;
2726
use syntax::print::{pp, pprust};
2827
use middle::ty;
2928
use middle::typeck;
3029
use util::ppaux::Repr;
30+
use util::nodemap::NodeMap;
3131

3232
#[deriving(Clone)]
3333
pub struct DataFlowContext<O> {
@@ -45,7 +45,7 @@ pub struct DataFlowContext<O> {
4545
priv words_per_id: uint,
4646

4747
// mapping from node to bitset index.
48-
priv nodeid_to_bitset: HashMap<ast::NodeId,uint>,
48+
priv nodeid_to_bitset: NodeMap<uint>,
4949

5050
// Bit sets per id. The following three fields (`gens`, `kills`,
5151
// and `on_entry`) all have the same structure. For each id in
@@ -139,7 +139,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
139139
tcx: tcx,
140140
method_map: method_map,
141141
words_per_id: words_per_id,
142-
nodeid_to_bitset: HashMap::new(),
142+
nodeid_to_bitset: NodeMap::new(),
143143
bits_per_id: bits_per_id,
144144
oper: oper,
145145
gens: gens,

src/librustc/middle/dead.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use middle::lint::{allow, contains_lint, DeadCode};
1616
use middle::privacy;
1717
use middle::ty;
1818
use middle::typeck;
19+
use util::nodemap::NodeSet;
1920

2021
use collections::HashSet;
2122
use syntax::ast;
@@ -252,7 +253,7 @@ impl Visitor<()> for LifeSeeder {
252253

253254
fn create_and_seed_worklist(tcx: ty::ctxt,
254255
exported_items: &privacy::ExportedItems,
255-
reachable_symbols: &HashSet<ast::NodeId>,
256+
reachable_symbols: &NodeSet,
256257
krate: &ast::Crate) -> ~[ast::NodeId] {
257258
let mut worklist = ~[];
258259

@@ -286,7 +287,7 @@ fn create_and_seed_worklist(tcx: ty::ctxt,
286287
fn find_live(tcx: ty::ctxt,
287288
method_map: typeck::MethodMap,
288289
exported_items: &privacy::ExportedItems,
289-
reachable_symbols: &HashSet<ast::NodeId>,
290+
reachable_symbols: &NodeSet,
290291
krate: &ast::Crate)
291292
-> ~HashSet<ast::NodeId> {
292293
let worklist = create_and_seed_worklist(tcx, exported_items,
@@ -409,7 +410,7 @@ impl Visitor<()> for DeadVisitor {
409410
pub fn check_crate(tcx: ty::ctxt,
410411
method_map: typeck::MethodMap,
411412
exported_items: &privacy::ExportedItems,
412-
reachable_symbols: &HashSet<ast::NodeId>,
413+
reachable_symbols: &NodeSet,
413414
krate: &ast::Crate) {
414415
let live_symbols = find_live(tcx, method_map, exported_items,
415416
reachable_symbols, krate);

src/librustc/middle/freevars.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
use middle::resolve;
1717
use middle::ty;
18+
use util::nodemap::{NodeMap, NodeSet};
1819

19-
use collections::HashMap;
2020
use syntax::codemap::Span;
2121
use syntax::{ast, ast_util};
2222
use syntax::visit;
@@ -30,10 +30,10 @@ pub struct freevar_entry {
3030
span: Span //< First span where it is accessed (there can be multiple)
3131
}
3232
pub type freevar_info = @~[@freevar_entry];
33-
pub type freevar_map = HashMap<ast::NodeId, freevar_info>;
33+
pub type freevar_map = NodeMap<freevar_info>;
3434

3535
struct CollectFreevarsVisitor {
36-
seen: HashMap<ast::NodeId, ()>,
36+
seen: NodeSet,
3737
refs: ~[@freevar_entry],
3838
def_map: resolve::DefMap,
3939
}
@@ -65,12 +65,12 @@ impl Visitor<int> for CollectFreevarsVisitor {
6565
}
6666
if i == depth { // Made it to end of loop
6767
let dnum = ast_util::def_id_of_def(def).node;
68-
if !self.seen.contains_key(&dnum) {
68+
if !self.seen.contains(&dnum) {
6969
self.refs.push(@freevar_entry {
7070
def: def,
7171
span: expr.span,
7272
});
73-
self.seen.insert(dnum, ());
73+
self.seen.insert(dnum);
7474
}
7575
}
7676
}
@@ -89,7 +89,7 @@ impl Visitor<int> for CollectFreevarsVisitor {
8989
// of the AST, we take a walker function that we invoke with a visitor
9090
// in order to start the search.
9191
fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block) -> freevar_info {
92-
let seen = HashMap::new();
92+
let seen = NodeSet::new();
9393
let refs = ~[];
9494

9595
let mut v = CollectFreevarsVisitor {
@@ -129,7 +129,7 @@ pub fn annotate_freevars(def_map: resolve::DefMap, krate: &ast::Crate) ->
129129
freevar_map {
130130
let mut visitor = AnnotateFreevarsVisitor {
131131
def_map: def_map,
132-
freevars: HashMap::new(),
132+
freevars: NodeMap::new(),
133133
};
134134
visit::walk_crate(&mut visitor, krate, ());
135135

src/librustc/middle/liveness.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ use middle::pat_util;
108108
use middle::ty;
109109
use middle::typeck;
110110
use middle::moves;
111+
use util::nodemap::NodeMap;
111112

112113
use std::cast::transmute;
113114
use std::cell::{Cell, RefCell};
@@ -116,7 +117,6 @@ use std::io;
116117
use std::str;
117118
use std::uint;
118119
use std::vec;
119-
use collections::HashMap;
120120
use syntax::ast::*;
121121
use syntax::codemap::Span;
122122
use syntax::parse::token::special_idents;
@@ -258,9 +258,9 @@ pub struct IrMaps {
258258

259259
num_live_nodes: Cell<uint>,
260260
num_vars: Cell<uint>,
261-
live_node_map: RefCell<HashMap<NodeId, LiveNode>>,
262-
variable_map: RefCell<HashMap<NodeId, Variable>>,
263-
capture_info_map: RefCell<HashMap<NodeId, @~[CaptureInfo]>>,
261+
live_node_map: RefCell<NodeMap<LiveNode>>,
262+
variable_map: RefCell<NodeMap<Variable>>,
263+
capture_info_map: RefCell<NodeMap<@~[CaptureInfo]>>,
264264
var_kinds: RefCell<~[VarKind]>,
265265
lnks: RefCell<~[LiveNodeKind]>,
266266
}
@@ -275,9 +275,9 @@ fn IrMaps(tcx: ty::ctxt,
275275
capture_map: capture_map,
276276
num_live_nodes: Cell::new(0),
277277
num_vars: Cell::new(0),
278-
live_node_map: RefCell::new(HashMap::new()),
279-
variable_map: RefCell::new(HashMap::new()),
280-
capture_info_map: RefCell::new(HashMap::new()),
278+
live_node_map: RefCell::new(NodeMap::new()),
279+
variable_map: RefCell::new(NodeMap::new()),
280+
capture_info_map: RefCell::new(NodeMap::new()),
281281
var_kinds: RefCell::new(~[]),
282282
lnks: RefCell::new(~[]),
283283
}
@@ -584,7 +584,7 @@ static ACC_READ: uint = 1u;
584584
static ACC_WRITE: uint = 2u;
585585
static ACC_USE: uint = 4u;
586586

587-
pub type LiveNodeMap = @RefCell<HashMap<NodeId, LiveNode>>;
587+
pub type LiveNodeMap = @RefCell<NodeMap<LiveNode>>;
588588

589589
pub struct Liveness {
590590
tcx: ty::ctxt,
@@ -613,8 +613,8 @@ fn Liveness(ir: @IrMaps, specials: Specials) -> Liveness {
613613
ir.num_vars.get(),
614614
invalid_users())),
615615
loop_scope: @RefCell::new(~[]),
616-
break_ln: @RefCell::new(HashMap::new()),
617-
cont_ln: @RefCell::new(HashMap::new()),
616+
break_ln: @RefCell::new(NodeMap::new()),
617+
cont_ln: @RefCell::new(NodeMap::new()),
618618
}
619619
}
620620

0 commit comments

Comments
 (0)