|
15 | 15 | #include "llvm/CodeGen/Passes.h"
|
16 | 16 | #include "BranchFolding.h"
|
17 | 17 | #include "llvm/ADT/STLExtras.h"
|
| 18 | +#include "llvm/ADT/ScopeExit.h" |
18 | 19 | #include "llvm/ADT/SmallSet.h"
|
19 | 20 | #include "llvm/ADT/Statistic.h"
|
20 | 21 | #include "llvm/CodeGen/LivePhysRegs.h"
|
@@ -550,16 +551,32 @@ static inline bool skipDebugInstructionsForward(
|
550 | 551 | return It == End;
|
551 | 552 | }
|
552 | 553 |
|
553 |
| -/// Decrement \p It until it points to a non-debug instruction or to \p Begin. |
| 554 | +/// Shrink the provided inclusive range by one instruction. |
| 555 | +/// If the range was one instruction (\p It == \p Begin), It is not modified, |
| 556 | +/// but \p Empty is set to true. |
| 557 | +static inline void shrinkInclusiveRange( |
| 558 | + MachineBasicBlock::iterator &Begin, |
| 559 | + MachineBasicBlock::iterator &It, |
| 560 | + bool &Empty) { |
| 561 | + if (It == Begin) |
| 562 | + Empty = true; |
| 563 | + else |
| 564 | + It--; |
| 565 | +} |
| 566 | + |
| 567 | +/// Decrement \p It until it points to a non-debug instruction or the range is |
| 568 | +/// empty. |
554 | 569 | /// @param It Iterator to decrement.
|
555 | 570 | /// @param Begin Iterator that points to beginning. Will be compared to It
|
556 |
| -/// @returns true if It == Begin, false otherwise. |
| 571 | +/// @param Empty Set to true if the resulting range is Empty |
| 572 | +/// @returns the value of Empty as a convenience. |
557 | 573 | static inline bool skipDebugInstructionsBackward(
|
| 574 | + MachineBasicBlock::iterator &Begin, |
558 | 575 | MachineBasicBlock::iterator &It,
|
559 |
| - MachineBasicBlock::iterator &Begin) { |
560 |
| - while (It != Begin && It->isDebugValue()) |
561 |
| - It--; |
562 |
| - return It == Begin; |
| 576 | + bool &Empty) { |
| 577 | + while (!Empty && It->isDebugValue()) |
| 578 | + shrinkInclusiveRange(Begin, It, Empty); |
| 579 | + return Empty; |
563 | 580 | }
|
564 | 581 |
|
565 | 582 | /// Count duplicated instructions and move the iterators to show where they
|
@@ -596,50 +613,67 @@ static void countDuplicatedInstructions(
|
596 | 613 | ++FIB;
|
597 | 614 | }
|
598 | 615 |
|
599 |
| - // Now, in preparation for counting duplicate instructions at the ends of the |
600 |
| - // blocks, move the end iterators up past any branch instructions. |
601 | 616 | // If both blocks are returning don't skip the branches, since they will
|
602 | 617 | // likely be both identical return instructions. In such cases the return
|
603 | 618 | // can be left unpredicated.
|
604 | 619 | // Check for already containing all of the block.
|
605 | 620 | if (TIB == TIE || FIB == FIE)
|
606 | 621 | return;
|
| 622 | + // Now, in preparation for counting duplicate instructions at the ends of the |
| 623 | + // blocks, move the end iterators up past any branch instructions. |
607 | 624 | --TIE;
|
608 | 625 | --FIE;
|
| 626 | + |
| 627 | + // After this point TIB and TIE define an inclusive range, which means that |
| 628 | + // TIB == TIE is true when there is one more instruction to consider, not at |
| 629 | + // the end. Because we may not be able to go before TIB, we need a flag to |
| 630 | + // indicate a completely empty range. |
| 631 | + bool TEmpty = false, FEmpty = false; |
| 632 | + |
| 633 | + // Upon exit TIE and FIE will both point at the last non-shared instruction. |
| 634 | + // They need to be moved forward to point past the last non-shared |
| 635 | + // instruction if the range they delimit is non-empty. |
| 636 | + auto IncrementEndIteratorsOnExit = make_scope_exit([&]() { |
| 637 | + if (!TEmpty) |
| 638 | + ++TIE; |
| 639 | + if (!FEmpty) |
| 640 | + ++FIE; |
| 641 | + }); |
| 642 | + |
609 | 643 | if (!TBB.succ_empty() || !FBB.succ_empty()) {
|
610 | 644 | if (SkipConditionalBranches) {
|
611 |
| - while (TIE != TIB && TIE->isBranch()) |
612 |
| - --TIE; |
613 |
| - while (FIE != FIB && FIE->isBranch()) |
614 |
| - --FIE; |
| 645 | + while (!TEmpty && TIE->isBranch()) |
| 646 | + shrinkInclusiveRange(TIB, TIE, TEmpty); |
| 647 | + while (!FEmpty && FIE->isBranch()) |
| 648 | + shrinkInclusiveRange(FIB, FIE, FEmpty); |
615 | 649 | } else {
|
616 |
| - while (TIE != TIB && TIE->isUnconditionalBranch()) |
617 |
| - --TIE; |
618 |
| - while (FIE != FIB && FIE->isUnconditionalBranch()) |
619 |
| - --FIE; |
| 650 | + while (!TEmpty && TIE->isUnconditionalBranch()) |
| 651 | + shrinkInclusiveRange(TIB, TIE, TEmpty); |
| 652 | + while (!FEmpty && FIE->isUnconditionalBranch()) |
| 653 | + shrinkInclusiveRange(FIB, FIE, FEmpty); |
620 | 654 | }
|
621 | 655 | }
|
622 | 656 |
|
623 | 657 | // If Dups1 includes all of a block, then don't count duplicate
|
624 | 658 | // instructions at the end of the blocks.
|
625 |
| - if (TIB == TIE || FIB == FIE) |
| 659 | + if (TEmpty || FEmpty) |
626 | 660 | return;
|
627 | 661 |
|
628 | 662 | // Count duplicate instructions at the ends of the blocks.
|
629 |
| - while (TIE != TIB && FIE != FIB) { |
| 663 | + while (!TEmpty && !FEmpty) { |
630 | 664 | // Skip dbg_value instructions. These do not count.
|
631 |
| - if (skipDebugInstructionsBackward(TIE, TIB)) |
| 665 | + if (skipDebugInstructionsBackward(TIB, TIE, TEmpty)) |
632 | 666 | break;
|
633 |
| - if (skipDebugInstructionsBackward(FIE, FIB)) |
| 667 | + if (skipDebugInstructionsBackward(FIB, FIE, FEmpty)) |
634 | 668 | break;
|
635 | 669 | if (!TIE->isIdenticalTo(*FIE))
|
636 | 670 | break;
|
637 | 671 | // If we are trying to make sure the conditional branches are the same, we
|
638 | 672 | // still don't want to count them.
|
639 | 673 | if (SkipConditionalBranches || !TIE->isBranch())
|
640 | 674 | ++Dups2;
|
641 |
| - --TIE; |
642 |
| - --FIE; |
| 675 | + shrinkInclusiveRange(TIB, TIE, TEmpty); |
| 676 | + shrinkInclusiveRange(FIB, FIE, FEmpty); |
643 | 677 | }
|
644 | 678 | }
|
645 | 679 |
|
|
0 commit comments