Skip to content

Commit 4e28b6c

Browse files
Use ThinLTO import information when doing incremental compilation.
1 parent 81daa48 commit 4e28b6c

File tree

9 files changed

+212
-99
lines changed

9 files changed

+212
-99
lines changed

src/librustc/dep_graph/graph.rs

+82-33
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,31 @@ impl DepGraph {
204204
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
205205
R: HashStable<StableHashingContext<'gcx>>,
206206
{
207-
self.with_task_impl(key, cx, arg, false, task,
207+
self.with_task_impl(key, cx, arg, false, true, task,
208208
|key| OpenTask::Regular(Lock::new(RegularOpenTask {
209209
node: key,
210210
reads: SmallVec::new(),
211211
read_set: FxHashSet(),
212212
})),
213-
|data, key, task| data.borrow_mut().complete_task(key, task))
213+
|data, key, task| data.borrow_mut().complete_task(key, task, false))
214+
}
215+
216+
pub fn with_forced_task<'gcx, C, A, R>(&self,
217+
key: DepNode,
218+
cx: C,
219+
arg: A,
220+
task: fn(C, A) -> R)
221+
-> (R, DepNodeIndex)
222+
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
223+
R: HashStable<StableHashingContext<'gcx>>,
224+
{
225+
self.with_task_impl(key, cx, arg, false, false, task,
226+
|key| OpenTask::Regular(Lock::new(RegularOpenTask {
227+
node: key,
228+
reads: SmallVec::new(),
229+
read_set: FxHashSet(),
230+
})),
231+
|data, key, task| data.borrow_mut().complete_task(key, task, true))
214232
}
215233

216234
/// Creates a new dep-graph input with value `input`
@@ -226,7 +244,7 @@ impl DepGraph {
226244
arg
227245
}
228246

