Skip to content

Commit f4e9efa

Browse files
committed
:3
1 parent d445519 commit f4e9efa

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

compiler/rustc_type_ir/src/search_graph/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::marker::PhantomData;
2121
use derive_where::derive_where;
2222
#[cfg(feature = "nightly")]
2323
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
24-
use rustc_type_ir::data_structures::HashMap;
24+
use rustc_type_ir::data_structures::{HashMap, HashSet};
2525
use tracing::{debug, instrument};
2626

2727
mod stack;
@@ -1113,7 +1113,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
11131113

11141114
/// Whether we've reached a fixpoint when evaluating a cycle head.
11151115
fn reached_fixpoint(
1116-
&mut self,
11171116
cx: X,
11181117
stack_entry: &StackEntry<X>,
11191118
usage_kind: UsageKind,
@@ -1161,7 +1160,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
11611160
// is equal to the provisional result of the previous iteration, or because
11621161
// this was only the root of either coinductive or inductive cycles, and the
11631162
// final result is equal to the initial response for that case.
1164-
if self.reached_fixpoint(cx, &stack_entry, usage_kind, result) {
1163+
if Self::reached_fixpoint(cx, &stack_entry, usage_kind, result) {
11651164
Self::rebase_provisional_cache_entries(
11661165
&self.stack,
11671166
&mut self.provisional_cache,
@@ -1270,7 +1269,9 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
12701269
let truncate_stack = |stack: &mut Stack<X>, provisional_cache: &mut _, depth| {
12711270
while stack.next_index() > depth {
12721271
let reeval_entry = stack.pop();
1273-
// TODO
1272+
// TODO: How can we tell whether this entry was the final revision.
1273+
//
1274+
// We should be able to rebase provisional entries in most cases.
12741275
Self::clear_dependent_provisional_results(stack, provisional_cache);
12751276
Self::update_parent_goal(
12761277
stack,
@@ -1286,6 +1287,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
12861287
let cycles = self.tree.rerun_get_and_reset_cycles(prev_stack_entry.node_id);
12871288
let current_stack_len = self.stack.len();
12881289
let mut first_cycle = true;
1290+
let mut has_changed = HashSet::default();
12891291
'outer: for cycle in cycles {
12901292
let &tree::Cycle { node_id: cycle_node_id, ref provisional_results } =
12911293
self.tree.get_cycle(cycle);
@@ -1310,6 +1312,13 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
13101312
if !self.tree.get_heads(entry_node_id).contains_stack_entry(current_depth) {
13111313
continue;
13121314
}
1315+
1316+
// We've evaluated the `entry_node_id` before evaluating this goal. In case
1317+
// that node and its parents has not changed, we can reinsert the cache entry
1318+
// before starting to reevaluate it.
1319+
if !self.tree.goal_or_parent_has_changed(node_id, &has_changed, entry_node_id) {
1320+
continue;
1321+
}
13131322
}
13141323
};
13151324

@@ -1345,8 +1354,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
13451354
while let Some(&(stack_depth, node_id, info)) = added_goals.peek() {
13461355
if let Some(existing_entry) = self.stack.get(stack_depth) {
13471356
let provisional_result = provisional_results.get(&stack_depth).copied();
1348-
// Issue: changing the provisional result means we must not rebase, but instead
1349-
// invalidate.
13501357
if existing_entry.node_id == node_id
13511358
&& provisional_result == existing_entry.provisional_result
13521359
{
@@ -1410,10 +1417,10 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
14101417
debug!(input = ?current_goal.1.input, ?result, "goal did not change");
14111418
continue 'outer;
14121419
} else {
1420+
has_changed.insert(current_goal.0);
14131421
debug!(input = ?current_goal.1.input, ?result, "goal did change");
14141422
if self.stack.len() > current_stack_len {
14151423
let parent = self.stack.pop();
1416-
// TODO
14171424
Self::clear_dependent_provisional_results(
14181425
&self.stack,
14191426
&mut self.provisional_cache,

compiler/rustc_type_ir/src/search_graph/tree.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ops::Range;
33

44
use derive_where::derive_where;
55
use rustc_index::IndexVec;
6-
use rustc_type_ir::data_structures::HashMap;
6+
use rustc_type_ir::data_structures::{HashMap, HashSet};
77

88
use crate::search_graph::{AvailableDepth, Cx, CycleHeads, PathKind, Stack, StackDepth};
99

@@ -175,6 +175,23 @@ impl<X: Cx> SearchTree<X> {
175175
}
176176
}
177177

178+
pub(super) fn goal_or_parent_has_changed(
179+
&self,
180+
cycle_head: NodeId,
181+
has_changed: &HashSet<NodeId>,
182+
mut node_id: NodeId,
183+
) -> bool {
184+
loop {
185+
if node_id == cycle_head {
186+
return false;
187+
} else if has_changed.contains(&node_id) {
188+
return true;
189+
} else {
190+
node_id = self.nodes[node_id].parent.unwrap();
191+
}
192+
}
193+
}
194+
178195
/// Compute the list of parents of `node_id` until encountering the node
179196
/// `until`. We're excluding `until` and are including `node_id`.
180197
pub(super) fn compute_rev_stack(

0 commit comments

Comments
 (0)