diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineBasicBlock.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineBasicBlock.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index aa3f3a8..8ed1701 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -254,12 +254,14 @@ MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() { return I; } -MachineBasicBlock::iterator MachineBasicBlock::getFirstNonDebugInstr() { +MachineBasicBlock::iterator +MachineBasicBlock::getFirstNonDebugInstr(bool SkipPseudoOp) { // Skip over begin-of-block dbg_value instructions. - return skipDebugInstructionsForward(begin(), end()); + return skipDebugInstructionsForward(begin(), end(), SkipPseudoOp); } -MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() { +MachineBasicBlock::iterator +MachineBasicBlock::getLastNonDebugInstr(bool SkipPseudoOp) { // Skip over end-of-block dbg_value instructions. instr_iterator B = instr_begin(), I = instr_end(); while (I != B) { @@ -267,6 +269,8 @@ MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() { // Return instruction that starts a bundle. if (I->isDebugInstr() || I->isInsideBundle()) continue; + if (SkipPseudoOp && I->isPseudoProbe()) + continue; return I; } // The block is all debug values. @@ -894,6 +898,32 @@ MachineBasicBlock::transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB) { normalizeSuccProbs(); } +/// A block emptied (i.e., with all instructions moved out of it) won't be +/// sampled at run time. In such cases, AutoFDO will be informed of zero samples +/// collected for the block. This is not accurate and could lead to misleading +/// weights assigned for the block. A way to mitigate that is to treat such +/// block as having unknown counts in the AutoFDO profile loader and allow the +/// counts inference tool a chance to calculate a relatively reasonable weight +/// for it. This can be done by moving all pseudo probes in the emptied block +/// i.e, /c this, to before /c ToMBB and tag them dangling. Note that this is +/// not needed for dead blocks which really have a zero weight. It's per +/// transforms to decide whether to call this function or not. +void MachineBasicBlock::moveAndDanglePseudoProbes(MachineBasicBlock *ToMBB) { + SmallVector<MachineInstr *, 4> ToBeMoved; + for (MachineInstr &MI : instrs()) { + if (MI.isPseudoProbe()) { + MI.addPseudoProbeAttribute(PseudoProbeAttributes::Dangling); + ToBeMoved.push_back(&MI); + } + } + + MachineBasicBlock::iterator I = ToMBB->getFirstTerminator(); + for (MachineInstr *MI : ToBeMoved) { + MI->removeFromParent(); + ToMBB->insert(I, MI); + } +} + bool MachineBasicBlock::isPredecessor(const MachineBasicBlock *MBB) const { return is_contained(predecessors(), MBB); } |