Index: lib/CodeGen/IfConversion.cpp =================================================================== --- lib/CodeGen/IfConversion.cpp +++ lib/CodeGen/IfConversion.cpp @@ -592,42 +592,14 @@ /// @param It Iterator to increment /// @param End Iterator that points to end. Will be compared to It /// @returns true if It == End, false otherwise. -static inline bool skipDebugInstructionsForward( - MachineBasicBlock::iterator &It, - MachineBasicBlock::iterator &End) { +template +static inline bool skipDebugInstructions( + T &It, const T &End) { while (It != End && It->isDebugValue()) It++; return It == End; } -/// Shrink the provided inclusive range by one instruction. -/// If the range was one instruction (\p It == \p Begin), It is not modified, -/// but \p Empty is set to true. -static inline void shrinkInclusiveRange( - MachineBasicBlock::iterator &Begin, - MachineBasicBlock::iterator &It, - bool &Empty) { - if (It == Begin) - Empty = true; - else - It--; -} - -/// Decrement \p It until it points to a non-debug instruction or the range is -/// empty. -/// @param It Iterator to decrement. -/// @param Begin Iterator that points to beginning. Will be compared to It -/// @param Empty Set to true if the resulting range is Empty -/// @returns the value of Empty as a convenience. -static inline bool skipDebugInstructionsBackward( - MachineBasicBlock::iterator &Begin, - MachineBasicBlock::iterator &It, - bool &Empty) { - while (!Empty && It->isDebugValue()) - shrinkInclusiveRange(Begin, It, Empty); - return Empty; -} - /// Count duplicated instructions and move the iterators to show where they /// are. /// @param TIB True Iterator Begin @@ -659,9 +631,9 @@ while (TIB != TIE && FIB != FIE) { // Skip dbg_value instructions. These do not count. - if(skipDebugInstructionsForward(TIB, TIE)) + if(skipDebugInstructions(TIB, TIE)) break; - if(skipDebugInstructionsForward(FIB, FIE)) + if(skipDebugInstructions(FIB, FIE)) break; if (!TIB->isIdenticalTo(*FIB)) break; @@ -681,56 +653,40 @@ if (TIB == TIE || FIB == FIE) return true; // Now, in preparation for counting duplicate instructions at the ends of the - // blocks, move the end iterators up past any branch instructions. - --TIE; - --FIE; - - // After this point TIB and TIE define an inclusive range, which means that - // TIB == TIE is true when there is one more instruction to consider, not at - // the end. Because we may not be able to go before TIB, we need a flag to - // indicate a completely empty range. - bool TEmpty = false, FEmpty = false; - - // Upon exit TIE and FIE will both point at the last non-shared instruction. - // They need to be moved forward to point past the last non-shared - // instruction if the range they delimit is non-empty. - auto IncrementEndIteratorsOnExit = make_scope_exit([&]() { - if (!TEmpty) - ++TIE; - if (!FEmpty) - ++FIE; - }); + // blocks, switch to reverse_iterators. Note that these are NOT std + // reverse_iterators, so we have to manually do the off by one accounting. + MachineBasicBlock::reverse_iterator RTIE = ++(TIE.getReverse()); + MachineBasicBlock::reverse_iterator RFIE = ++(FIE.getReverse()); + const MachineBasicBlock::reverse_iterator RTIB = ++(TIB.getReverse()); + const MachineBasicBlock::reverse_iterator RFIB = ++(FIB.getReverse()); if (!TBB.succ_empty() || !FBB.succ_empty()) { if (SkipUnconditionalBranches) { - while (!TEmpty && TIE->isUnconditionalBranch()) - shrinkInclusiveRange(TIB, TIE, TEmpty); - while (!FEmpty && FIE->isUnconditionalBranch()) - shrinkInclusiveRange(FIB, FIE, FEmpty); + while (RTIE != RTIB && RTIE->isUnconditionalBranch()) + ++RTIE; + while (RFIE != RFIB && RFIE->isUnconditionalBranch()) + ++RFIE; } } - // If Dups1 includes all of a block, then don't count duplicate - // instructions at the end of the blocks. - if (TEmpty || FEmpty) - return true; - // Count duplicate instructions at the ends of the blocks. - while (!TEmpty && !FEmpty) { + while (RTIE != RTIB && RFIE != RFIB) { // Skip dbg_value instructions. These do not count. - if (skipDebugInstructionsBackward(TIB, TIE, TEmpty)) + if (skipDebugInstructions(RTIE, RTIB)) break; - if (skipDebugInstructionsBackward(FIB, FIE, FEmpty)) + if (skipDebugInstructions(RFIE, RFIB)) break; - if (!TIE->isIdenticalTo(*FIE)) + if (!RTIE->isIdenticalTo(*RFIE)) break; // We have to verify that any branch instructions are the same, and then we // don't count them toward the # of duplicate instructions. - if (!TIE->isBranch()) + if (!RTIE->isBranch()) ++Dups2; - shrinkInclusiveRange(TIB, TIE, TEmpty); - shrinkInclusiveRange(FIB, FIE, FEmpty); + ++RTIE; + ++RFIE; } + TIE = ++RTIE.getReverse(); + FIE = ++RFIE.getReverse(); return true; } @@ -764,22 +720,21 @@ static void verifySameBranchInstructions( MachineBasicBlock *MBB1, MachineBasicBlock *MBB2) { - MachineBasicBlock::iterator B1 = MBB1->begin(); - MachineBasicBlock::iterator B2 = MBB2->begin(); - MachineBasicBlock::iterator E1 = std::prev(MBB1->end()); - MachineBasicBlock::iterator E2 = std::prev(MBB2->end()); - bool Empty1 = false, Empty2 = false; - while (!Empty1 && !Empty2) { - skipDebugInstructionsBackward(B1, E1, Empty1); - skipDebugInstructionsBackward(B2, E2, Empty2); - if (Empty1 && Empty2) + const MachineBasicBlock::reverse_iterator B1 = MBB1->rend(); + const MachineBasicBlock::reverse_iterator B2 = MBB2->rend(); + MachineBasicBlock::reverse_iterator E1 = MBB1->rbegin(); + MachineBasicBlock::reverse_iterator E2 = MBB2->rbegin(); + while (E1 != B1 && E2 != B2) { + skipDebugInstructions(E1, B1); + skipDebugInstructions(E2, B2); + if (E1 == B1 && E2 == B2) break; - if (Empty1) { + if (E1 == B1) { assert(!E2->isBranch() && "Branch mis-match, one block is empty."); break; } - if (Empty2) { + if (E2 == B2) { assert(!E1->isBranch() && "Branch mis-match, one block is empty."); break; } @@ -789,8 +744,8 @@ "Branch mis-match, branch instructions don't match."); else break; - shrinkInclusiveRange(B1, E1, Empty1); - shrinkInclusiveRange(B2, E2, Empty2); + ++E1; + ++E2; } } #endif