Skip to content

Commit

Permalink
Auto merge of #35854 - nikomatsakis:incr-comp-cache-hash-35549, r=mw
Browse files Browse the repository at this point in the history
compute and cache HIR hashes at beginning

This avoids the compile-time overhead of computing them twice.  It also fixes
an issue where the hash computed after typeck is differen than the hash before,
because typeck mutates the def-map in place.

Fixes #35549.
Fixes #35593.

Some performance measurements suggest this `HashesMap` is very small in memory (unobservable via `-Z time-passes`) and very cheap to construct. I do see some (very minor) performance wins in the incremental case after the first run -- the first run costs more because loading the dep-graph didn't have any hashing to do in that case. Example timings from two runs  of `libsyntex-syntax` -- the (1) indicates first run, (2) indicates second run, and (*) indicates both together:

| Phase | Master | Branch |
| ---- | ---- | ---- |
| compute_hashes_map (1) | N/A | 0.343 |
| load_dep_graph (1) | 0 | 0 |
| serialize dep graph (1) | 4.190 | 3.920 |
| total (1) | 4.190 | 4.260 |
| compute_hashes_map (2) | N/A | 0.344 |
| load_dep_graph (2) | 0.592 | 0.252 |
| serialize dep graph (2) | 4.119 | 3.779 |
| total (2) | 4.71 | 4.375 |
| total (*) | 8.9 | 8.635 |

r? @michaelwoerister
  • Loading branch information
bors authored Aug 23, 2016
2 parents 0bd99f9 + 1cc7c90 commit 012f45e
Show file tree
Hide file tree
Showing 19 changed files with 350 additions and 176 deletions.
5 changes: 5 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ impl<D: Clone + Debug> DepNode<D> {
}
}

if label == "Krate" {
// special case
return Ok(DepNode::Krate);
}

check! {
CollectItem,
BorrowCheck,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1621,7 +1621,7 @@ pub type FreevarMap = NodeMap<Vec<Freevar>>;

pub type CaptureModeMap = NodeMap<CaptureClause>;

#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct TraitCandidate {
pub def_id: DefId,
pub import_id: Option<NodeId>,
Expand Down
41 changes: 28 additions & 13 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use rustc::util::common::time;
use rustc::util::nodemap::NodeSet;
use rustc_back::sha2::{Sha256, Digest};
use rustc_borrowck as borrowck;
use rustc_incremental;
use rustc_incremental::{self, IncrementalHashesMap};
use rustc_resolve::{MakeGlobMap, Resolver};
use rustc_metadata::macro_import;
use rustc_metadata::creader::read_local_crates;
Expand Down Expand Up @@ -172,7 +172,7 @@ pub fn compile_input(sess: &Session,
resolutions,
&arenas,
&crate_name,
|tcx, mir_map, analysis, result| {
|tcx, mir_map, analysis, incremental_hashes_map, result| {
{
// Eventually, we will want to track plugins.
let _ignore = tcx.dep_graph.in_ignore();
Expand Down Expand Up @@ -202,7 +202,8 @@ pub fn compile_input(sess: &Session,
}
let trans = phase_4_translate_to_llvm(tcx,
mir_map.unwrap(),
analysis);
analysis,
&incremental_hashes_map);

if log_enabled!(::log::INFO) {
println!("Post-trans");
Expand Down Expand Up @@ -797,14 +798,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
Option<MirMap<'tcx>>,
ty::CrateAnalysis,
IncrementalHashesMap,
CompileResult) -> R
{
macro_rules! try_with_f {
($e: expr, ($t: expr, $m: expr, $a: expr)) => {
($e: expr, ($t: expr, $m: expr, $a: expr, $h: expr)) => {
match $e {
Ok(x) => x,
Err(x) => {
f($t, $m, $a, Err(x));
f($t, $m, $a, $h, Err(x));
return Err(x);
}
}
Expand Down Expand Up @@ -860,12 +862,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
index,
name,
|tcx| {
let incremental_hashes_map =
time(time_passes,
"compute_incremental_hashes_map",
|| rustc_incremental::compute_incremental_hashes_map(tcx));
time(time_passes,
"load_dep_graph",
|| rustc_incremental::load_dep_graph(tcx));
|| rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));

// passes are timed inside typeck
try_with_f!(typeck::check_crate(tcx), (tcx, None, analysis));
try_with_f!(typeck::check_crate(tcx), (tcx, None, analysis, incremental_hashes_map));

time(time_passes,
"const checking",
Expand Down Expand Up @@ -935,7 +941,11 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
if sess.err_count() > 0 {
return Ok(f(tcx, Some(mir_map), analysis, Err(sess.err_count())));
return Ok(f(tcx,
Some(mir_map),
analysis,
incremental_hashes_map,
Err(sess.err_count())));
}

analysis.reachable =
Expand Down Expand Up @@ -963,17 +973,22 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,

// The above three passes generate errors w/o aborting
if sess.err_count() > 0 {
return Ok(f(tcx, Some(mir_map), analysis, Err(sess.err_count())));
return Ok(f(tcx,
Some(mir_map),
analysis,
incremental_hashes_map,
Err(sess.err_count())));
}

Ok(f(tcx, Some(mir_map), analysis, Ok(())))
Ok(f(tcx, Some(mir_map), analysis, incremental_hashes_map, Ok(())))
})
}

/// Run the translation phase to LLVM, after which the AST and analysis can
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mut mir_map: MirMap<'tcx>,
analysis: ty::CrateAnalysis)
analysis: ty::CrateAnalysis,
incremental_hashes_map: &IncrementalHashesMap)
-> trans::CrateTranslation {
let time_passes = tcx.sess.time_passes();

Expand Down Expand Up @@ -1007,15 +1022,15 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let translation =
time(time_passes,
"translation",
move || trans::trans_crate(tcx, &mir_map, analysis));
move || trans::trans_crate(tcx, &mir_map, analysis, &incremental_hashes_map));

time(time_passes,
"assert dep graph",
move || rustc_incremental::assert_dep_graph(tcx));

time(time_passes,
"serialize dep graph",
move || rustc_incremental::save_dep_graph(tcx));
move || rustc_incremental::save_dep_graph(tcx, &incremental_hashes_map));

translation
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_driver/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl PpSourceMode {
resolutions.clone(),
arenas,
id,
|tcx, _, _, _| {
|tcx, _, _, _, _| {
let annotation = TypedAnnotation {
tcx: tcx,
};
Expand Down Expand Up @@ -951,7 +951,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
resolutions.clone(),
arenas,
crate_name,
|tcx, mir_map, _, _| {
|tcx, mir_map, _, _, _| {
match ppm {
PpmMir | PpmMirCFG => {
if let Some(mir_map) = mir_map {
Expand Down
36 changes: 36 additions & 0 deletions src/librustc_incremental/calculate_svh/def_path_hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::hir::def_id::DefId;
use rustc::ty::TyCtxt;
use rustc::util::nodemap::DefIdMap;

pub struct DefPathHashes<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
data: DefIdMap<u64>,
}

impl<'a, 'tcx> DefPathHashes<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
DefPathHashes {
tcx: tcx,
data: DefIdMap()
}
}

pub fn hash(&mut self, def_id: DefId) -> u64 {
let tcx = self.tcx;
*self.data.entry(def_id)
.or_insert_with(|| {
let def_path = tcx.def_path(def_id);
def_path.deterministic_hash(tcx)
})
}
}
Loading

0 comments on commit 012f45e

Please sign in to comment.