Skip to content

Commit 9e96980

Browse files
Add caching of external MIR in trans::collector
1 parent 862911d commit 9e96980

File tree

5 files changed

+87
-46
lines changed

5 files changed

+87
-46
lines changed

src/librustc/mir/repr.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use std::{iter, u32};
2525
use std::ops::{Index, IndexMut};
2626

2727
/// Lowered representation of a single function.
28-
#[derive(RustcEncodable, RustcDecodable)]
28+
#[derive(Clone, RustcEncodable, RustcDecodable)]
2929
pub struct Mir<'tcx> {
3030
/// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
3131
/// that indexes into this vector.
@@ -146,7 +146,7 @@ pub enum BorrowKind {
146146

147147
// A "variable" is a binding declared by the user as part of the fn
148148
// decl, a let, etc.
149-
#[derive(RustcEncodable, RustcDecodable)]
149+
#[derive(Clone, RustcEncodable, RustcDecodable)]
150150
pub struct VarDecl<'tcx> {
151151
pub mutability: Mutability,
152152
pub name: Name,
@@ -155,7 +155,7 @@ pub struct VarDecl<'tcx> {
155155

156156
// A "temp" is a temporary that we place on the stack. They are
157157
// anonymous, always mutable, and have only a type.
158-
#[derive(RustcEncodable, RustcDecodable)]
158+
#[derive(Clone, RustcEncodable, RustcDecodable)]
159159
pub struct TempDecl<'tcx> {
160160
pub ty: Ty<'tcx>,
161161
}
@@ -171,7 +171,7 @@ pub struct TempDecl<'tcx> {
171171
//
172172
// there is only one argument, of type `(i32, u32)`, but two bindings
173173
// (`x` and `y`).
174-
#[derive(RustcEncodable, RustcDecodable)]
174+
#[derive(Clone, RustcEncodable, RustcDecodable)]
175175
pub struct ArgDecl<'tcx> {
176176
pub ty: Ty<'tcx>,
177177
}
@@ -207,14 +207,14 @@ impl Debug for BasicBlock {
207207
///////////////////////////////////////////////////////////////////////////
208208
// BasicBlock and Terminator
209209

210-
#[derive(Debug, RustcEncodable, RustcDecodable)]
210+
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
211211
pub struct BasicBlockData<'tcx> {
212212
pub statements: Vec<Statement<'tcx>>,
213213
pub terminator: Option<Terminator<'tcx>>,
214214
pub is_cleanup: bool,
215215
}
216216

