@@ -191,26 +191,26 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
191
191
192
192
/// Recursion entry point to find threading opportunities.
193
193
#[ instrument( level = "trace" , skip( self ) ) ]
194
- fn start_from_switch ( & mut self , bb : BasicBlock ) -> Option < ! > {
194
+ fn start_from_switch ( & mut self , bb : BasicBlock ) {
195
195
let bbdata = & self . body [ bb] ;
196
196
if bbdata. is_cleanup || self . loop_headers . contains ( bb) {
197
- return None ;
197
+ return ;
198
198
}
199
- let ( discr, targets) = bbdata. terminator ( ) . kind . as_switch ( ) ? ;
200
- let discr = discr. place ( ) ? ;
199
+ let Some ( ( discr, targets) ) = bbdata. terminator ( ) . kind . as_switch ( ) else { return } ;
200
+ let Some ( discr) = discr. place ( ) else { return } ;
201
201
debug ! ( ?discr, ?bb) ;
202
202
203
203
let discr_ty = discr. ty ( self . body , self . tcx ) . ty ;
204
- let discr_layout = self . ecx . layout_of ( discr_ty) . ok ( ) ? ;
204
+ let Ok ( discr_layout) = self . ecx . layout_of ( discr_ty) else { return } ;
205
205
206
- let discr = self . map . find ( discr. as_ref ( ) ) ? ;
206
+ let Some ( discr) = self . map . find ( discr. as_ref ( ) ) else { return } ;
207
207
debug ! ( ?discr) ;
208
208
209
209
let cost = CostChecker :: new ( self . tcx , self . param_env , None , self . body ) ;
210
210
let mut state = State :: new_reachable ( ) ;
211
211
212
212
let conds = if let Some ( ( value, then, else_) ) = targets. as_static_if ( ) {
213
- let value = ScalarInt :: try_from_uint ( value, discr_layout. size ) ? ;
213
+ let Some ( value) = ScalarInt :: try_from_uint ( value, discr_layout. size ) else { return } ;
214
214
self . arena . alloc_from_iter ( [
215
215
Condition { value, polarity : Polarity :: Eq , target : then } ,
216
216
Condition { value, polarity : Polarity :: Ne , target : else_ } ,
@@ -225,7 +225,6 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
225
225
state. insert_value_idx ( discr, conds, self . map ) ;
226
226
227
227
self . find_opportunity ( bb, state, cost, 0 ) ;
228
- None
229
228
}
230
229
231
230
/// Recursively walk statements backwards from this bb's terminator to find threading
@@ -364,18 +363,17 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
364
363
lhs : PlaceIndex ,
365
364
rhs : ImmTy < ' tcx > ,
366
365
state : & mut State < ConditionSet < ' a > > ,
367
- ) -> Option < ! > {
366
+ ) {
368
367
let register_opportunity = |c : Condition | {
369
368
debug ! ( ?bb, ?c. target, "register" ) ;
370
369
self . opportunities . push ( ThreadingOpportunity { chain : vec ! [ bb] , target : c. target } )
371
370
} ;
372
371
373
- let conditions = state. try_get_idx ( lhs, self . map ) ?;
374
- if let Immediate :: Scalar ( Scalar :: Int ( int) ) = * rhs {
372
+ if let Some ( conditions) = state. try_get_idx ( lhs, self . map )
373
+ && let Immediate :: Scalar ( Scalar :: Int ( int) ) = * rhs
374
+ {
375
375
conditions. iter_matches ( int) . for_each ( register_opportunity) ;
376
376
}
377
-
378
- None
379
377
}
380
378
381
379
/// If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
@@ -428,22 +426,23 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
428
426
lhs : PlaceIndex ,
429
427
rhs : & Operand < ' tcx > ,
430
428
state : & mut State < ConditionSet < ' a > > ,
431
- ) -> Option < ! > {
429
+ ) {
432
430
match rhs {
433
431
// If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
434
432
Operand :: Constant ( constant) => {
435
- let constant =
436
- self . ecx . eval_mir_constant ( & constant. const_ , constant. span , None ) . ok ( ) ?;
433
+ let Ok ( constant) =
434
+ self . ecx . eval_mir_constant ( & constant. const_ , constant. span , None )
435
+ else {
436
+ return ;
437
+ } ;
437
438
self . process_constant ( bb, lhs, constant, state) ;
438
439
}
439
440
// Transfer the conditions on the copied rhs.
440
441
Operand :: Move ( rhs) | Operand :: Copy ( rhs) => {
441
- let rhs = self . map . find ( rhs. as_ref ( ) ) ? ;
442
+ let Some ( rhs) = self . map . find ( rhs. as_ref ( ) ) else { return } ;
442
443
state. insert_place_idx ( rhs, lhs, self . map ) ;
443
444
}
444
445
}
445
-
446
- None
447
446
}
448
447
449
448
#[ instrument( level = "trace" , skip( self ) ) ]
@@ -453,32 +452,34 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
453
452
lhs_place : & Place < ' tcx > ,
454
453
rhs : & Rvalue < ' tcx > ,
455
454
state : & mut State < ConditionSet < ' a > > ,
456
- ) -> Option < ! > {
457
- let lhs = self . map . find ( lhs_place. as_ref ( ) ) ? ;
455
+ ) {
456
+ let Some ( lhs) = self . map . find ( lhs_place. as_ref ( ) ) else { return } ;
458
457
match rhs {
459
- Rvalue :: Use ( operand) => self . process_operand ( bb, lhs, operand, state) ? ,
458
+ Rvalue :: Use ( operand) => self . process_operand ( bb, lhs, operand, state) ,
460
459
// Transfer the conditions on the copy rhs.
461
- Rvalue :: CopyForDeref ( rhs) => {
462
- self . process_operand ( bb, lhs, & Operand :: Copy ( * rhs) , state) ?
463
- }
460
+ Rvalue :: CopyForDeref ( rhs) => self . process_operand ( bb, lhs, & Operand :: Copy ( * rhs) , state) ,
464
461
Rvalue :: Discriminant ( rhs) => {
465
- let rhs = self . map . find_discr ( rhs. as_ref ( ) ) ? ;
462
+ let Some ( rhs) = self . map . find_discr ( rhs. as_ref ( ) ) else { return } ;
466
463
state. insert_place_idx ( rhs, lhs, self . map ) ;
467
464
}
468
465
// If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
469
466
Rvalue :: Aggregate ( box ref kind, ref operands) => {
470
467
let agg_ty = lhs_place. ty ( self . body , self . tcx ) . ty ;
471
468
let lhs = match kind {
472
469
// Do not support unions.
473
- AggregateKind :: Adt ( .., Some ( _) ) => return None ,
470
+ AggregateKind :: Adt ( .., Some ( _) ) => return ,
474
471
AggregateKind :: Adt ( _, variant_index, ..) if agg_ty. is_enum ( ) => {
475
472
if let Some ( discr_target) = self . map . apply ( lhs, TrackElem :: Discriminant )
476
473
&& let Ok ( discr_value) =
477
474
self . ecx . discriminant_for_variant ( agg_ty, * variant_index)
478
475
{
479
476
self . process_immediate ( bb, discr_target, discr_value, state) ;
480
477
}
481
- self . map . apply ( lhs, TrackElem :: Variant ( * variant_index) ) ?
478
+ if let Some ( idx) = self . map . apply ( lhs, TrackElem :: Variant ( * variant_index) ) {
479
+ idx
480
+ } else {
481
+ return ;
482
+ }
482
483
}
483
484
_ => lhs,
484
485
} ;
@@ -490,8 +491,8 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
490
491
}
491
492
// Transfer the conditions on the copy rhs, after inversing polarity.
492
493
Rvalue :: UnaryOp ( UnOp :: Not , Operand :: Move ( place) | Operand :: Copy ( place) ) => {
493
- let conditions = state. try_get_idx ( lhs, self . map ) ? ;
494
- let place = self . map . find ( place. as_ref ( ) ) ? ;
494
+ let Some ( conditions) = state. try_get_idx ( lhs, self . map ) else { return } ;
495
+ let Some ( place) = self . map . find ( place. as_ref ( ) ) else { return } ;
495
496
let conds = conditions. map ( self . arena , Condition :: inv) ;
496
497
state. insert_value_idx ( place, conds, self . map ) ;
497
498
}
@@ -502,21 +503,25 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
502
503
box ( Operand :: Move ( place) | Operand :: Copy ( place) , Operand :: Constant ( value) )
503
504
| box ( Operand :: Constant ( value) , Operand :: Move ( place) | Operand :: Copy ( place) ) ,
504
505
) => {
505
- let conditions = state. try_get_idx ( lhs, self . map ) ? ;
506
- let place = self . map . find ( place. as_ref ( ) ) ? ;
506
+ let Some ( conditions) = state. try_get_idx ( lhs, self . map ) else { return } ;
507
+ let Some ( place) = self . map . find ( place. as_ref ( ) ) else { return } ;
507
508
let equals = match op {
508
509
BinOp :: Eq => ScalarInt :: TRUE ,
509
510
BinOp :: Ne => ScalarInt :: FALSE ,
510
- _ => return None ,
511
+ _ => return ,
511
512
} ;
512
513
if value. const_ . ty ( ) . is_floating_point ( ) {
513
514
// Floating point equality does not follow bit-patterns.
514
515
// -0.0 and NaN both have special rules for equality,
515
516
// and therefore we cannot use integer comparisons for them.
516
517
// Avoid handling them, though this could be extended in the future.
517
- return None ;
518
+ return ;
518
519
}
519
- let value = value. const_ . normalize ( self . tcx , self . param_env ) . try_to_scalar_int ( ) ?;
520
+ let Some ( value) =
521
+ value. const_ . normalize ( self . tcx , self . param_env ) . try_to_scalar_int ( )
522
+ else {
523
+ return ;
524
+ } ;
520
525
let conds = conditions. map ( self . arena , |c| Condition {
521
526
value,
522
527
polarity : if c. matches ( equals) { Polarity :: Eq } else { Polarity :: Ne } ,
@@ -527,8 +532,6 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
527
532
528
533
_ => { }
529
534
}
530
-
531
- None
532
535
}
533
536
534
537
#[ instrument( level = "trace" , skip( self ) ) ]
@@ -537,7 +540,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
537
540
bb : BasicBlock ,
538
541
stmt : & Statement < ' tcx > ,
539
542
state : & mut State < ConditionSet < ' a > > ,
540
- ) -> Option < ! > {
543
+ ) {
541
544
let register_opportunity = |c : Condition | {
542
545
debug ! ( ?bb, ?c. target, "register" ) ;
543
546
self . opportunities . push ( ThreadingOpportunity { chain : vec ! [ bb] , target : c. target } )
@@ -550,12 +553,12 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
550
553
// If we expect `discriminant(place) ?= A`,
551
554
// we have an opportunity if `variant_index ?= A`.
552
555
StatementKind :: SetDiscriminant { box place, variant_index } => {
553
- let discr_target = self . map . find_discr ( place. as_ref ( ) ) ? ;
556
+ let Some ( discr_target) = self . map . find_discr ( place. as_ref ( ) ) else { return } ;
554
557
let enum_ty = place. ty ( self . body , self . tcx ) . ty ;
555
558
// `SetDiscriminant` may be a no-op if the assigned variant is the untagged variant
556
559
// of a niche encoding. If we cannot ensure that we write to the discriminant, do
557
560
// nothing.
558
- let enum_layout = self . ecx . layout_of ( enum_ty) . ok ( ) ? ;
561
+ let Ok ( enum_layout) = self . ecx . layout_of ( enum_ty) else { return } ;
559
562
let writes_discriminant = match enum_layout. variants {
560
563
Variants :: Single { index } => {
561
564
assert_eq ! ( index, * variant_index) ;
@@ -568,24 +571,25 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
568
571
} => * variant_index != untagged_variant,
569
572
} ;
570
573
if writes_discriminant {
571
- let discr = self . ecx . discriminant_for_variant ( enum_ty, * variant_index) . ok ( ) ?;
572
- self . process_immediate ( bb, discr_target, discr, state) ?;
574
+ let Ok ( discr) = self . ecx . discriminant_for_variant ( enum_ty, * variant_index)
575
+ else {
576
+ return ;
577
+ } ;
578
+ self . process_immediate ( bb, discr_target, discr, state) ;
573
579
}
574
580
}
575
581
// If we expect `lhs ?= true`, we have an opportunity if we assume `lhs == true`.
576
582
StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: Assume (
577
583
Operand :: Copy ( place) | Operand :: Move ( place) ,
578
584
) ) => {
579
- let conditions = state. try_get ( place. as_ref ( ) , self . map ) ? ;
585
+ let Some ( conditions) = state. try_get ( place. as_ref ( ) , self . map ) else { return } ;
580
586
conditions. iter_matches ( ScalarInt :: TRUE ) . for_each ( register_opportunity) ;
581
587
}
582
588
StatementKind :: Assign ( box ( lhs_place, rhs) ) => {
583
- self . process_assign ( bb, lhs_place, rhs, state) ? ;
589
+ self . process_assign ( bb, lhs_place, rhs, state) ;
584
590
}
585
591
_ => { }
586
592
}
587
-
588
- None
589
593
}
590
594
591
595
#[ instrument( level = "trace" , skip( self , state, cost) ) ]
@@ -638,17 +642,17 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
638
642
targets : & SwitchTargets ,
639
643
target_bb : BasicBlock ,
640
644
state : & mut State < ConditionSet < ' a > > ,
641
- ) -> Option < ! > {
645
+ ) {
642
646
debug_assert_ne ! ( target_bb, START_BLOCK ) ;
643
647
debug_assert_eq ! ( self . body. basic_blocks. predecessors( ) [ target_bb] . len( ) , 1 ) ;
644
648
645
- let discr = discr. place ( ) ? ;
649
+ let Some ( discr) = discr. place ( ) else { return } ;
646
650
let discr_ty = discr. ty ( self . body , self . tcx ) . ty ;
647
- let discr_layout = self . ecx . layout_of ( discr_ty) . ok ( ) ? ;
648
- let conditions = state. try_get ( discr. as_ref ( ) , self . map ) ? ;
651
+ let Ok ( discr_layout) = self . ecx . layout_of ( discr_ty) else { return } ;
652
+ let Some ( conditions) = state. try_get ( discr. as_ref ( ) , self . map ) else { return } ;
649
653
650
654
if let Some ( ( value, _) ) = targets. iter ( ) . find ( |& ( _, target) | target == target_bb) {
651
- let value = ScalarInt :: try_from_uint ( value, discr_layout. size ) ? ;
655
+ let Some ( value) = ScalarInt :: try_from_uint ( value, discr_layout. size ) else { return } ;
652
656
debug_assert_eq ! ( targets. iter( ) . filter( |& ( _, target) | target == target_bb) . count( ) , 1 ) ;
653
657
654
658
// We are inside `target_bb`. Since we have a single predecessor, we know we passed
@@ -662,7 +666,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
662
666
} else if let Some ( ( value, _, else_bb) ) = targets. as_static_if ( )
663
667
&& target_bb == else_bb
664
668
{
665
- let value = ScalarInt :: try_from_uint ( value, discr_layout. size ) ? ;
669
+ let Some ( value) = ScalarInt :: try_from_uint ( value, discr_layout. size ) else { return } ;
666
670
667
671
// We only know that `discr != value`. That's much weaker information than
668
672
// the equality we had in the previous arm. All we can conclude is that
@@ -675,8 +679,6 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
675
679
}
676
680
}
677
681
}
678
-
679
- None
680
682
}
681
683
}
682
684
0 commit comments