From fbc3cc18bee7fb6dfd39e11521783f00506ca06b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sun, 8 May 2022 00:00:00 +0000 Subject: [PATCH] Avoid constructing switch sources unless necessary Switch sources are used by backward analysis with a custom switch int edge effects, but are otherwise unnecessarily computed. Delay the computation until we know that switch sources are indeed required and avoid the computation otherwise. --- compiler/rustc_middle/src/mir/mod.rs | 2 ++ compiler/rustc_mir_dataflow/src/framework/direction.rs | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 682f3734d309..4d26840fd624 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -580,6 +580,8 @@ impl<'tcx> Body<'tcx> { self.predecessor_cache.compute(&self.basic_blocks) } + /// `body.switch_sources()[target][switch]` returns a list of switch values + /// that lead to a `target` block from a `switch` block. #[inline] pub fn switch_sources(&self) -> &SwitchSources { self.switch_source_cache.compute(&self.basic_blocks) diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 93118dfeb773..327002219db6 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -269,9 +269,9 @@ impl Direction for Backward { mir::TerminatorKind::SwitchInt { targets: _, ref discr, switch_ty: _ } => { let mut applier = BackwardSwitchIntEdgeEffectsApplier { + body, pred, exit_state, - values: &body.switch_sources()[bb][pred], bb, propagate: &mut propagate, effects_applied: false, @@ -305,9 +305,9 @@ impl Direction for Backward { } struct BackwardSwitchIntEdgeEffectsApplier<'a, D, F> { + body: &'a mir::Body<'a>, pred: BasicBlock, exit_state: &'a mut D, - values: &'a [Option], bb: BasicBlock, propagate: &'a mut F, @@ -322,7 +322,8 @@ where fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) { assert!(!self.effects_applied); - let targets = self.values.iter().map(|&value| SwitchIntTarget { value, target: self.bb }); + let values = &self.body.switch_sources()[self.bb][self.pred]; + let targets = values.iter().map(|&value| SwitchIntTarget { value, target: self.bb }); let mut tmp = None; for target in targets {