Skip to content

Commit

Permalink
Rollup merge of rust-lang#123934 - WaffleLapkin:graph-mini-refactor, …
Browse files Browse the repository at this point in the history
…r=fmease

`rustc_data_structures::graph` mini refactor

Who doesn't love to breathe dust from the ancient times?
  • Loading branch information
jieyouxu committed Apr 15, 2024
2 parents b79d0b0 + 435db9b commit 5580ae9
Show file tree
Hide file tree
Showing 18 changed files with 89 additions and 193 deletions.
13 changes: 2 additions & 11 deletions compiler/rustc_borrowck/src/constraints/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,23 +216,14 @@ impl<'s, 'tcx, D: ConstraintGraphDirection> Iterator for Successors<'s, 'tcx, D>

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::DirectedGraph for RegionGraph<'s, 'tcx, D> {
type Node = RegionVid;
}

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::WithNumNodes for RegionGraph<'s, 'tcx, D> {
fn num_nodes(&self) -> usize {
self.constraint_graph.first_constraints.len()
}
}

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::WithSuccessors for RegionGraph<'s, 'tcx, D> {
fn successors(&self, node: Self::Node) -> <Self as graph::GraphSuccessors<'_>>::Iter {
impl<'s, 'tcx, D: ConstraintGraphDirection> graph::Successors for RegionGraph<'s, 'tcx, D> {
fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
self.outgoing_regions(node)
}
}

