Skip to content

Commit d407822

Browse files
committed
Parallelize and optimize parts of HIR map creation
1 parent f39bd9b commit d407822

File tree

6 files changed

+124
-45
lines changed

6 files changed

+124
-45
lines changed

src/librustc/hir/lowering.rs

+30-2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ pub struct LoweringContext<'a> {
9090
trait_impls: BTreeMap<DefId, Vec<NodeId>>,
9191
trait_auto_impl: BTreeMap<DefId, NodeId>,
9292

93+
modules: BTreeMap<NodeId, hir::ModuleItems>,
94+
9395
is_generator: bool,
9496

9597
catch_scopes: Vec<NodeId>,
@@ -228,6 +230,7 @@ pub fn lower_crate(
228230
bodies: BTreeMap::new(),
229231
trait_impls: BTreeMap::new(),
230232
trait_auto_impl: BTreeMap::new(),
233+
modules: BTreeMap::new(),
231234
exported_macros: Vec::new(),
232235
catch_scopes: Vec::new(),
233236
loop_scopes: Vec::new(),
@@ -356,6 +359,15 @@ impl<'a> LoweringContext<'a> {
356359
}
357360

358361
impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
362+
fn visit_mod(&mut self, m: &'lcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
363+
self.lctx.modules.insert(n, hir::ModuleItems {
364+
items: Vec::new(),
365+
trait_items: Vec::new(),
366+
impl_items: Vec::new(),
367+
});
368+
visit::walk_mod(self, m);
369+
}
370+
359371
fn visit_item(&mut self, item: &'lcx Item) {
360372
self.lctx.allocate_hir_id_counter(item.id, item);
361373

@@ -395,6 +407,7 @@ impl<'a> LoweringContext<'a> {
395407

396408
struct ItemLowerer<'lcx, 'interner: 'lcx> {
397409
lctx: &'lcx mut LoweringContext<'interner>,
410+
module: NodeId,
398411
}
399412

400413
impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> {
@@ -414,11 +427,20 @@ impl<'a> LoweringContext<'a> {
414427
}
415428

416429
impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
430+
fn visit_mod(&mut self, m: &'lcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
431+
let old = self.module;
432+
self.module = n;
433+
visit::walk_mod(self, m);
434+
self.module = old;
435+
}
436+
417437
fn visit_item(&mut self, item: &'lcx Item) {
418438
let mut item_lowered = true;
439+
let module = &self.module;
419440
self.lctx.with_hir_id_owner(item.id, |lctx| {
420441
if let Some(hir_item) = lctx.lower_item(item) {
421442
lctx.items.insert(item.id, hir_item);
443+
lctx.modules.get_mut(module).unwrap().items.push(item.id);
422444
} else {
423445
item_lowered = false;
424446
}
@@ -433,8 +455,9 @@ impl<'a> LoweringContext<'a> {
433455
_ => HirVec::new(),
434456
};
435457

458+
let module = self.module;
436459
self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| {
437-
let this = &mut ItemLowerer { lctx: this };
460+
let this = &mut ItemLowerer { lctx: this, module };
438461
if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node {
439462
this.with_trait_impl_ref(opt_trait_ref, |this| {
440463
visit::walk_item(this, item)
@@ -447,20 +470,24 @@ impl<'a> LoweringContext<'a> {
447470
}
448471

449472
fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
473+
let module = &self.module;
450474
self.lctx.with_hir_id_owner(item.id, |lctx| {
451475
let id = hir::TraitItemId { node_id: item.id };
452476
let hir_item = lctx.lower_trait_item(item);
453477
lctx.trait_items.insert(id, hir_item);
478+
lctx.modules.get_mut(module).unwrap().trait_items.push(id);
454479
});
455480

456481
visit::walk_trait_item(self, item);
457482
}
458483

459484
fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
485+
let module = &self.module;
460486
self.lctx.with_hir_id_owner(item.id, |lctx| {
461487
let id = hir::ImplItemId { node_id: item.id };
462488
let hir_item = lctx.lower_impl_item(item);
463489
lctx.impl_items.insert(id, hir_item);
490+
lctx.modules.get_mut(module).unwrap().impl_items.push(id);
464491
});
465492
visit::walk_impl_item(self, item);
466493
}
@@ -470,7 +497,7 @@ impl<'a> LoweringContext<'a> {
470497
debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID);
471498

472499
visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c);
473-
visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c);
500+
visit::walk_crate(&mut ItemLowerer { lctx: &mut self, module: CRATE_NODE_ID }, c);
474501

475502
let module = self.lower_mod(&c.module);
476503
let attrs = self.lower_attrs(&c.attrs);
@@ -492,6 +519,7 @@ impl<'a> LoweringContext<'a> {
492519
body_ids,
493520
trait_impls: self.trait_impls,
494521
trait_auto_impl: self.trait_auto_impl,
522+
modules: self.modules,
495523
}
496524
}
497525

src/librustc/hir/map/collector.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_data_structures::svh::Svh;
66
use ich::Fingerprint;
77
use middle::cstore::CrateStore;
88
use session::CrateDisambiguator;
9+
use session::Session;
910
use std::iter::repeat;
1011
use syntax::ast::{NodeId, CRATE_NODE_ID};
1112
use syntax::source_map::SourceMap;
@@ -45,11 +46,11 @@ pub(super) struct NodeCollector<'a, 'hir> {
4546
}
4647

4748
impl<'a, 'hir> NodeCollector<'a, 'hir> {
48-
pub(super) fn root(krate: &'hir Crate,
49+
pub(super) fn root(sess: &'a Session,
50+
krate: &'hir Crate,
4951
dep_graph: &'a DepGraph,
5052
definitions: &'a definitions::Definitions,
51-
hcx: StableHashingContext<'a>,
52-
source_map: &'a SourceMap)
53+
hcx: StableHashingContext<'a>)
5354
-> NodeCollector<'a, 'hir> {
5455
let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX);
5556

@@ -71,6 +72,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
7172
trait_impls: _,
7273
trait_auto_impl: _,
7374
body_ids: _,
75+
modules: _,
7476
} = *krate;
7577

7678
root_mod_sig_dep_index = dep_graph.input_task(
@@ -97,8 +99,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
9799

98100
let mut collector = NodeCollector {
99101
krate,
100-
source_map,
101-
map: vec![],
102+
source_map: sess.source_map(),
103+
map: repeat(None).take(sess.current_node_id_count()).collect(),
102104
parent_node: CRATE_NODE_ID,
103105
current_signature_dep_index: root_mod_sig_dep_index,
104106
current_full_dep_index: root_mod_full_dep_index,
@@ -175,10 +177,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
175177

176178
fn insert_entry(&mut self, id: NodeId, entry: Entry<'hir>) {
177179
debug!("hir_map: {:?} => {:?}", id, entry);
178-
let len = self.map.len();
179-
if id.as_usize() >= len {
180-
self.map.extend(repeat(None).take(id.as_usize() - len + 1));
181-
}
182180
self.map[id.as_usize()] = Some(entry);
183181
}
184182

src/librustc/hir/map/hir_id_validator.rs

+26-19
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,24 @@ use hir::{self, intravisit, HirId, ItemLocalId};
33
use syntax::ast::NodeId;
44
use hir::itemlikevisit::ItemLikeVisitor;
55
use rustc_data_structures::fx::FxHashMap;
6+
use rustc_data_structures::sync::{Lock, ParallelIterator, par_iter};
67

78
pub fn check_crate<'hir>(hir_map: &hir::map::Map<'hir>) {
8-
let mut outer_visitor = OuterVisitor {
9-
hir_map,
10-
errors: vec![],
11-
};
12-
139
hir_map.dep_graph.assert_ignored();
1410

15-
hir_map.krate().visit_all_item_likes(&mut outer_visitor);
16-
if !outer_visitor.errors.is_empty() {
17-
let message = outer_visitor
18-
.errors
11+
let errors = Lock::new(Vec::new());
12+
13+
par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| {
14+
hir_map.visit_module_item_likes(hir_map.local_def_id(*module_id), &mut OuterVisitor {
15+
hir_map,
16+
errors: &errors,
17+
});
18+
});
19+
20+
let errors = errors.into_inner();
21+
22+
if !errors.is_empty() {
23+
let message = errors
1924
.iter()
2025
.fold(String::new(), |s1, s2| s1 + "\n" + s2);
2126
bug!("{}", message);
@@ -26,12 +31,12 @@ struct HirIdValidator<'a, 'hir: 'a> {
2631
hir_map: &'a hir::map::Map<'hir>,
2732
owner_def_index: Option<DefIndex>,
2833
hir_ids_seen: FxHashMap<ItemLocalId, NodeId>,
29-
errors: Vec<String>,
34+
errors: &'a Lock<Vec<String>>,
3035
}
3136

3237
struct OuterVisitor<'a, 'hir: 'a> {
3338
hir_map: &'a hir::map::Map<'hir>,
34-
errors: Vec<String>,
39+
errors: &'a Lock<Vec<String>>,
3540
}
3641

3742
impl<'a, 'hir: 'a> OuterVisitor<'a, 'hir> {
@@ -42,7 +47,7 @@ impl<'a, 'hir: 'a> OuterVisitor<'a, 'hir> {
4247
hir_map,
4348
owner_def_index: None,
4449
hir_ids_seen: Default::default(),
45-
errors: Vec::new(),
50+
errors: self.errors,
4651
}
4752
}
4853
}
@@ -51,23 +56,25 @@ impl<'a, 'hir: 'a> ItemLikeVisitor<'hir> for OuterVisitor<'a, 'hir> {
5156
fn visit_item(&mut self, i: &'hir hir::Item) {
5257
let mut inner_visitor = self.new_inner_visitor(self.hir_map);
5358
inner_visitor.check(i.id, |this| intravisit::walk_item(this, i));
54-
self.errors.extend(inner_visitor.errors.drain(..));
5559
}
5660

5761
fn visit_trait_item(&mut self, i: &'hir hir::TraitItem) {
5862
let mut inner_visitor = self.new_inner_visitor(self.hir_map);
5963
inner_visitor.check(i.id, |this| intravisit::walk_trait_item(this, i));
60-
self.errors.extend(inner_visitor.errors.drain(..));
6164
}
6265

6366
fn visit_impl_item(&mut self, i: &'hir hir::ImplItem) {
6467
let mut inner_visitor = self.new_inner_visitor(self.hir_map);
6568
inner_visitor.check(i.id, |this| intravisit::walk_impl_item(this, i));
66-
self.errors.extend(inner_visitor.errors.drain(..));
6769
}
6870
}
6971

7072
impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
73+
#[cold]
74+
#[inline(never)]
75+
fn error(&self, f: impl FnOnce() -> String) {
76+
self.errors.lock().push(f());
77+
}
7178

7279
fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self,
7380
node_id: NodeId,
@@ -119,7 +126,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
119126
local_id,
120127
self.hir_map.node_to_string(node_id)));
121128
}
122-
self.errors.push(format!(
129+
self.error(|| format!(
123130
"ItemLocalIds not assigned densely in {}. \
124131
Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}",
125132
self.hir_map.def_path(DefId::local(owner_def_index)).to_string_no_crate(),
@@ -145,14 +152,14 @@ impl<'a, 'hir: 'a> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
145152
let stable_id = self.hir_map.definitions().node_to_hir_id[node_id];
146153

147154
if stable_id == hir::DUMMY_HIR_ID {
148-
self.errors.push(format!("HirIdValidator: No HirId assigned for NodeId {}: {:?}",
155+
self.error(|| format!("HirIdValidator: No HirId assigned for NodeId {}: {:?}",
149156
node_id,
150157
self.hir_map.node_to_string(node_id)));
151158
return;
152159
}
153160

154161
if owner != stable_id.owner {
155-
self.errors.push(format!(
162+
self.error(|| format!(
156163
"HirIdValidator: The recorded owner of {} is {} instead of {}",
157164
self.hir_map.node_to_string(node_id),
158165
self.hir_map.def_path(DefId::local(stable_id.owner)).to_string_no_crate(),
@@ -161,7 +168,7 @@ impl<'a, 'hir: 'a> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
161168

162169
if let Some(prev) = self.hir_ids_seen.insert(stable_id.local_id, node_id) {
163170
if prev != node_id {
164-
self.errors.push(format!(
171+
self.error(|| format!(
165172
"HirIdValidator: Same HirId {}/{} assigned for nodes {} and {}",
166173
self.hir_map.def_path(DefId::local(stable_id.owner)).to_string_no_crate(),
167174
stable_id.local_id.as_usize(),

0 commit comments

Comments
 (0)