/// Return the first instruction in MBB after I that is not a PHI, label or
/// debug. This is the correct point to insert copies at the beginning of a
/// basic block.
- iterator SkipPHIsLabelsAndDebug(iterator I);
+ iterator SkipPHIsLabelsAndDebug(iterator I, bool SkipPseudoOp = true);
/// Returns an iterator to the first terminator instruction of this basic
/// block. If a terminator does not exist, it returns end().
/// Therefore, they should be considered as a valid instruction when this
/// function is called in a context of such optimizations. On the other hand,
/// \c SkipPseudoOp should be true when it's used in optimizations that
- /// unlikely hurt profile quality, e.g., without block merging.
- /// TODO: flip the default value of \c SkipPseudoOp to maximize code quality
- /// with pseudo probes.
- iterator getFirstNonDebugInstr(bool SkipPseudoOp = false);
- const_iterator getFirstNonDebugInstr(bool SkipPseudoOp = false) const {
+ /// unlikely hurt profile quality, e.g., without block merging. The default
+ /// value of \c SkipPseudoOp is set to true to maximize code quality in
+ /// general, with an explict false value passed in in a few places like branch
+ /// folding and if-conversion to favor profile quality.
+ iterator getFirstNonDebugInstr(bool SkipPseudoOp = true);
+ const_iterator getFirstNonDebugInstr(bool SkipPseudoOp = true) const {
return const_cast<MachineBasicBlock *>(this)->getFirstNonDebugInstr(
SkipPseudoOp);
}
/// Therefore, they should be considered as a valid instruction when this
/// function is called in a context of such optimizations. On the other hand,
/// \c SkipPseudoOp should be true when it's used in optimizations that
- /// unlikely hurt profile quality, e.g., without block merging.
- iterator getLastNonDebugInstr(bool SkipPseudoOp = false);
- const_iterator getLastNonDebugInstr(bool SkipPseudoOp = false) const {
+ /// unlikely hurt profile quality, e.g., without block merging. The default
+ /// value of \c SkipPseudoOp is set to true to maximize code quality in
+ /// general, with an explict false value passed in in a few places like branch
+ /// folding and if-conversion to favor profile quality.
+ iterator getLastNonDebugInstr(bool SkipPseudoOp = true);
+ const_iterator getLastNonDebugInstr(bool SkipPseudoOp = true) const {
return const_cast<MachineBasicBlock *>(this)->getLastNonDebugInstr(
SkipPseudoOp);
}
/// const_instr_iterator} and the respective reverse iterators.
template <typename IterT>
inline IterT skipDebugInstructionsForward(IterT It, IterT End,
- bool SkipPseudoOp = false) {
+ bool SkipPseudoOp = true) {
while (It != End &&
(It->isDebugInstr() || (SkipPseudoOp && It->isPseudoProbe())))
++It;
/// const_instr_iterator} and the respective reverse iterators.
template <class IterT>
inline IterT skipDebugInstructionsBackward(IterT It, IterT Begin,
- bool SkipPseudoOp = false) {
+ bool SkipPseudoOp = true) {
while (It != Begin &&
(It->isDebugInstr() || (SkipPseudoOp && It->isPseudoProbe())))
--It;
/// Increment \p It, then continue incrementing it while it points to a debug
/// instruction. A replacement for std::next.
template <typename IterT>
-inline IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp = false) {
+inline IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp = true) {
return skipDebugInstructionsForward(std::next(It), End, SkipPseudoOp);
}
/// Decrement \p It, then continue decrementing it while it points to a debug
/// instruction. A replacement for std::prev.
template <typename IterT>
-inline IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp = false) {
+inline IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp = true) {
return skipDebugInstructionsBackward(std::prev(It), Begin, SkipPseudoOp);
}
/// \p End is reached, skipping any debug instructions.
template <typename IterT>
inline auto instructionsWithoutDebug(IterT It, IterT End,
- bool SkipPseudoOp = false) {
+ bool SkipPseudoOp = true) {
return make_filter_range(make_range(It, End), [=](const MachineInstr &MI) {
return !MI.isDebugInstr() && !(SkipPseudoOp && MI.isPseudoProbe());
});
/// HashEndOfMBB - Hash the last instruction in the MBB.
static unsigned HashEndOfMBB(const MachineBasicBlock &MBB) {
- MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
+ MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr(false);
if (I == MBB.end())
return 0;
// Move the iterators to the beginning of the MBB if we only got debug
// instructions before the tail. This is to avoid splitting a block when we
// only got debug instructions before the tail (to be invariant on -g).
- if (skipDebugInstructionsForward(MBB1->begin(), MBB1->end()) == I1)
+ if (skipDebugInstructionsForward(MBB1->begin(), MBB1->end(), false) == I1)
I1 = MBB1->begin();
- if (skipDebugInstructionsForward(MBB2->begin(), MBB2->end()) == I2)
+ if (skipDebugInstructionsForward(MBB2->begin(), MBB2->end(), false) == I2)
I2 = MBB2->begin();
bool FullBlockTail1 = I1 == MBB1->begin();
MachineBasicBlock::iterator FIE = FBB->end();
while (TIB != TIE && FIB != FIE) {
// Skip dbg_value instructions. These do not count.
- TIB = skipDebugInstructionsForward(TIB, TIE);
- FIB = skipDebugInstructionsForward(FIB, FIE);
+ TIB = skipDebugInstructionsForward(TIB, TIE, false);
+ FIB = skipDebugInstructionsForward(FIB, FIE, false);
if (TIB == TIE || FIB == FIE)
break;
bool SkipUnconditionalBranches) const {
while (TIB != TIE && FIB != FIE) {
// Skip dbg_value instructions. These do not count.
- TIB = skipDebugInstructionsForward(TIB, TIE);
- FIB = skipDebugInstructionsForward(FIB, FIE);
+ TIB = skipDebugInstructionsForward(TIB, TIE, false);
+ FIB = skipDebugInstructionsForward(FIB, FIE, false);
if (TIB == TIE || FIB == FIE)
break;
if (!TIB->isIdenticalTo(*FIB))
while (RTIE != RTIB && RFIE != RFIB) {
// Skip dbg_value instructions. These do not count.
// Note that these are reverse iterators going forward.
- RTIE = skipDebugInstructionsForward(RTIE, RTIB);
- RFIE = skipDebugInstructionsForward(RFIE, RFIB);
+ RTIE = skipDebugInstructionsForward(RTIE, RTIB, false);
+ RFIE = skipDebugInstructionsForward(RFIE, RFIB, false);
if (RTIE == RTIB || RFIE == RFIB)
break;
if (!RTIE->isIdenticalTo(*RFIE))
MachineBasicBlock::reverse_iterator E1 = MBB1->rbegin();
MachineBasicBlock::reverse_iterator E2 = MBB2->rbegin();
while (E1 != B1 && E2 != B2) {
- skipDebugInstructionsForward(E1, B1);
- skipDebugInstructionsForward(E2, B2);
+ skipDebugInstructionsForward(E1, B1, false);
+ skipDebugInstructionsForward(E2, B2, false);
if (E1 == B1 && E2 == B2)
break;
// Remove the duplicated instructions at the beginnings of both paths.
// Skip dbg_value instructions.
- MachineBasicBlock::iterator DI1 = MBB1.getFirstNonDebugInstr();
- MachineBasicBlock::iterator DI2 = MBB2.getFirstNonDebugInstr();
+ MachineBasicBlock::iterator DI1 = MBB1.getFirstNonDebugInstr(false);
+ MachineBasicBlock::iterator DI2 = MBB2.getFirstNonDebugInstr(false);
BBI1->NonPredSize -= NumDups1;
BBI2->NonPredSize -= NumDups1;