@@ -389,8 +389,6 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
389
389
390
390
noway_assert (!opts.MinOpts ());
391
391
392
- bool removeLoop = false ;
393
-
394
392
// If an unreachable block is a loop entry or bottom then the loop is unreachable.
395
393
// Special case: the block was the head of a loop - or pointing to a loop entry.
396
394
@@ -456,101 +454,37 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
456
454
// If `block` flows to the loop entry then the whole loop will become unreachable if it is the
457
455
// only non-loop predecessor.
458
456
459
- switch (block->bbJumpKind )
457
+ bool removeLoop = false ;
458
+ if (!loop.lpContains (block))
460
459
{
461
- case BBJ_NONE:
462
- if (block->bbNext == loop.lpEntry )
463
- {
464
- removeLoop = true ;
465
- }
466
- break ;
467
-
468
- case BBJ_COND:
469
- if ((block->bbNext == loop.lpEntry ) || (block->bbJumpDest == loop.lpEntry ))
470
- {
471
- removeLoop = true ;
472
- }
473
- break ;
474
-
475
- case BBJ_ALWAYS:
476
- if (block->bbJumpDest == loop.lpEntry )
460
+ for (BasicBlock* const succ : block->Succs ())
461
+ {
462
+ if (loop.lpEntry == succ)
477
463
{
478
464
removeLoop = true ;
465
+ break ;
479
466
}
480
- break ;
467
+ }
481
468
482
- case BBJ_SWITCH:
483
- for (BasicBlock* const bTarget : block->SwitchTargets ())
469
+ if (removeLoop)
470
+ {
471
+ // If the entry has any non-loop block that is not the known 'block' predecessor of entry
472
+ // (found above), then don't remove the loop.
473
+ for (BasicBlock* const predBlock : loop.lpEntry ->PredBlocks ())
484
474
{
485
- if (bTarget == loop. lpEntry )
475
+ if (!loop. lpContains (predBlock) && (predBlock != block) )
486
476
{
487
- removeLoop = true ;
477
+ removeLoop = false ;
488
478
break ;
489
479
}
490
480
}
491
- break ;
492
-
493
- default :
494
- break ;
481
+ }
495
482
}
496
483
497
484
if (removeLoop)
498
485
{
499
- // Check if the entry has other predecessors outside the loop.
500
- // TODO: Replace this when predecessors are available.
501
-
502
- for (BasicBlock* const auxBlock : Blocks ())
503
- {
504
- // Ignore blocks in the loop.
505
- if (loop.lpContains (auxBlock))
506
- {
507
- continue ;
508
- }
509
-
510
- switch (auxBlock->bbJumpKind )
511
- {
512
- case BBJ_NONE:
513
- if (auxBlock->bbNext == loop.lpEntry )
514
- {
515
- removeLoop = false ;
516
- }
517
- break ;
518
-
519
- case BBJ_COND:
520
- if ((auxBlock->bbNext == loop.lpEntry ) || (auxBlock->bbJumpDest == loop.lpEntry ))
521
- {
522
- removeLoop = false ;
523
- }
524
- break ;
525
-
526
- case BBJ_ALWAYS:
527
- if (auxBlock->bbJumpDest == loop.lpEntry )
528
- {
529
- removeLoop = false ;
530
- }
531
- break ;
532
-
533
- case BBJ_SWITCH:
534
- for (BasicBlock* const bTarget : auxBlock->SwitchTargets ())
535
- {
536
- if (bTarget == loop.lpEntry )
537
- {
538
- removeLoop = false ;
539
- break ;
540
- }
541
- }
542
- break ;
543
-
544
- default :
545
- break ;
546
- }
547
- }
548
-
549
- if (removeLoop)
550
- {
551
- reportBefore ();
552
- optMarkLoopRemoved (loopNum);
553
- }
486
+ reportBefore ();
487
+ optMarkLoopRemoved (loopNum);
554
488
}
555
489
else if (loop.lpHead == block)
556
490
{
0 commit comments