229-
self.with_task_impl(key, cx, input, true, identity_fn,
247+
self.with_task_impl(key, cx, input, true, true, identity_fn,
230248
|_| OpenTask::Ignore,
231249
|data, key, _| data.borrow_mut().alloc_node(key, SmallVec::new()))
232250
}
@@ -237,6 +255,7 @@ impl DepGraph {
237255
cx: C,
238256
arg: A,
239257
no_tcx: bool,
258+
do_fingerprinting: bool,
240259
task: fn(C, A) -> R,
241260
create_task: fn(DepNode) -> OpenTask,
242261
finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
@@ -282,41 +301,58 @@ impl DepGraph {
282301

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

285-
let mut stable_hasher = StableHasher::new();
286-
result.hash_stable(&mut hcx, &mut stable_hasher);
304+
if do_fingerprinting {
305+
let mut stable_hasher = StableHasher::new();
306+
result.hash_stable(&mut hcx, &mut stable_hasher);
287307

288-
let current_fingerprint = stable_hasher.finish();
308+
let current_fingerprint = stable_hasher.finish();
289309

290-
// Store the current fingerprint
291-
{
292-
let mut fingerprints = self.fingerprints.borrow_mut();
310+
// Store the current fingerprint
311+
{
312+
let mut fingerprints = self.fingerprints.borrow_mut();
313+
314+
if dep_node_index.index() >= fingerprints.len() {
315+
fingerprints.resize(dep_node_index.index() + 1, Fingerprint::ZERO);
316+
}
293317

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

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

304-
// Determine the color of the new DepNode.
305-
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
306-
let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);
328+
let color = if current_fingerprint == prev_fingerprint {
329+
DepNodeColor::Green(dep_node_index)
330+
} else {
331+
DepNodeColor::Red
332+
};
307333

308-
let color = if current_fingerprint == prev_fingerprint {
309-
DepNodeColor::Green(dep_node_index)
310-
} else {
311-
DepNodeColor::Red
312-
};
334+
let mut colors = data.colors.borrow_mut();
335+
debug_assert!(colors.get(prev_index).is_none(),
336+
"DepGraph::with_task() - Duplicate DepNodeColor \
337+
insertion for {:?}", key);
338+
339+
colors.insert(prev_index, color);
340+
}
341+
} else {
342+
// Always store a ZERO fingerprint
343+
{
344+
let mut fingerprints = self.fingerprints.borrow_mut();
313345

314-
let mut colors = data.colors.borrow_mut();
315-
debug_assert!(colors.get(prev_index).is_none(),
316-
"DepGraph::with_task() - Duplicate DepNodeColor \
317-
insertion for {:?}", key);
346+
if dep_node_index.index() >= fingerprints.len() {
347+
fingerprints.resize(dep_node_index.index() + 1, Fingerprint::ZERO);
348+
}
349+
350+
fingerprints[dep_node_index] = Fingerprint::ZERO;
351+
}
318352

319-
colors.insert(prev_index, color);
353+
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
354+
data.colors.borrow_mut().insert(prev_index, DepNodeColor::Red);
355+
}
320356
}
321357

322358
(result, dep_node_index)
@@ -378,7 +414,7 @@ impl DepGraph {
378414
}
379415

380416
/// Execute something within an "eval-always" task which is a task
381-
// that runs whenever anything changes.
417+
/// that runs whenever anything changes.
382418
pub fn with_eval_always_task<'gcx, C, A, R>(&self,
383419
key: DepNode,
384420
cx: C,
@@ -388,7 +424,7 @@ impl DepGraph {
388424
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
389425
R: HashStable<StableHashingContext<'gcx>>,
390426
{
391-
self.with_task_impl(key, cx, arg, false, task,
427+
self.with_task_impl(key, cx, arg, false, true, task,
392428
|key| OpenTask::EvalAlways { node: key },
393429
|data, key, task| data.borrow_mut().complete_eval_always_task(key, task))
394430
}
@@ -939,7 +975,11 @@ impl CurrentDepGraph {
939975
}
940976
}
941977

942-
fn complete_task(&mut self, key: DepNode, task: OpenTask) -> DepNodeIndex {
978+
fn complete_task(&mut self,
979+
key: DepNode,
980+
task: OpenTask,
981+
allow_existing_dep_node: bool)
982+
-> DepNodeIndex {
943983
if let OpenTask::Regular(task) = task {
944984
let RegularOpenTask {
945985
node,
@@ -970,7 +1010,16 @@ impl CurrentDepGraph {
9701010
}
9711011
}
9721012

973-
self.alloc_node(node, reads)
1013+
if allow_existing_dep_node {
1014+
if let Some(&dep_node_index) = self.node_to_node_index.get(&node) {
1015+
self.edges[dep_node_index] = reads;
1016+
dep_node_index
1017+
} else {
1018+
self.alloc_node(node, reads)
1019+
}
1020+
} else {
1021+
self.alloc_node(node, reads)
1022+
}
9741023
} else {
9751024
bug!("complete_task() - Expected regular task to be popped")
9761025
}

src/librustc/session/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1973,7 +1973,7 @@ pub fn build_session_options_and_crate_config(
19731973
(&None, &None) => None,
19741974
}.map(|m| PathBuf::from(m));
19751975

1976-
if cg.lto != Lto::No && incremental.is_some() {
1976+
if cg.lto == Lto::Fat && incremental.is_some() {
19771977
early_error(
19781978
error_format,
19791979
"can't perform LTO when compiling incrementally",

src/librustc/session/mod.rs

-5
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,6 @@ impl Session {
583583
return config::Lto::No;
584584
}
585585

586-
// Right now ThinLTO isn't compatible with incremental compilation.
587-
if self.opts.incremental.is_some() {
588-
return config::Lto::No;
589-
}
590-
591586
// Now we're in "defaults" territory. By default we enable ThinLTO for
592587
// optimized compiles (anything greater than O0).
593588
match self.opts.optimize {

src/librustc/ty/query/config.rs

-6
Original file line numberDiff line numberDiff line change
@@ -702,12 +702,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> {
702702
}
703703
}
704704

705-
impl<'tcx> QueryDescription<'tcx> for queries::compile_codegen_unit<'tcx> {
706-
fn describe(_tcx: TyCtxt, _: InternedString) -> String {
707-
format!("compile_codegen_unit")
708-
}
709-
}
710-
711705
impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
712706
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
713707
format!("output_filenames")

src/librustc/ty/query/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use middle::stability::{self, DeprecationEntry};
2727
use middle::lang_items::{LanguageItems, LangItem};
2828
use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
2929
use mir::interpret::ConstEvalResult;
30-
use mir::mono::{CodegenUnit, Stats};
30+
use mir::mono::CodegenUnit;
3131
use mir;
3232
use mir::interpret::{GlobalId, Allocation};
3333
use session::{CompileResult, CrateDisambiguator};
@@ -436,7 +436,6 @@ define_queries! { <'tcx>
436436
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
437437
[] fn is_codegened_item: IsCodegenedItem(DefId) -> bool,
438438
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
439-
[] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
440439
[] fn output_filenames: output_filenames_node(CrateNum)
441440
-> Arc<OutputFilenames>,
442441

src/librustc_codegen_llvm/back/lto.rs

+4
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,10 @@ impl ThinLTOImports {
811811
}
812812
}
813813

814+
pub fn modules_imported_by(&self, llvm_module_name: &str) -> &[String] {
815+
self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
816+
}
817+
814818
/// Load the ThinLTO import map from ThinLTOData.
815819
unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports {
816820
let raw_data: *const llvm::ThinLTOModuleImports =

0 commit comments

Comments
 (0)