@@ -5,7 +5,7 @@ use std::path::PathBuf;
55
66use rustc_data_structures:: work_queue:: WorkQueue ;
77use rustc_hir:: def_id:: DefId ;
8- use rustc_index:: { Idx , IndexVec } ;
8+ use rustc_index:: IndexVec ;
99use rustc_middle:: bug;
1010use rustc_middle:: mir:: { self , BasicBlock , create_dump_file, dump_enabled, traversal} ;
1111use rustc_middle:: ty:: TyCtxt ;
@@ -16,13 +16,12 @@ use {rustc_ast as ast, rustc_graphviz as dot};
1616
1717use super :: fmt:: DebugWithContext ;
1818use super :: {
19- Analysis , AnalysisDomain , Direction , GenKill , GenKillAnalysis , GenKillSet , JoinSemiLattice ,
20- ResultsCursor , ResultsVisitor , graphviz , visit_results,
19+ Analysis , AnalysisDomain , Direction , JoinSemiLattice , ResultsCursor , ResultsVisitor , graphviz ,
20+ visit_results,
2121} ;
2222use crate :: errors:: {
2323 DuplicateValuesFor , PathMustEndInFilename , RequiresAnArgument , UnknownFormatter ,
2424} ;
25- use crate :: framework:: BitSetExt ;
2625
2726type EntrySets < ' tcx , A > = IndexVec < BasicBlock , <A as AnalysisDomain < ' tcx > >:: Domain > ;
2827
8281 entry_sets : IndexVec < BasicBlock , A :: Domain > ,
8382 pass_name : Option < & ' static str > ,
8483 analysis : A ,
85-
86- /// Cached, cumulative transfer functions for each block.
87- //
88- // FIXME(ecstaticmorse): This boxed `Fn` trait object is invoked inside a tight loop for
89- // gen/kill problems on cyclic CFGs. This is not ideal, but it doesn't seem to degrade
90- // performance in practice. I've tried a few ways to avoid this, but they have downsides. See
91- // the message for the commit that added this FIXME for more information.
92- apply_statement_trans_for_block : Option < Box < dyn Fn ( BasicBlock , & mut A :: Domain ) > > ,
93- }
94-
95- impl < ' mir , ' tcx , A , D , T > Engine < ' mir , ' tcx , A >
96- where
97- A : GenKillAnalysis < ' tcx , Idx = T , Domain = D > ,
98- D : Clone + JoinSemiLattice + GenKill < T > + BitSetExt < T > ,
99- T : Idx ,
100- {
101- /// Creates a new `Engine` to solve a gen-kill dataflow problem.
102- pub fn new_gen_kill ( tcx : TyCtxt < ' tcx > , body : & ' mir mir:: Body < ' tcx > , mut analysis : A ) -> Self {
103- // If there are no back-edges in the control-flow graph, we only ever need to apply the
104- // transfer function for each block exactly once (assuming that we process blocks in RPO).
105- //
106- // In this case, there's no need to compute the block transfer functions ahead of time.
107- if !body. basic_blocks . is_cfg_cyclic ( ) {
108- return Self :: new ( tcx, body, analysis, None ) ;
109- }
110-
111- // Otherwise, compute and store the cumulative transfer function for each block.
112-
113- let identity = GenKillSet :: identity ( analysis. domain_size ( body) ) ;
114- let mut trans_for_block = IndexVec :: from_elem ( identity, & body. basic_blocks ) ;
115-
116- for ( block, block_data) in body. basic_blocks . iter_enumerated ( ) {
117- let trans = & mut trans_for_block[ block] ;
118- A :: Direction :: gen_kill_statement_effects_in_block (
119- & mut analysis,
120- trans,
121- block,
122- block_data,
123- ) ;
124- }
125-
126- let apply_trans = Box :: new ( move |bb : BasicBlock , state : & mut A :: Domain | {
127- trans_for_block[ bb] . apply ( state) ;
128- } ) ;
129-
130- Self :: new ( tcx, body, analysis, Some ( apply_trans as Box < _ > ) )
131- }
13284}
13385
13486impl < ' mir , ' tcx , A , D > Engine < ' mir , ' tcx , A >
@@ -138,19 +90,7 @@ where
13890{
13991 /// Creates a new `Engine` to solve a dataflow problem with an arbitrary transfer
14092 /// function.
141- ///
142- /// Gen-kill problems should use `new_gen_kill`, which will coalesce transfer functions for
143- /// better performance.
144- pub fn new_generic ( tcx : TyCtxt < ' tcx > , body : & ' mir mir:: Body < ' tcx > , analysis : A ) -> Self {
145- Self :: new ( tcx, body, analysis, None )
146- }
147-
148- fn new (
149- tcx : TyCtxt < ' tcx > ,
150- body : & ' mir mir:: Body < ' tcx > ,
151- analysis : A ,
152- apply_statement_trans_for_block : Option < Box < dyn Fn ( BasicBlock , & mut A :: Domain ) > > ,
153- ) -> Self {
93+ pub ( crate ) fn new ( tcx : TyCtxt < ' tcx > , body : & ' mir mir:: Body < ' tcx > , analysis : A ) -> Self {
15494 let mut entry_sets =
15595 IndexVec :: from_fn_n ( |_| analysis. bottom_value ( body) , body. basic_blocks . len ( ) ) ;
15696 analysis. initialize_start_block ( body, & mut entry_sets[ mir:: START_BLOCK ] ) ;
@@ -160,7 +100,7 @@ where
160100 bug ! ( "`initialize_start_block` is not yet supported for backward dataflow analyses" ) ;
161101 }
162102
163- Engine { analysis, tcx, body, pass_name : None , entry_sets, apply_statement_trans_for_block }
103+ Engine { analysis, tcx, body, pass_name : None , entry_sets }
164104 }
165105
166106 /// Adds an identifier to the graphviz output for this particular run of a dataflow analysis.
@@ -177,14 +117,7 @@ where
177117 where
178118 A :: Domain : DebugWithContext < A > ,
179119 {
180- let Engine {
181- mut analysis,
182- body,
183- mut entry_sets,
184- tcx,
185- apply_statement_trans_for_block,
186- pass_name,
187- } = self ;
120+ let Engine { mut analysis, body, mut entry_sets, tcx, pass_name } = self ;
188121
189122 let mut dirty_queue: WorkQueue < BasicBlock > = WorkQueue :: with_none ( body. basic_blocks . len ( ) ) ;
190123
@@ -213,13 +146,8 @@ where
213146 state. clone_from ( & entry_sets[ bb] ) ;
214147
215148 // Apply the block transfer function, using the cached one if it exists.
216- let edges = A :: Direction :: apply_effects_in_block (
217- & mut analysis,
218- & mut state,
219- bb,
220- bb_data,
221- apply_statement_trans_for_block. as_deref ( ) ,
222- ) ;
149+ let edges =
150+ A :: Direction :: apply_effects_in_block ( & mut analysis, & mut state, bb, bb_data) ;
223151
224152 A :: Direction :: join_state_into_successors_of (
225153 & mut analysis,
0 commit comments