@@ -4,7 +4,8 @@ use std::ops::RangeInclusive;
4
4
5
5
use super :: visitor:: { ResultsVisitable , ResultsVisitor } ;
6
6
use super :: {
7
- Analysis , CallReturnPlaces , Effect , EffectIndex , GenKillAnalysis , GenKillSet , SwitchIntTarget ,
7
+ Analysis , AnalysisDomain , CallReturnPlaces , Effect , EffectIndex , GenKillAnalysis , GenKillSet ,
8
+ SwitchIntTarget , WithJoinCtxt ,
8
9
} ;
9
10
10
11
pub trait Direction {
@@ -55,9 +56,9 @@ pub trait Direction {
55
56
body : & mir:: Body < ' tcx > ,
56
57
exit_state : & mut A :: Domain ,
57
58
block : ( BasicBlock , & ' _ mir:: BasicBlockData < ' tcx > ) ,
58
- propagate : impl FnMut ( BasicBlock , & A :: Domain ) ,
59
+ propagate : impl FnMut ( & A :: JoinCtxt , BasicBlock , & A :: Domain ) ,
59
60
) where
60
- A : Analysis < ' tcx > ;
61
+ A : Analysis < ' tcx > + WithJoinCtxt < ' tcx > ;
61
62
}
62
63
63
64
/// Dataflow that runs from the exit of a block (the terminator), to its entry (the first statement).
@@ -221,9 +222,9 @@ impl Direction for Backward {
221
222
body : & mir:: Body < ' tcx > ,
222
223
exit_state : & mut A :: Domain ,
223
224
( bb, _bb_data) : ( BasicBlock , & ' _ mir:: BasicBlockData < ' tcx > ) ,
224
- mut propagate : impl FnMut ( BasicBlock , & A :: Domain ) ,
225
+ mut propagate : impl FnMut ( & A :: JoinCtxt , BasicBlock , & A :: Domain ) ,
225
226
) where
226
- A : Analysis < ' tcx > ,
227
+ A : Analysis < ' tcx > + WithJoinCtxt < ' tcx > ,
227
228
{
228
229
for pred in body. basic_blocks . predecessors ( ) [ bb] . iter ( ) . copied ( ) {
229
230
match body[ pred] . terminator ( ) . kind {
@@ -237,7 +238,7 @@ impl Direction for Backward {
237
238
pred,
238
239
CallReturnPlaces :: Call ( destination) ,
239
240
) ;
240
- propagate ( pred, & tmp) ;
241
+ propagate ( analysis . join_ctxt ( ) , pred, & tmp) ;
241
242
}
242
243
243
244
mir:: TerminatorKind :: InlineAsm {
@@ -249,13 +250,13 @@ impl Direction for Backward {
249
250
pred,
250
251
CallReturnPlaces :: InlineAsm ( operands) ,
251
252
) ;
252
- propagate ( pred, & tmp) ;
253
+ propagate ( analysis . join_ctxt ( ) , pred, & tmp) ;
253
254
}
254
255
255
256
mir:: TerminatorKind :: Yield { resume, resume_arg, .. } if resume == bb => {
256
257
let mut tmp = exit_state. clone ( ) ;
257
258
analysis. apply_yield_resume_effect ( & mut tmp, resume, resume_arg) ;
258
- propagate ( pred, & tmp) ;
259
+ propagate ( analysis . join_ctxt ( ) , pred, & tmp) ;
259
260
}
260
261
261
262
mir:: TerminatorKind :: SwitchInt { targets : _, ref discr } => {
@@ -271,11 +272,11 @@ impl Direction for Backward {
271
272
analysis. apply_switch_int_edge_effects ( pred, discr, & mut applier) ;
272
273
273
274
if !applier. effects_applied {
274
- propagate ( pred, exit_state)
275
+ propagate ( analysis . join_ctxt ( ) , pred, exit_state)
275
276
}
276
277
}
277
278
278
- _ => propagate ( pred, exit_state) ,
279
+ _ => propagate ( analysis . join_ctxt ( ) , pred, exit_state) ,
279
280
}
280
281
}
281
282
}
@@ -290,12 +291,17 @@ struct BackwardSwitchIntEdgeEffectsApplier<'a, 'tcx, D, F> {
290
291
effects_applied : bool ,
291
292
}
292
293
293
- impl < D , F > super :: SwitchIntEdgeEffects < D > for BackwardSwitchIntEdgeEffectsApplier < ' _ , ' _ , D , F >
294
+ impl < ' tcx , A , F > super :: SwitchIntEdgeEffects < ' tcx , A >
295
+ for BackwardSwitchIntEdgeEffectsApplier < ' _ , ' _ , A :: Domain , F >
294
296
where
295
- D : Clone ,
296
- F : FnMut ( BasicBlock , & D ) ,
297
+ A : AnalysisDomain < ' tcx > ,
298
+ F : FnMut ( & A :: JoinCtxt , BasicBlock , & A :: Domain ) ,
297
299
{
298
- fn apply ( & mut self , mut apply_edge_effect : impl FnMut ( & mut D , SwitchIntTarget ) ) {
300
+ fn apply (
301
+ & mut self ,
302
+ ctxt : & A :: JoinCtxt ,
303
+ mut apply_edge_effect : impl FnMut ( & mut A :: Domain , SwitchIntTarget ) ,
304
+ ) {
299
305
assert ! ( !self . effects_applied) ;
300
306
301
307
let values = & self . body . basic_blocks . switch_sources ( ) [ & ( self . bb , self . pred ) ] ;
@@ -305,7 +311,7 @@ where
305
311
for target in targets {
306
312
let tmp = opt_clone_from_or_clone ( & mut tmp, self . exit_state ) ;
307
313
apply_edge_effect ( tmp, target) ;
308
- ( self . propagate ) ( self . pred , tmp) ;
314
+ ( self . propagate ) ( ctxt , self . pred , tmp) ;
309
315
}
310
316
311
317
self . effects_applied = true ;
@@ -468,43 +474,43 @@ impl Direction for Forward {
468
474
_body : & mir:: Body < ' tcx > ,
469
475
exit_state : & mut A :: Domain ,
470
476
( bb, bb_data) : ( BasicBlock , & ' _ mir:: BasicBlockData < ' tcx > ) ,
471
- mut propagate : impl FnMut ( BasicBlock , & A :: Domain ) ,
477
+ mut propagate : impl FnMut ( & A :: JoinCtxt , BasicBlock , & A :: Domain ) ,
472
478
) where
473
- A : Analysis < ' tcx > ,
479
+ A : Analysis < ' tcx > + WithJoinCtxt < ' tcx > ,
474
480
{
475
481
use mir:: TerminatorKind :: * ;
476
482
match bb_data. terminator ( ) . kind {
477
483
Return | Resume | Terminate | GeneratorDrop | Unreachable => { }
478
484
479
- Goto { target } => propagate ( target, exit_state) ,
485
+ Goto { target } => propagate ( analysis . join_ctxt ( ) , target, exit_state) ,
480
486
481
487
Assert { target, unwind, expected : _, msg : _, cond : _ }
482
488
| Drop { target, unwind, place : _, replace : _ }
483
489
| FalseUnwind { real_target : target, unwind } => {
484
490
if let UnwindAction :: Cleanup ( unwind) = unwind {
485
- propagate ( unwind, exit_state) ;
491
+ propagate ( analysis . join_ctxt ( ) , unwind, exit_state) ;
486
492
}
487
493
488
- propagate ( target, exit_state) ;
494
+ propagate ( analysis . join_ctxt ( ) , target, exit_state) ;
489
495
}
490
496
491
497
FalseEdge { real_target, imaginary_target } => {
492
- propagate ( real_target, exit_state) ;
493
- propagate ( imaginary_target, exit_state) ;
498
+ propagate ( analysis . join_ctxt ( ) , real_target, exit_state) ;
499
+ propagate ( analysis . join_ctxt ( ) , imaginary_target, exit_state) ;
494
500
}
495
501
496
502
Yield { resume : target, drop, resume_arg, value : _ } => {
497
503
if let Some ( drop) = drop {
498
- propagate ( drop, exit_state) ;
504
+ propagate ( analysis . join_ctxt ( ) , drop, exit_state) ;
499
505
}
500
506
501
507
analysis. apply_yield_resume_effect ( exit_state, target, resume_arg) ;
502
- propagate ( target, exit_state) ;
508
+ propagate ( analysis . join_ctxt ( ) , target, exit_state) ;
503
509
}
504
510
505
511
Call { unwind, destination, target, func : _, args : _, call_source : _, fn_span : _ } => {
506
512
if let UnwindAction :: Cleanup ( unwind) = unwind {
507
- propagate ( unwind, exit_state) ;
513
+ propagate ( analysis . join_ctxt ( ) , unwind, exit_state) ;
508
514
}
509
515
510
516
if let Some ( target) = target {
@@ -515,7 +521,7 @@ impl Direction for Forward {
515
521
bb,
516
522
CallReturnPlaces :: Call ( destination) ,
517
523
) ;
518
- propagate ( target, exit_state) ;
524
+ propagate ( analysis . join_ctxt ( ) , target, exit_state) ;
519
525
}
520
526
}
521
527
@@ -528,7 +534,7 @@ impl Direction for Forward {
528
534
unwind,
529
535
} => {
530
536
if let UnwindAction :: Cleanup ( unwind) = unwind {
531
- propagate ( unwind, exit_state) ;
537
+ propagate ( analysis . join_ctxt ( ) , unwind, exit_state) ;
532
538
}
533
539
534
540
if let Some ( target) = destination {
@@ -539,7 +545,7 @@ impl Direction for Forward {
539
545
bb,
540
546
CallReturnPlaces :: InlineAsm ( operands) ,
541
547
) ;
542
- propagate ( target, exit_state) ;
548
+ propagate ( analysis . join_ctxt ( ) , target, exit_state) ;
543
549
}
544
550
}
545
551
@@ -562,7 +568,7 @@ impl Direction for Forward {
562
568
563
569
if !effects_applied {
564
570
for target in targets. all_targets ( ) {
565
- propagate ( * target, exit_state) ;
571
+ propagate ( analysis . join_ctxt ( ) , * target, exit_state) ;
566
572
}
567
573
}
568
574
}
@@ -578,26 +584,31 @@ struct ForwardSwitchIntEdgeEffectsApplier<'a, D, F> {
578
584
effects_applied : bool ,
579
585
}
580
586
581
- impl < D , F > super :: SwitchIntEdgeEffects < D > for ForwardSwitchIntEdgeEffectsApplier < ' _ , D , F >
587
+ impl < ' tcx , A , F > super :: SwitchIntEdgeEffects < ' tcx , A >
588
+ for ForwardSwitchIntEdgeEffectsApplier < ' _ , A :: Domain , F >
582
589
where
583
- D : Clone ,
584
- F : FnMut ( BasicBlock , & D ) ,
590
+ A : AnalysisDomain < ' tcx > ,
591
+ F : FnMut ( & A :: JoinCtxt , BasicBlock , & A :: Domain ) ,
585
592
{
586
- fn apply ( & mut self , mut apply_edge_effect : impl FnMut ( & mut D , SwitchIntTarget ) ) {
593
+ fn apply (
594
+ & mut self ,
595
+ ctxt : & A :: JoinCtxt ,
596
+ mut apply_edge_effect : impl FnMut ( & mut A :: Domain , SwitchIntTarget ) ,
597
+ ) {
587
598
assert ! ( !self . effects_applied) ;
588
599
589
600
let mut tmp = None ;
590
601
for ( value, target) in self . targets . iter ( ) {
591
602
let tmp = opt_clone_from_or_clone ( & mut tmp, self . exit_state ) ;
592
603
apply_edge_effect ( tmp, SwitchIntTarget { value : Some ( value) , target } ) ;
593
- ( self . propagate ) ( target, tmp) ;
604
+ ( self . propagate ) ( ctxt , target, tmp) ;
594
605
}
595
606
596
607
// Once we get to the final, "otherwise" branch, there is no need to preserve `exit_state`,
597
608
// so pass it directly to `apply_edge_effect` to save a clone of the dataflow state.
598
609
let otherwise = self . targets . otherwise ( ) ;
599
610
apply_edge_effect ( self . exit_state , SwitchIntTarget { value : None , target : otherwise } ) ;
600
- ( self . propagate ) ( otherwise, self . exit_state ) ;
611
+ ( self . propagate ) ( ctxt , otherwise, self . exit_state ) ;
601
612
602
613
self . effects_applied = true ;
603
614
}
0 commit comments