diff options
author | Hongtao Yu <hoy@fb.com> | 2021-02-25 00:52:58 -0800 |
---|---|---|
committer | Hongtao Yu <hoy@fb.com> | 2021-03-03 22:44:42 -0800 |
commit | 89855158228644b7be273055efd728b82ea82803 (patch) | |
tree | b58bf3372eb91d5004f216ac900310f5edacd628 /llvm/lib/CodeGen/MachineBasicBlock.cpp | |
parent | ad2a59f5840482d7dd802e83b82262c97704a4eb (diff) | |
download | llvm-89855158228644b7be273055efd728b82ea82803.zip llvm-89855158228644b7be273055efd728b82ea82803.tar.gz llvm-89855158228644b7be273055efd728b82ea82803.tar.bz2 |
[CSSPGO] Unblocking optimizations by dangling pseudo probes.
This change fixes a couple places where the pseudo probe intrinsic blocks optimizations because they are not naturally removable. To unblock those optimizations, the blocking pseudo probes are moved out of the original blocks and tagged dangling, instead of allowing pseudo probes to be literally removed. The reason is that when the original block is removed, we won't be able to sample it. Instead of assigning it a zero weight, moving all its pseudo probes into another block and marking them dangling should allow the counts inference a chance to assign them a more reasonable weight. We have not seen counts quality degradation from our experiments.
The optimizations being unblocked are:
1. Removing conditional probes for if-converted branches. Conditional probes are tagged dangling when their homing branch arms are folded so that they will not be over-counted.
2. Unblocking jump threading from removing empty blocks. Pseudo probe prevents jump threading from removing logically empty blocks that only has one unconditional jump instructions.
3. Unblocking SimplifyCFG and MIR tail duplicate to thread empty blocks and blocks with redundant branch checks.
Since dangling probes are logically deleted, they should not consume any samples in LTO postLink. This can be achieved by setting their distribution factors to zero when dangled.
Reviewed By: wmi
Differential Revision: https://reviews.llvm.org/D97481
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); } |