diff options
Diffstat (limited to 'compiler/rustc_middle/src/mir/mod.rs')
-rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 7054cede2..1e5a7401c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -736,6 +736,8 @@ impl SourceInfo { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] + #[orderable] #[debug_format = "_{}"] pub struct Local { const RETURN_PLACE = 0; @@ -973,7 +975,7 @@ pub enum LocalInfo<'tcx> { impl<'tcx> LocalDecl<'tcx> { pub fn local_info(&self) -> &LocalInfo<'tcx> { - &self.local_info.as_ref().assert_crate_local() + self.local_info.as_ref().assert_crate_local() } /// Returns `true` only if local is a binding that can itself be @@ -1171,6 +1173,8 @@ rustc_index::newtype_index! { /// [`CriticalCallEdges`]: ../../rustc_const_eval/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges /// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/ #[derive(HashStable)] + #[encodable] + #[orderable] #[debug_format = "bb{}"] pub struct BasicBlock { const START_BLOCK = 0; @@ -1305,6 +1309,7 @@ impl<'tcx> BasicBlockData<'tcx> { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] #[debug_format = "scope[{}]"] pub struct SourceScope { const OUTERMOST_SOURCE_SCOPE = 0; @@ -1533,6 +1538,8 @@ impl UserTypeProjection { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] + #[orderable] #[debug_format = "promoted[{}]"] pub struct Promoted {} } @@ -1611,14 +1618,29 @@ impl Location { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum DefLocation { Argument, - Body(Location), + Assignment(Location), + CallReturn { call: BasicBlock, target: Option<BasicBlock> }, } impl DefLocation { pub fn dominates(self, location: Location, dominators: &Dominators<BasicBlock>) -> bool { match self { DefLocation::Argument => true, - DefLocation::Body(def) => def.successor_within_block().dominates(location, dominators), + DefLocation::Assignment(def) => { + def.successor_within_block().dominates(location, dominators) + } + DefLocation::CallReturn { target: None, .. } => false, + DefLocation::CallReturn { call, target: Some(target) } => { + // The definition occurs on the call -> target edge. The definition dominates a use + // if and only if the edge is on all paths from the entry to the use. + // + // Note that a call terminator has only one edge that can reach the target, so when + // the call strongly dominates the target, all paths from the entry to the target + // go through the call -> target edge. + call != target + && dominators.dominates(call, target) + && dominators.dominates(target, location.block) + } } } } |