diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 53ff67f60e37..b7ddd52e9ac1 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -386,6 +386,24 @@ pub fn dominates(&self, a: Node, b: Node) -> bool { } } } + + /// Returns true if `a` **strictly** dominates `b` + /// + /// # Panics + /// + /// Panics if `b` is unreachable + #[inline] + pub fn strictly_dominates(&self, a: Node, b: Node) -> bool { + match &self.kind { + Kind::Path => a.index() < b.index(), + Kind::General(g) => { + let a = g.time[a]; + let b = g.time[b]; + assert!(b.start != 0, "node {b:?} is not reachable"); + a.start < b.start && b.finish < a.finish + } + } + } } /// Describes the number of vertices discovered at the time when processing of a particular vertex diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 36752bba9f72..d5795e64089b 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1609,6 +1609,11 @@ pub fn dominates(&self, other: Location, dominators: &Dominators) -> dominators.dominates(self.block, other.block) } } + + #[inline] + pub fn strictly_dominates(&self, other: Location, dominators: &Dominators) -> bool { + self.block != other.block && dominators.strictly_dominates(self.block, other.block) + } } /// `DefLocation` represents the location of a definition - either an argument or an assignment