diff options
| author | Nicholas Nethercote <nnethercote@mozilla.com> | 2019-12-06 13:31:40 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <nnethercote@mozilla.com> | 2019-12-13 08:36:25 +1100 |
| commit | 7d550445e2b650ec198ef1c6de19612f0dc6287e (patch) | |
| tree | e89a57329180571927c6905c2a44f09de2ae612a | |
| parent | a8207b195840fc664ffc4a9c033cd3ee0746ea2e (diff) | |
| download | rust-7d550445e2b650ec198ef1c6de19612f0dc6287e.tar.gz rust-7d550445e2b650ec198ef1c6de19612f0dc6287e.zip | |
Move functions around.
In particular, it has bugged me for some time that `process_cycles` is currently located before `mark_still_waiting_nodes` despite being called afterwards.
| -rw-r--r-- | src/librustc_data_structures/obligation_forest/mod.rs | 118 |
1 files changed, 59 insertions, 59 deletions
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 020facff5ff..54b014a0f28 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -520,57 +520,6 @@ impl<O: ForestObligation> ObligationForest<O> { } } - /// Report cycles between all `Success` nodes that aren't still waiting. - /// This must be called after `mark_still_waiting_nodes`. - fn process_cycles<P>(&self, processor: &mut P) - where P: ObligationProcessor<Obligation=O> - { - let mut stack = vec![]; - - debug!("process_cycles()"); - - for (index, node) in self.nodes.iter().enumerate() { - // For some benchmarks this state test is extremely hot. It's a win - // to handle the no-op cases immediately to avoid the cost of the - // function call. - if let NodeState::Success(waiting) = node.state.get() { - if !self.is_still_waiting(waiting) { - self.find_cycles_from_node(&mut stack, processor, index); - } - } - } - - debug!("process_cycles: complete"); - - debug_assert!(stack.is_empty()); - } - - fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>, processor: &mut P, index: usize) - where P: ObligationProcessor<Obligation=O> - { - let node = &self.nodes[index]; - if let NodeState::Success(waiting) = node.state.get() { - if !self.is_still_waiting(waiting) { - match stack.iter().rposition(|&n| n == index) { - None => { - stack.push(index); - for &index in node.dependents.iter() { - self.find_cycles_from_node(stack, processor, index); - } - stack.pop(); - } - Some(rpos) => { - // Cycle detected. - processor.process_backedge( - stack[rpos..].iter().map(GetObligation(&self.nodes)), - PhantomData - ); - } - } - } - } - } - /// Returns a vector of obligations for `p` and all of its /// ancestors, putting them into the error state in the process. fn error_at(&self, mut index: usize) -> Vec<O> { @@ -604,6 +553,18 @@ impl<O: ForestObligation> ObligationForest<O> { trace } + /// Mark all `Success` nodes that depend on a pending node as still + /// waiting. Upon completion, any `Success` nodes that aren't still waiting + /// can be removed by `compress`. + fn mark_still_waiting_nodes(&self) { + for node in &self.nodes { + if node.state.get() == NodeState::Pending { + // This call site is hot. + self.inlined_mark_dependents_as_still_waiting(node); + } + } + } + // This always-inlined function is for the hot call site. #[inline(always)] fn inlined_mark_dependents_as_still_waiting(&self, node: &Node<O>) { @@ -625,14 +586,53 @@ impl<O: ForestObligation> ObligationForest<O> { self.inlined_mark_dependents_as_still_waiting(node) } - /// Mark all `Success` nodes that depend on a pending node as still - /// waiting. Upon completion, any `Success` nodes that aren't still waiting - /// can be removed by `compress`. - fn mark_still_waiting_nodes(&self) { - for node in &self.nodes { - if node.state.get() == NodeState::Pending { - // This call site is hot. - self.inlined_mark_dependents_as_still_waiting(node); + /// Report cycles between all `Success` nodes that aren't still waiting. + /// This must be called after `mark_still_waiting_nodes`. + fn process_cycles<P>(&self, processor: &mut P) + where P: ObligationProcessor<Obligation=O> + { + let mut stack = vec![]; + + debug!("process_cycles()"); + + for (index, node) in self.nodes.iter().enumerate() { + // For some benchmarks this state test is extremely hot. It's a win + // to handle the no-op cases immediately to avoid the cost of the + // function call. + if let NodeState::Success(waiting) = node.state.get() { + if !self.is_still_waiting(waiting) { + self.find_cycles_from_node(&mut stack, processor, index); + } + } + } + + debug!("process_cycles: complete"); + + debug_assert!(stack.is_empty()); + } + + fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>, processor: &mut P, index: usize) + where P: ObligationProcessor<Obligation=O> + { + let node = &self.nodes[index]; + if let NodeState::Success(waiting) = node.state.get() { + if !self.is_still_waiting(waiting) { + match stack.iter().rposition(|&n| n == index) { + None => { + stack.push(index); + for &index in node.dependents.iter() { + self.find_cycles_from_node(stack, processor, index); + } + stack.pop(); + } + Some(rpos) => { + // Cycle detected. + processor.process_backedge( + stack[rpos..].iter().map(GetObligation(&self.nodes)), + PhantomData + ); + } + } } } } |