217-
#[derive(RustcEncodable, RustcDecodable)]
217+
#[derive(Clone, RustcEncodable, RustcDecodable)]
218218
pub enum Terminator<'tcx> {
219219
/// block should have one successor in the graph; we jump there
220220
Goto {
@@ -481,13 +481,13 @@ impl<'tcx> Terminator<'tcx> {
481481
///////////////////////////////////////////////////////////////////////////
482482
// Statements
483483

484-
#[derive(RustcEncodable, RustcDecodable)]
484+
#[derive(Clone, RustcEncodable, RustcDecodable)]
485485
pub struct Statement<'tcx> {
486486
pub span: Span,
487487
pub kind: StatementKind<'tcx>,
488488
}
489489

490-
#[derive(Debug, RustcEncodable, RustcDecodable)]
490+
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
491491
pub enum StatementKind<'tcx> {
492492
Assign(Lvalue<'tcx>, Rvalue<'tcx>),
493493
Drop(DropKind, Lvalue<'tcx>),

src/librustc_trans/trans/base.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,6 +2110,10 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
21102110
fn record_translation_item_as_generated<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
21112111
node_id: ast::NodeId,
21122112
param_substs: &'tcx Substs<'tcx>) {
2113+
if !collector::collecting_debug_information(ccx) {
2114+
return;
2115+
}
2116+
21132117
let def_id = match ccx.tcx().node_id_to_type(node_id).sty {
21142118
ty::TyClosure(def_id, _) => def_id,
21152119
_ => ccx.external_srcs()

src/librustc_trans/trans/collector.rs

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ use trans::monomorphize;
217217
use util::nodemap::{FnvHashSet, FnvHashMap, DefIdMap};
218218

219219
use std::hash::{Hash, Hasher};
220+
use std::rc::Rc;
220221

221222
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
222223
pub enum TransItemCollectionMode {
@@ -281,9 +282,14 @@ pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
281282
debug!("Building translation item graph, beginning at roots");
282283
let mut visited = FnvHashSet();
283284
let mut recursion_depths = DefIdMap();
285+
let mut mir_cache = DefIdMap();
284286

285287
for root in roots {
286-
collect_items_rec(ccx, root, &mut visited, &mut recursion_depths);
288+
collect_items_rec(ccx,
289+
root,
290+
&mut visited,
291+
&mut recursion_depths,
292+
&mut mir_cache);
287293
}
288294

289295
visited
@@ -313,11 +319,27 @@ fn collect_roots<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
313319
roots
314320
}
315321

322+
#[derive(Clone)]
323+
enum CachedMir<'mir, 'tcx: 'mir> {
324+
Ref(&'mir mir::Mir<'tcx>),
325+
Owned(Rc<mir::Mir<'tcx>>)
326+
}
327+
328+
impl<'mir, 'tcx: 'mir> CachedMir<'mir, 'tcx> {
329+
fn get_ref<'a>(&'a self) -> &'a mir::Mir<'tcx> {
330+
match *self {
331+
CachedMir::Ref(r) => r,
332+
CachedMir::Owned(ref rc) => &**rc,
333+
}
334+
}
335+
}
336+
316337
// Collect all monomorphized translation items reachable from `starting_point`
317338
fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
318339
starting_point: TransItem<'tcx>,
319340
visited: &mut FnvHashSet<TransItem<'tcx>>,
320-
recursion_depths: &mut DefIdMap<usize>) {
341+
recursion_depths: &mut DefIdMap<usize>,
342+
mir_cache: &mut DefIdMap<CachedMir<'a, 'tcx>>) {
321343
if !visited.insert(starting_point.clone()) {
322344
// We've been here already, no need to search again.
323345
return;
@@ -343,42 +365,21 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
343365

344366
// Scan the MIR in order to find function calls, closures, and
345367
// drop-glue
346-
let mir_not_found_error_message = || {
347-
format!("Could not find MIR for function: {}",
348-
ccx.tcx().item_path_str(def_id))
349-
};
350-
351-
let external_mir = if !def_id.is_local() {
352-
ccx.sess().cstore.maybe_get_item_mir(ccx.tcx(), def_id)
353-
} else {
354-
None
355-
};
356-
357-
let mir_opt = match external_mir {
358-
Some(ref mir) => Some(mir),
359-
None => {
360-
let node_id = ccx.tcx().map.as_local_node_id(def_id).unwrap();
361-
ccx.mir_map().get(&node_id)
362-
}
363-
};
364-
365-
let mir = errors::expect(ccx.sess().diagnostic(),
366-
mir_opt,
367-
mir_not_found_error_message);
368+
let mir = load_mir(ccx, def_id, mir_cache);
368369

369370
let mut visitor = MirNeighborCollector {
370371
ccx: ccx,
371-
mir: mir,
372+
mir: mir.get_ref(),
372373
output: &mut neighbors,
373374
param_substs: param_substs
374375
};
375376

376-
visitor.visit_mir(mir);
377+
visitor.visit_mir(mir.get_ref());
377378
}
378379
}
379380

380381
for neighbour in neighbors {
381-
collect_items_rec(ccx, neighbour, visited, recursion_depths);
382+
collect_items_rec(ccx, neighbour, visited, recursion_depths, mir_cache);
382383
}
383384

384385
if let Some((def_id, depth)) = recursion_depth_reset {
@@ -388,6 +389,37 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
388389
debug!("END collect_items_rec({})", starting_point.to_string(ccx));
389390
}
390391

