Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 1eee0ec

Browse files
author
Kyle Butt
committed
IfConversion: Handle inclusive ranges more carefully.
This may affect calculations for thresholds, but is not a significant change in behavior. The problem was that an inclusive range must have an additonal flag to showr that it is empty, because otherwise begin == end implies that the range has one element, and it may not be possible to move past on either side. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279166 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f20ce37 commit 1eee0ec

File tree

1 file changed

+56
-22
lines changed

1 file changed

+56
-22
lines changed

lib/CodeGen/IfConversion.cpp

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "llvm/CodeGen/Passes.h"
1616
#include "BranchFolding.h"
1717
#include "llvm/ADT/STLExtras.h"
18+
#include "llvm/ADT/ScopeExit.h"
1819
#include "llvm/ADT/SmallSet.h"
1920
#include "llvm/ADT/Statistic.h"
2021
#include "llvm/CodeGen/LivePhysRegs.h"
@@ -550,16 +551,32 @@ static inline bool skipDebugInstructionsForward(
550551
return It == End;
551552
}
552553

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.
554569
/// @param It Iterator to decrement.
555570
/// @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.
557573
static inline bool skipDebugInstructionsBackward(
574+
MachineBasicBlock::iterator &Begin,
558575
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;
563580
}
564581

565582
/// Count duplicated instructions and move the iterators to show where they
@@ -596,50 +613,67 @@ static void countDuplicatedInstructions(
596613
++FIB;
597614
}
598615

599-
// Now, in preparation for counting duplicate instructions at the ends of the
600-
// blocks, move the end iterators up past any branch instructions.
601616
// If both blocks are returning don't skip the branches, since they will
602617
// likely be both identical return instructions. In such cases the return
603618
// can be left unpredicated.
604619
// Check for already containing all of the block.
605620
if (TIB == TIE || FIB == FIE)
606621
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.
607624
--TIE;
608625
--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+
609643
if (!TBB.succ_empty() || !FBB.succ_empty()) {
610644
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);
615649
} 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);
620654
}
621655
}
622656

623657
// If Dups1 includes all of a block, then don't count duplicate
624658
// instructions at the end of the blocks.
625-
if (TIB == TIE || FIB == FIE)
659+
if (TEmpty || FEmpty)
626660
return;
627661

628662
// Count duplicate instructions at the ends of the blocks.
629-
while (TIE != TIB && FIE != FIB) {
663+
while (!TEmpty && !FEmpty) {
630664
// Skip dbg_value instructions. These do not count.
631-
if (skipDebugInstructionsBackward(TIE, TIB))
665+
if (skipDebugInstructionsBackward(TIB, TIE, TEmpty))
632666
break;
633-
if (skipDebugInstructionsBackward(FIE, FIB))
667+
if (skipDebugInstructionsBackward(FIB, FIE, FEmpty))
634668
break;
635669
if (!TIE->isIdenticalTo(*FIE))
636670
break;
637671
// If we are trying to make sure the conditional branches are the same, we
638672
// still don't want to count them.
639673
if (SkipConditionalBranches || !TIE->isBranch())
640674
++Dups2;
641-
--TIE;
642-
--FIE;
675+
shrinkInclusiveRange(TIB, TIE, TEmpty);
676+
shrinkInclusiveRange(FIB, FIE, FEmpty);
643677
}
644678
}
645679

0 commit comments

Comments
 (0)