Skip to content

Commit

Permalink
Use ThinLTO import information when doing incremental compilation.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed Jul 13, 2018
1 parent 81daa48 commit 4e28b6c
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 99 deletions.
115 changes: 82 additions & 33 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,31 @@ impl DepGraph {
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
R: HashStable<StableHashingContext<'gcx>>,
{
self.with_task_impl(key, cx, arg, false, task,
self.with_task_impl(key, cx, arg, false, true, task,
|key| OpenTask::Regular(Lock::new(RegularOpenTask {
node: key,
reads: SmallVec::new(),
read_set: FxHashSet(),
})),
|data, key, task| data.borrow_mut().complete_task(key, task))
|data, key, task| data.borrow_mut().complete_task(key, task, false))
}

pub fn with_forced_task<'gcx, C, A, R>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
R: HashStable<StableHashingContext<'gcx>>,
{
self.with_task_impl(key, cx, arg, false, false, task,
|key| OpenTask::Regular(Lock::new(RegularOpenTask {
node: key,
reads: SmallVec::new(),
read_set: FxHashSet(),
})),
|data, key, task| data.borrow_mut().complete_task(key, task, true))
}

/// Creates a new dep-graph input with value `input`
Expand All @@ -226,7 +244,7 @@ impl DepGraph {
arg
}

self.with_task_impl(key, cx, input, true, identity_fn,
self.with_task_impl(key, cx, input, true, true, identity_fn,
|_| OpenTask::Ignore,
|data, key, _| data.borrow_mut().alloc_node(key, SmallVec::new()))
}
Expand All @@ -237,6 +255,7 @@ impl DepGraph {
cx: C,
arg: A,
no_tcx: bool,
do_fingerprinting: bool,
task: fn(C, A) -> R,
create_task: fn(DepNode) -> OpenTask,
finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
Expand Down Expand Up @@ -282,41 +301,58 @@ impl DepGraph {

let dep_node_index = finish_task_and_alloc_depnode(&data.current, key, open_task);

let mut stable_hasher = StableHasher::new();
result.hash_stable(&mut hcx, &mut stable_hasher);
if do_fingerprinting {
let mut stable_hasher = StableHasher::new();
result.hash_stable(&mut hcx, &mut stable_hasher);

let current_fingerprint = stable_hasher.finish();
let current_fingerprint = stable_hasher.finish();

// Store the current fingerprint
{
let mut fingerprints = self.fingerprints.borrow_mut();
// Store the current fingerprint
{
let mut fingerprints = self.fingerprints.borrow_mut();

if dep_node_index.index() >= fingerprints.len() {
fingerprints.resize(dep_node_index.index() + 1, Fingerprint::ZERO);
}

if dep_node_index.index() >= fingerprints.len() {
fingerprints.resize(dep_node_index.index() + 1, Fingerprint::ZERO);
debug_assert!(fingerprints[dep_node_index] == Fingerprint::ZERO,
"DepGraph::with_task() - Duplicate fingerprint \
insertion for {:?}", key);
fingerprints[dep_node_index] = current_fingerprint;
}

debug_assert!(fingerprints[dep_node_index] == Fingerprint::ZERO,
"DepGraph::with_task() - Duplicate fingerprint \
insertion for {:?}", key);
fingerprints[dep_node_index] = current_fingerprint;
}
// Determine the color of the new DepNode.
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);

// Determine the color of the new DepNode.
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);
let color = if current_fingerprint == prev_fingerprint {
DepNodeColor::Green(dep_node_index)
} else {
DepNodeColor::Red
};

let color = if current_fingerprint == prev_fingerprint {
DepNodeColor::Green(dep_node_index)
} else {
DepNodeColor::Red
};
let mut colors = data.colors.borrow_mut();
debug_assert!(colors.get(prev_index).is_none(),
"DepGraph::with_task() - Duplicate DepNodeColor \
insertion for {:?}", key);

colors.insert(prev_index, color);
}
} else {
// Always store a ZERO fingerprint
{
let mut fingerprints = self.fingerprints.borrow_mut();

let mut colors = data.colors.borrow_mut();
debug_assert!(colors.get(prev_index).is_none(),
"DepGraph::with_task() - Duplicate DepNodeColor \
insertion for {:?}", key);
if dep_node_index.index() >= fingerprints.len() {
fingerprints.resize(dep_node_index.index() + 1, Fingerprint::ZERO);
}

fingerprints[dep_node_index] = Fingerprint::ZERO;
}

colors.insert(prev_index, color);
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
data.colors.borrow_mut().insert(prev_index, DepNodeColor::Red);
}
}

