Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
incr.comp.: Allow for more fine-grained testing of CGU reuse and use …
…it to test incremental ThinLTO.
- Loading branch information
1 parent
b80cb47
commit ca19732
Showing
12 changed files
with
373 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Copyright 2018 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. | ||
|
||
//! Some facilities for tracking how codegen-units are reused during incremental | ||
//! compilition. This is used for incremental compiliation tests and debug | ||
//! output. | ||
|
||
use session::Session; | ||
use rustc_data_structures::fx::FxHashMap; | ||
use std::sync::{Arc, Mutex}; | ||
use syntax_pos::Span; | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] | ||
pub enum CguReuse { | ||
No, | ||
PreLto, | ||
PostLto, | ||
} | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq)] | ||
pub enum ComparisonKind { | ||
Exact, | ||
AtLeast, | ||
} | ||
|
||
struct TrackerData { | ||
actual_reuse: FxHashMap<String, CguReuse>, | ||
expected_reuse: FxHashMap<String, (String, SendSpan, CguReuse, ComparisonKind)>, | ||
} | ||
|
||
// Span does not implement `Send`, so we can't just store it in the shared | ||
// `TrackerData` object. Instead of splitting up `TrackerData` into shared and | ||
// non-shared parts (which would be complicated), we just mark the `Span` here | ||
// explicitly as `Send`. That's safe because the span data here is only ever | ||
// accessed from the main thread. | ||
struct SendSpan(Span); | ||
unsafe impl Send for SendSpan {} | ||
|
||
#[derive(Clone)] | ||
pub struct CguReuseTracker { | ||
data: Option<Arc<Mutex<TrackerData>>>, | ||
} | ||
|
||
impl CguReuseTracker { | ||
pub fn new() -> CguReuseTracker { | ||
let data = TrackerData { | ||
actual_reuse: FxHashMap(), | ||
expected_reuse: FxHashMap(), | ||
}; | ||
|
||
CguReuseTracker { | ||
data: Some(Arc::new(Mutex::new(data))), | ||
} | ||
} | ||
|
||
pub fn new_disabled() -> CguReuseTracker { | ||
CguReuseTracker { | ||
data: None, | ||
} | ||
} | ||
|
||
pub fn set_actual_reuse(&self, cgu_name: &str, kind: CguReuse) { | ||
if let Some(ref data) = self.data { | ||
debug!("set_actual_reuse({:?}, {:?})", cgu_name, kind); | ||
|
||
let prev_reuse = data.lock() | ||
.unwrap() | ||
.actual_reuse | ||
.insert(cgu_name.to_string(), kind); | ||
|
||
if let Some(prev_reuse) = prev_reuse { | ||
// The only time it is legal to overwrite reuse state is when | ||
// we discover during ThinLTO that we can actually reuse the | ||
// post-LTO version of a CGU. | ||
assert_eq!(prev_reuse, CguReuse::PreLto); | ||
} | ||
} | ||
} | ||
|
||
pub fn set_expectation(&self, | ||
cgu_name: &str, | ||
cgu_user_name: &str, | ||
error_span: Span, | ||
expected_reuse: CguReuse, | ||
comparison_kind: ComparisonKind) { | ||
if let Some(ref data) = self.data { | ||
debug!("set_expectation({:?}, {:?}, {:?})", cgu_name, | ||
expected_reuse, | ||
comparison_kind); | ||
let mut data = data.lock().unwrap(); | ||
|
||
data.expected_reuse.insert(cgu_name.to_string(), | ||
(cgu_user_name.to_string(), | ||
SendSpan(error_span), | ||
expected_reuse, | ||
comparison_kind)); | ||
} | ||
} | ||
|
||
pub fn check_expected_reuse(&self, sess: &Session) { | ||
if let Some(ref data) = self.data { | ||
let data = data.lock().unwrap(); | ||
|
||
for (cgu_name, &(ref cgu_user_name, | ||
ref error_span, | ||
expected_reuse, | ||
comparison_kind)) in &data.expected_reuse { | ||
if let Some(&actual_reuse) = data.actual_reuse.get(cgu_name) { | ||
let (error, at_least) = match comparison_kind { | ||
ComparisonKind::Exact => { | ||
(expected_reuse != actual_reuse, false) | ||
} | ||
ComparisonKind::AtLeast => { | ||
(actual_reuse < expected_reuse, true) | ||
} | ||
}; | ||
|
||
if error { | ||
let at_least = if at_least { "at least " } else { "" }; | ||
let msg = format!("CGU-reuse for `{}` is `{:?}` but \ | ||
should be {}`{:?}`", | ||
cgu_user_name, | ||
actual_reuse, | ||
at_least, | ||
expected_reuse); | ||
sess.span_err(error_span.0, &msg); | ||
} | ||
} else { | ||
let msg = format!("CGU-reuse for `{}` (mangled: `{}`) was \ | ||
not recorded", | ||
cgu_user_name, | ||
cgu_name); | ||
sess.span_fatal(error_span.0, &msg); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.