392+
fn load_mir<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
393+
def_id: DefId,
394+
mir_cache: &mut DefIdMap<CachedMir<'a, 'tcx>>)
395+
-> CachedMir<'a, 'tcx> {
396+
let mir_not_found_error_message = || {
397+
format!("Could not find MIR for function: {}",
398+
ccx.tcx().item_path_str(def_id))
399+
};
400+
401+
if def_id.is_local() {
402+
let node_id = ccx.tcx().map.as_local_node_id(def_id).unwrap();
403+
let mir_opt = ccx.mir_map().get(&node_id);
404+
let mir = errors::expect(ccx.sess().diagnostic(),
405+
mir_opt,
406+
mir_not_found_error_message);
407+
CachedMir::Ref(mir)
408+
} else {
409+
if let Some(mir) = mir_cache.get(&def_id) {
410+
return mir.clone();
411+
}
412+
413+
let mir_opt = ccx.sess().cstore.maybe_get_item_mir(ccx.tcx(), def_id);
414+
let mir = errors::expect(ccx.sess().diagnostic(),
415+
mir_opt,
416+
mir_not_found_error_message);
417+
let cached = CachedMir::Owned(Rc::new(mir));
418+
mir_cache.insert(def_id, cached.clone());
419+
cached
420+
}
421+
}
422+
391423
fn check_recursion_limit<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
392424
def_id: DefId,
393425
recursion_depths: &mut DefIdMap<usize>)
@@ -1488,14 +1520,15 @@ pub enum TransItemState {
14881520
NotPredictedButGenerated,
14891521
}
14901522

1523+
pub fn collecting_debug_information(ccx: &CrateContext) -> bool {
1524+
return cfg!(debug_assertions) &&
1525+
ccx.sess().opts.debugging_opts.print_trans_items.is_some();
1526+
}
1527+
14911528
pub fn print_collection_results<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
14921529
use std::hash::{Hash, SipHasher, Hasher};
14931530

1494-
if !cfg!(debug_assertions) {
1495-
return;
1496-
}
1497-
1498-
if ccx.sess().opts.debugging_opts.print_trans_items.is_none() {
1531+
if !collecting_debug_information(ccx) {
14991532
return;
15001533
}
15011534

src/librustc_trans/trans/consts.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use middle::def::Def;
3030
use middle::def_id::DefId;
3131
use trans::{adt, closure, debuginfo, expr, inline, machine};
3232
use trans::base::{self, push_ctxt};
33-
use trans::collector::TransItem;
33+
use trans::collector::{self, TransItem};
3434
use trans::common::{self, type_is_sized, ExprOrMethodCall, node_id_substs, C_nil, const_get_elt};
3535
use trans::common::{CrateContext, C_integral, C_floating, C_bool, C_str_slice, C_bytes, val_ty};
3636
use trans::common::{C_struct, C_undef, const_to_opt_int, const_to_opt_uint, VariantInfo, C_uint};
@@ -1018,7 +1018,9 @@ pub fn trans_static(ccx: &CrateContext,
10181018
attrs: &[ast::Attribute])
10191019
-> Result<ValueRef, ConstEvalErr> {
10201020

1021-
ccx.record_translation_item_as_generated(TransItem::Static(id));
1021+
if collector::collecting_debug_information(ccx) {
1022+
ccx.record_translation_item_as_generated(TransItem::Static(id));
1023+
}
10221024

10231025
unsafe {
10241026
let _icx = push_ctxt("trans_static");

src/librustc_trans/trans/glue.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use trans::build::*;
2828
use trans::callee;
2929
use trans::cleanup;
3030
use trans::cleanup::CleanupMethods;
31-
use trans::collector::TransItem;
31+
use trans::collector::{self, TransItem};
3232
use trans::common::*;
3333
use trans::debuginfo::DebugLoc;
3434
use trans::declare;
@@ -498,9 +498,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
498498
-> Block<'blk, 'tcx> {
499499
let t = g.ty();
500500

501-
bcx.ccx()
502-
.record_translation_item_as_generated(TransItem::DropGlue(bcx.tcx()
503-
.erase_regions(&t)));
501+
if collector::collecting_debug_information(bcx.ccx()) {
502+
bcx.ccx()
503+
.record_translation_item_as_generated(TransItem::DropGlue(bcx.tcx()
504+
.erase_regions(&t)));
505+
}
504506

505507
let skip_dtor = match g { DropGlueKind::Ty(_) => false, DropGlueKind::TyContents(_) => true };
506508
// NB: v0 is an *alias* of type t here, not a direct value.

0 commit comments

Comments
 (0)