-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disambiguate expansions relative to the creating DepNode #111815
Conversation
r? @wesleywiser (rustbot has picked a reviewer for you, use r? to override) |
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
This comment was marked as outdated.
This comment was marked as outdated.
c564776
to
ffa197c
Compare
@@ -31,6 +31,10 @@ pub struct ImplicitCtxt<'a, 'tcx> { | |||
/// Used to prevent queries from calling too deeply. | |||
pub query_depth: usize, | |||
|
|||
/// The DepNode of the query being executed. This is updated by the dep-graph. Thisis used to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// The DepNode of the query being executed. This is updated by the dep-graph. Thisis used to | |
/// The DepNode of the query being executed. This is updated by the dep-graph. This is used to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this makes sense to me and the implementation does what you describe, but I'm far from fully grokking all the implications. I still think we should land it, unless you want to have someone else review it additionally.
/// Fill an empty expansion. This method must not be used outside of the resolver. | ||
#[inline] | ||
#[instrument(level = "trace", skip(self))] | ||
pub fn finalize_expansion(self, expn_id: LocalExpnId, expn_data: ExpnData) { | ||
self.with_stable_hashing_context(|ctx| expn_id.set_untracked_expn_data(expn_data, ctx)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems like a very subtle invariant. Can it just be inlined into the resolver?
compiler/rustc_span/src/hygiene.rs
Outdated
HygieneData::with(|data| { | ||
let expn_id = data.local_expn_data.push(Some(expn_data)); | ||
let _eid = data.local_expn_hashes.push(expn_hash); | ||
debug_assert_eq!(expn_id, _eid); | ||
let _old_id = data.expn_hash_to_expn_id.insert(expn_hash, expn_id.to_expn_id()); | ||
debug_assert!(_old_id.is_none()); | ||
if !_old_id.is_none() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use is_some()
and remove the _
from the variable name
As this touches the expansion infra, cc @petrochenkov |
15b6aa7
to
6a76425
Compare
I'm sufficiently sure that neither AST lowering nor especially MIR inlining should reuse the macro expansion machinery, just never got to investigating how to get rid of it. |
I don't really understand how dep nodes work in this context, but assume the issue in #110457 happens because expansions are created "after incremental is enabled", and earlier expansions don't have such issues because they are still at the "redo everything and hash all the results" stage? |
compiler/rustc_span/src/lib.rs
Outdated
@@ -2158,12 +2158,13 @@ where | |||
const TAG_INVALID_SPAN: u8 = 1; | |||
const TAG_RELATIVE_SPAN: u8 = 2; | |||
|
|||
// Hash expansion in all cases, even if we don't want to hash positions themselves. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why?
let _old_id = data.expn_hash_to_expn_id.insert(expn_hash, self.to_expn_id()); | ||
debug_assert!(_old_id.is_none()); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meta: code is changed and moved in the same commit, makes it harder to read the diff.
debug!( | ||
dep_node = ?tcx.dep_graph().data().unwrap().prev_node_of(prev_index), | ||
?new_hash, ?old_hash, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: temporary debug output not removed (in some other places too).
compiler/rustc_span/src/hygiene.rs
Outdated
pub fn fresh_empty() -> LocalExpnId { | ||
/// Create a new expansions without any information. This method must not be used outside of | ||
/// the resolver. | ||
pub fn reserve_expansion_id() -> LocalExpnId { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub fn reserve_expansion_id() -> LocalExpnId { | |
pub fn reserve_expn_id() -> LocalExpnId { |
Nit: it's pretty much always conventionally abbreviated in the current code.
compiler/rustc_span/src/hygiene.rs
Outdated
pub struct FakeDepNode { | ||
pub kind: u16, | ||
pub hash: PackedFingerprint, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some back and forth changes in the commits, probably makes sense to cleanup the history.
compiler/rustc_span/src/hygiene.rs
Outdated
@@ -1484,44 +1471,38 @@ impl<D: Decoder> Decodable<D> for SyntaxContext { | |||
#[instrument(level = "trace", skip(ctx), ret)] | |||
fn update_disambiguator( | |||
expn_data: &mut ExpnData, | |||
dep_node: FakeDepNode, | |||
hash_extra: impl Hash + Copy + fmt::Debug, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hash_extra: impl Hash + Copy + fmt::Debug, | |
hash_extra: impl Hash + Copy |
Unused bound (in a couple of other places too).
pub fn regular(dep_node: DepNode<K>) -> CurrentDepNode<K> { | ||
CurrentDepNode::Regular { | ||
dep_node, | ||
expn_disambiguators: Lrc::new(Lock::new(UnhashMap::default())), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expn_disambiguators: Lrc::new(Lock::new(UnhashMap::default())), | |
expn_disambiguators: Default::default(), |
Fingers crossed.
@@ -142,7 +142,7 @@ impl QueryContext for QueryCtxt<'_> { | |||
query: Some(token), | |||
diagnostics, | |||
query_depth: current_icx.query_depth + depth_limit as usize, | |||
current_node: current_icx.current_node, | |||
current_node: current_icx.current_node.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So there are two clones of the expansion disambiguation map and only one of them is updated.
Are changes to current_node.expn_disambiguators
written back to current_icx.current_node.expn_disambiguators
anywhere, or what is happening here?
Easy, we can just nuke it without replacement. The use case for it has since been refactored away, so at best it would cause a minor mir opt change |
Remove ExpnKind::Inlined. Suggested in rust-lang#111815 (comment) r? `@oli-obk`
Remove ExpnKind::Inlined. Suggested in rust-lang#111815 (comment) r? ``@oli-obk``
☔ The latest upstream changes (presumably #111960) made this pull request unmergeable. Please resolve the merge conflicts. |
Remove ExpnKind::Inlined. Suggested in rust-lang/rust#111815 (comment) r? ``@oli-obk``
6a76425
to
315d403
Compare
This comment was marked as outdated.
This comment was marked as outdated.
315d403
to
97a63ca
Compare
Exactly. The ICE #110457 itself has been fixed by #111952. The theoretical ICE still exists, but I don't think there is a way to trigger it right now. This global disambiguation is a footgun for incremental, so I'm still proposing to land this PR. |
Remove ExpnKind::Inlined. Suggested in rust-lang/rust#111815 (comment) r? ``@oli-obk``
The initial idea was to create expansion disambiguators per parent This solution is pretty similar to per-defpath disambiguators, right? Maybe with a slightly different granularity? |
Yes, it's quite close. As the DefPath approach was limited by perf: |
This comment has been minimized.
This comment has been minimized.
⌛ Trying commit 97a63ca with merge 516fd7002cc2ce4a8639ad243932a6e3a33a0847... |
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (516fd7002cc2ce4a8639ad243932a6e3a33a0847): comparison URL. Overall result: ❌ regressions - ACTION NEEDEDBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 647.057s -> 646.11s (-0.15%) |
Could we limit the current disambiguation mechanism to just macro expansion say via. a scoped thread local? I'd prefer to avoid extending the query system here, but I don't see any obviously wrong. It does seem this could use the |
This is not required any more, the bugs have been fixed independently. To be revisited if queries advance into the resolve. |
In which PR exactly? |
#111950? |
Both |
Expansion data requires to be disambiguated in case of colliding spans. The current disambiguation mechanism was merely looking at hash collisions using a global disambiguation counter.
This global counter created an untracked data dependency between unrelated queries. For instance here: #110457 (comment)
This PR replaces the global disambiguation map by a per-DepNode map. This requires threading the currently evaluated DepNode through the implicit context. We use a dummy in the non-incremental case to simplify the logic.