(result, dep_node_index)
Expand Down Expand Up @@ -378,7 +414,7 @@ impl DepGraph {
}

/// Execute something within an "eval-always" task which is a task
// that runs whenever anything changes.
/// that runs whenever anything changes.
pub fn with_eval_always_task<'gcx, C, A, R>(&self,
key: DepNode,
cx: C,
Expand All @@ -388,7 +424,7 @@ impl DepGraph {
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
R: HashStable<StableHashingContext<'gcx>>,
{
self.with_task_impl(key, cx, arg, false, task,
self.with_task_impl(key, cx, arg, false, true, task,
|key| OpenTask::EvalAlways { node: key },
|data, key, task| data.borrow_mut().complete_eval_always_task(key, task))
}
Expand Down Expand Up @@ -939,7 +975,11 @@ impl CurrentDepGraph {
}
}

fn complete_task(&mut self, key: DepNode, task: OpenTask) -> DepNodeIndex {
fn complete_task(&mut self,
key: DepNode,
task: OpenTask,
allow_existing_dep_node: bool)
-> DepNodeIndex {
if let OpenTask::Regular(task) = task {
let RegularOpenTask {
node,
Expand Down Expand Up @@ -970,7 +1010,16 @@ impl CurrentDepGraph {
}
}

self.alloc_node(node, reads)
if allow_existing_dep_node {
if let Some(&dep_node_index) = self.node_to_node_index.get(&node) {
self.edges[dep_node_index] = reads;
dep_node_index
} else {
self.alloc_node(node, reads)
}
} else {
self.alloc_node(node, reads)
}
} else {
bug!("complete_task() - Expected regular task to be popped")
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1973,7 +1973,7 @@ pub fn build_session_options_and_crate_config(
(&None, &None) => None,
}.map(|m| PathBuf::from(m));

if cg.lto != Lto::No && incremental.is_some() {
if cg.lto == Lto::Fat && incremental.is_some() {
early_error(
error_format,
"can't perform LTO when compiling incrementally",
Expand Down
5 changes: 0 additions & 5 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,6 @@ impl Session {
return config::Lto::No;
}

// Right now ThinLTO isn't compatible with incremental compilation.
if self.opts.incremental.is_some() {
return config::Lto::No;
}

// Now we're in "defaults" territory. By default we enable ThinLTO for
// optimized compiles (anything greater than O0).
match self.opts.optimize {
Expand Down
6 changes: 0 additions & 6 deletions src/librustc/ty/query/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,12 +702,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> {
}
}

impl<'tcx> QueryDescription<'tcx> for queries::compile_codegen_unit<'tcx> {
fn describe(_tcx: TyCtxt, _: InternedString) -> String {
format!("compile_codegen_unit")
}
}

impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("output_filenames")
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use middle::stability::{self, DeprecationEntry};
use middle::lang_items::{LanguageItems, LangItem};
use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
use mir::interpret::ConstEvalResult;
use mir::mono::{CodegenUnit, Stats};
use mir::mono::CodegenUnit;
use mir;
use mir::interpret::{GlobalId, Allocation};
use session::{CompileResult, CrateDisambiguator};
Expand Down Expand Up @@ -436,7 +436,6 @@ define_queries! { <'tcx>
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
[] fn is_codegened_item: IsCodegenedItem(DefId) -> bool,
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
[] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
[] fn output_filenames: output_filenames_node(CrateNum)
-> Arc<OutputFilenames>,

Expand Down
4 changes: 4 additions & 0 deletions src/librustc_codegen_llvm/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,10 @@ impl ThinLTOImports {
}
}

pub fn modules_imported_by(&self, llvm_module_name: &str) -> &[String] {
self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
}

/// Load the ThinLTO import map from ThinLTOData.
unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports {
let raw_data: *const llvm::ThinLTOModuleImports =
Expand Down
Loading

0 comments on commit 4e28b6c

Please sign in to comment.