@@ -5,7 +5,7 @@ use std::path::PathBuf;
5
5
6
6
use rustc_data_structures:: work_queue:: WorkQueue ;
7
7
use rustc_hir:: def_id:: DefId ;
8
- use rustc_index:: { Idx , IndexVec } ;
8
+ use rustc_index:: IndexVec ;
9
9
use rustc_middle:: bug;
10
10
use rustc_middle:: mir:: { self , BasicBlock , create_dump_file, dump_enabled, traversal} ;
11
11
use rustc_middle:: ty:: TyCtxt ;
@@ -16,13 +16,12 @@ use {rustc_ast as ast, rustc_graphviz as dot};
16
16
17
17
use super :: fmt:: DebugWithContext ;
18
18
use 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,
21
21
} ;
22
22
use crate :: errors:: {
23
23
DuplicateValuesFor , PathMustEndInFilename , RequiresAnArgument , UnknownFormatter ,
24
24
} ;
25
- use crate :: framework:: BitSetExt ;
26
25
27
26
type EntrySets < ' tcx , A > = IndexVec < BasicBlock , <A as AnalysisDomain < ' tcx > >:: Domain > ;
28
27
82
81
entry_sets : IndexVec < BasicBlock , A :: Domain > ,
83
82
pass_name : Option < & ' static str > ,
84
83
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
- }
132
84
}
133
85
134
86
impl < ' mir , ' tcx , A , D > Engine < ' mir , ' tcx , A >
@@ -138,19 +90,7 @@ where
138
90
{
139
91
/// Creates a new `Engine` to solve a dataflow problem with an arbitrary transfer
140
92
/// 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 {
154
94
let mut entry_sets =
155
95
IndexVec :: from_fn_n ( |_| analysis. bottom_value ( body) , body. basic_blocks . len ( ) ) ;
156
96
analysis. initialize_start_block ( body, & mut entry_sets[ mir:: START_BLOCK ] ) ;
@@ -160,7 +100,7 @@ where
160
100
bug ! ( "`initialize_start_block` is not yet supported for backward dataflow analyses" ) ;
161
101
}
162
102
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 }
164
104
}
165
105
166
106
/// Adds an identifier to the graphviz output for this particular run of a dataflow analysis.
@@ -177,14 +117,7 @@ where
177
117
where
178
118
A :: Domain : DebugWithContext < A > ,
179
119
{
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 ;
188
121
189
122
let mut dirty_queue: WorkQueue < BasicBlock > = WorkQueue :: with_none ( body. basic_blocks . len ( ) ) ;
190
123
@@ -213,13 +146,8 @@ where
213
146
state. clone_from ( & entry_sets[ bb] ) ;
214
147
215
148
// 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) ;
223
151
224
152
A :: Direction :: join_state_into_successors_of (
225
153
& mut analysis,
0 commit comments