impl<'s, 'tcx, D: ConstraintGraphDirection> graph::GraphSuccessors<'_>
for RegionGraph<'s, 'tcx, D>
{
type Item = RegionVid;
type Iter = Successors<'s, 'tcx, D>;
}
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::graph::WithSuccessors;
use rustc_data_structures::graph;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{
self, BasicBlock, Body, CallReturnPlaces, Location, Place, TerminatorEdges,
Expand Down Expand Up @@ -262,7 +262,7 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {

// We first handle the cases where the loan doesn't go out of scope, depending on the issuing
// region's successors.
for successor in self.regioncx.region_graph().depth_first_search(issuing_region) {
for successor in graph::depth_first_search(&self.regioncx.region_graph(), issuing_region) {
// 1. Via applied member constraints
//
// The issuing region can flow into the choice regions, and they are either:
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::constraints::ConstraintSccIndex;
use crate::RegionInferenceContext;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph;
use rustc_data_structures::graph::vec_graph::VecGraph;
use rustc_data_structures::graph::WithSuccessors;
use rustc_middle::ty::RegionVid;
use std::ops::Range;

Expand All @@ -23,8 +23,7 @@ impl ReverseSccGraph {
scc0: ConstraintSccIndex,
) -> impl Iterator<Item = RegionVid> + 'a {
let mut duplicates = FxIndexSet::default();
self.graph
.depth_first_search(scc0)
graph::depth_first_search(&self.graph, scc0)
.flat_map(move |scc1| {
self.scc_regions
.get(&scc1)
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph::WithSuccessors;
use rustc_index::bit_set::BitSet;
use rustc_index::interval::IntervalSet;
use rustc_infer::infer::canonical::QueryRegionConstraints;
Expand Down Expand Up @@ -64,7 +63,10 @@ pub(super) fn trace<'mir, 'tcx>(
// Traverse each issuing region's constraints, and record the loan as flowing into the
// outlived region.
for (loan, issuing_region_data) in borrow_set.iter_enumerated() {
for succ in region_graph.depth_first_search(issuing_region_data.region) {
for succ in rustc_data_structures::graph::depth_first_search(
&region_graph,
issuing_region_data.region,
) {
// We don't need to mention that a loan flows into its issuing region.
if succ == issuing_region_data.region {
continue;
Expand Down
24 changes: 12 additions & 12 deletions compiler/rustc_data_structures/src/graph/iterate/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use super::{DirectedGraph, WithNumNodes, WithStartNode, WithSuccessors};
use super::{DirectedGraph, StartNode, Successors};
use rustc_index::bit_set::BitSet;
use rustc_index::{IndexSlice, IndexVec};
use std::ops::ControlFlow;

#[cfg(test)]
mod tests;

pub fn post_order_from<G: DirectedGraph + WithSuccessors + WithNumNodes>(
pub fn post_order_from<G: DirectedGraph + Successors>(
graph: &G,
start_node: G::Node,
) -> Vec<G::Node> {
post_order_from_to(graph, start_node, None)
}

pub fn post_order_from_to<G: DirectedGraph + WithSuccessors + WithNumNodes>(
pub fn post_order_from_to<G: DirectedGraph + Successors>(
graph: &G,
start_node: G::Node,
end_node: Option<G::Node>,
Expand All @@ -27,7 +27,7 @@ pub fn post_order_from_to<G: DirectedGraph + WithSuccessors + WithNumNodes>(
result
}

fn post_order_walk<G: DirectedGraph + WithSuccessors + WithNumNodes>(
fn post_order_walk<G: DirectedGraph + Successors>(
graph: &G,
node: G::Node,
result: &mut Vec<G::Node>,
Expand Down Expand Up @@ -60,7 +60,7 @@ fn post_order_walk<G: DirectedGraph + WithSuccessors + WithNumNodes>(
}
}

pub fn reverse_post_order<G: DirectedGraph + WithSuccessors + WithNumNodes>(
pub fn reverse_post_order<G: DirectedGraph + Successors>(
graph: &G,
start_node: G::Node,
) -> Vec<G::Node> {
Expand All @@ -72,7 +72,7 @@ pub fn reverse_post_order<G: DirectedGraph + WithSuccessors + WithNumNodes>(
/// A "depth-first search" iterator for a directed graph.
pub struct DepthFirstSearch<'graph, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
G: ?Sized + DirectedGraph + Successors,
{
graph: &'graph G,
stack: Vec<G::Node>,
Expand All @@ -81,7 +81,7 @@ where

impl<'graph, G> DepthFirstSearch<'graph, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
G: ?Sized + DirectedGraph + Successors,
{
pub fn new(graph: &'graph G) -> Self {
Self { graph, stack: vec![], visited: BitSet::new_empty(graph.num_nodes()) }
Expand Down Expand Up @@ -127,7 +127,7 @@ where

impl<G> std::fmt::Debug for DepthFirstSearch<'_, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
G: ?Sized + DirectedGraph + Successors,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut f = fmt.debug_set();
Expand All @@ -140,7 +140,7 @@ where

impl<G> Iterator for DepthFirstSearch<'_, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
G: ?Sized + DirectedGraph + Successors,
{
type Item = G::Node;

Expand Down Expand Up @@ -201,7 +201,7 @@ struct Event<N> {
/// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms
pub struct TriColorDepthFirstSearch<'graph, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
G: ?Sized + DirectedGraph + Successors,
{
graph: &'graph G,
stack: Vec<Event<G::Node>>,
Expand All @@ -211,7 +211,7 @@ where

impl<'graph, G> TriColorDepthFirstSearch<'graph, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
G: ?Sized + DirectedGraph + Successors,
{
pub fn new(graph: &'graph G) -> Self {
TriColorDepthFirstSearch {
Expand Down Expand Up @@ -278,7 +278,7 @@ where

impl<G> TriColorDepthFirstSearch<'_, G>
where
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors + WithStartNode,
G: ?Sized + DirectedGraph + Successors + StartNode,
{
/// Performs a depth-first search, starting from `G::start_node()`.
///
Expand Down
63 changes: 18 additions & 45 deletions compiler/rustc_data_structures/src/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,70 +12,43 @@ mod tests;

pub trait DirectedGraph {
type Node: Idx;
}

pub trait WithNumNodes: DirectedGraph {
fn num_nodes(&self) -> usize;
}

pub trait WithNumEdges: DirectedGraph {
pub trait NumEdges: DirectedGraph {
fn num_edges(&self) -> usize;
}

pub trait WithSuccessors: DirectedGraph
where
Self: for<'graph> GraphSuccessors<'graph, Item = <Self as DirectedGraph>::Node>,
{
fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter;

fn depth_first_search(&self, from: Self::Node) -> iterate::DepthFirstSearch<'_, Self>
where
Self: WithNumNodes,
{
iterate::DepthFirstSearch::new(self).with_start_node(from)
}
}

#[allow(unused_lifetimes)]
pub trait GraphSuccessors<'graph> {
type Item;
type Iter: Iterator<Item = Self::Item>;
}

pub trait WithPredecessors: DirectedGraph
where
Self: for<'graph> GraphPredecessors<'graph, Item = <Self as DirectedGraph>::Node>,
{
fn predecessors(&self, node: Self::Node) -> <Self as GraphPredecessors<'_>>::Iter;
}

#[allow(unused_lifetimes)]
pub trait GraphPredecessors<'graph> {
type Item;
type Iter: Iterator<Item = Self::Item>;
}

pub trait WithStartNode: DirectedGraph {
pub trait StartNode: DirectedGraph {
fn start_node(&self) -> Self::Node;
}

pub trait ControlFlowGraph:
DirectedGraph + WithStartNode + WithPredecessors + WithSuccessors + WithNumNodes
{
// convenient trait
pub trait Successors: DirectedGraph {
fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node>;
}

impl<T> ControlFlowGraph for T where
T: DirectedGraph + WithStartNode + WithPredecessors + WithSuccessors + WithNumNodes
{
pub trait Predecessors: DirectedGraph {
fn predecessors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node>;
}

/// Alias for [`DirectedGraph`] + [`StartNode`] + [`Predecessors`] + [`Successors`].
pub trait ControlFlowGraph: DirectedGraph + StartNode + Predecessors + Successors {}
impl<T> ControlFlowGraph for T where T: DirectedGraph + StartNode + Predecessors + Successors {}

/// Returns `true` if the graph has a cycle that is reachable from the start node.
pub fn is_cyclic<G>(graph: &G) -> bool
where
G: ?Sized + DirectedGraph + WithStartNode + WithSuccessors + WithNumNodes,
G: ?Sized + DirectedGraph + StartNode + Successors,
{
iterate::TriColorDepthFirstSearch::new(graph)
.run_from_start(&mut iterate::CycleDetector)
.is_some()
}

pub fn depth_first_search<G>(graph: &G, from: G::Node) -> iterate::DepthFirstSearch<'_, G>
where
G: ?Sized + Successors,
{
iterate::DepthFirstSearch::new(graph).with_start_node(from)
}
22 changes: 5 additions & 17 deletions compiler/rustc_data_structures/src/graph/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,26 @@ use super::*;

impl<'graph, G: DirectedGraph> DirectedGraph for &'graph G {
type Node = G::Node;
}

impl<'graph, G: WithNumNodes> WithNumNodes for &'graph G {
fn num_nodes(&self) -> usize {
(**self).num_nodes()
}
}

impl<'graph, G: WithStartNode> WithStartNode for &'graph G {
impl<'graph, G: StartNode> StartNode for &'graph G {
fn start_node(&self) -> Self::Node {
(**self).start_node()
}
}

impl<'graph, G: WithSuccessors> WithSuccessors for &'graph G {
fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
impl<'graph, G: Successors> Successors for &'graph G {
fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
(**self).successors(node)
}
}

impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G {
fn predecessors(&self, node: Self::Node) -> <Self as GraphPredecessors<'_>>::Iter {
impl<'graph, G: Predecessors> Predecessors for &'graph G {
fn predecessors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
(**self).predecessors(node)
}
}

impl<'iter, 'graph, G: WithPredecessors> GraphPredecessors<'iter> for &'graph G {
type Item = G::Node;
type Iter = <G as GraphPredecessors<'iter>>::Iter;
}

impl<'iter, 'graph, G: WithSuccessors> GraphSuccessors<'iter> for &'graph G {
type Item = G::Node;
type Iter = <G as GraphSuccessors<'iter>>::Iter;
}
24 changes: 8 additions & 16 deletions compiler/rustc_data_structures/src/graph/scc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

use crate::fx::FxHashSet;
use crate::graph::vec_graph::VecGraph;
use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors};
use crate::graph::{DirectedGraph, NumEdges, Successors};
use rustc_index::{Idx, IndexSlice, IndexVec};
use std::ops::Range;

Expand Down Expand Up @@ -39,7 +39,7 @@ pub struct SccData<S: Idx> {
}

impl<N: Idx, S: Idx + Ord> Sccs<N, S> {
pub fn new(graph: &(impl DirectedGraph<Node = N> + WithNumNodes + WithSuccessors)) -> Self {
pub fn new(graph: &(impl DirectedGraph<Node = N> + Successors)) -> Self {
SccsConstruction::construct(graph)
}

Expand Down Expand Up @@ -89,30 +89,22 @@ impl<N: Idx, S: Idx + Ord> Sccs<N, S> {
}
}

impl<N: Idx, S: Idx> DirectedGraph for Sccs<N, S> {
impl<N: Idx, S: Idx + Ord> DirectedGraph for Sccs<N, S> {
type Node = S;
}

impl<N: Idx, S: Idx + Ord> WithNumNodes for Sccs<N, S> {
fn num_nodes(&self) -> usize {
self.num_sccs()
}
}

impl<N: Idx, S: Idx> WithNumEdges for Sccs<N, S> {
impl<N: Idx, S: Idx + Ord> NumEdges for Sccs<N, S> {
fn num_edges(&self) -> usize {
self.scc_data.all_successors.len()
}
}

impl<'graph, N: Idx, S: Idx> GraphSuccessors<'graph> for Sccs<N, S> {
type Item = S;

type Iter = std::iter::Cloned<std::slice::Iter<'graph, S>>;
}

impl<N: Idx, S: Idx + Ord> WithSuccessors for Sccs<N, S> {
fn successors(&self, node: S) -> <Self as GraphSuccessors<'_>>::Iter {
impl<N: Idx, S: Idx + Ord> Successors for Sccs<N, S> {
fn successors(&self, node: S) -> impl Iterator<Item = Self::Node> {
self.successors(node).iter().cloned()
}
}
Expand Down Expand Up @@ -158,7 +150,7 @@ impl<S: Idx> SccData<S> {
}
}

struct SccsConstruction<'c, G: DirectedGraph + WithNumNodes + WithSuccessors, S: Idx> {
struct SccsConstruction<'c, G: DirectedGraph + Successors, S: Idx> {
graph: &'c G,

/// The state of each node; used during walk to record the stack
Expand Down Expand Up @@ -218,7 +210,7 @@ enum WalkReturn<S> {

impl<'c, G, S> SccsConstruction<'c, G, S>
where
G: DirectedGraph + WithNumNodes + WithSuccessors,
G: DirectedGraph + Successors,
S: Idx,
{
/// Identifies SCCs in the graph `G` and computes the resulting
Expand Down
Loading

0 comments on commit 5580ae9

Please sign in to comment.