diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCReduceCRLogicals.cpp | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCReduceCRLogicals.cpp b/llvm/lib/Target/PowerPC/PPCReduceCRLogicals.cpp index 45f8907a08e..8eaa6dfe2bf 100644 --- a/llvm/lib/Target/PowerPC/PPCReduceCRLogicals.cpp +++ b/llvm/lib/Target/PowerPC/PPCReduceCRLogicals.cpp @@ -166,9 +166,33 @@ static bool splitMBB(BlockSplitInfo &BSI) { : *ThisMBB->succ_begin(); MachineBasicBlock *NewBRTarget = BSI.BranchToFallThrough ? OrigFallThrough : OrigTarget; - BranchProbability ProbToNewTarget = - !BSI.MBPI ? BranchProbability::getUnknown() - : BSI.MBPI->getEdgeProbability(ThisMBB, NewBRTarget); + + // It's impossible to know the precise branch probability after the split. + // But it still needs to be reasonable, the whole probability to original + // targets should not be changed. + // After split NewBRTarget will get two incoming edges. Assume P0 is the + // original branch probability to NewBRTarget, P1 and P2 are new branch + // probabilies to NewBRTarget after split. If the two edge frequencies are + // same, then + // F * P1 = F * P0 / 2 ==> P1 = P0 / 2 + // F * (1 - P1) * P2 = F * P1 ==> P2 = P1 / (1 - P1) + BranchProbability ProbToNewTarget, ProbFallThrough; // Prob for new Br. + BranchProbability ProbOrigTarget, ProbOrigFallThrough; // Prob for orig Br. + ProbToNewTarget = ProbFallThrough = BranchProbability::getUnknown(); + ProbOrigTarget = ProbOrigFallThrough = BranchProbability::getUnknown(); + if (BSI.MBPI) { + if (BSI.BranchToFallThrough) { + ProbToNewTarget = BSI.MBPI->getEdgeProbability(ThisMBB, OrigFallThrough) / 2; + ProbFallThrough = ProbToNewTarget.getCompl(); + ProbOrigFallThrough = ProbToNewTarget / ProbToNewTarget.getCompl(); + ProbOrigTarget = ProbOrigFallThrough.getCompl(); + } else { + ProbToNewTarget = BSI.MBPI->getEdgeProbability(ThisMBB, OrigTarget) / 2; + ProbFallThrough = ProbToNewTarget.getCompl(); + ProbOrigTarget = ProbToNewTarget / ProbToNewTarget.getCompl(); + ProbOrigFallThrough = ProbOrigTarget.getCompl(); + } + } // Create a new basic block. MachineBasicBlock::iterator InsertPoint = BSI.SplitBefore; @@ -180,11 +204,16 @@ static bool splitMBB(BlockSplitInfo &BSI) { // Move everything after SplitBefore into the new block. NewMBB->splice(NewMBB->end(), ThisMBB, InsertPoint, ThisMBB->end()); NewMBB->transferSuccessors(ThisMBB); + if (!ProbOrigTarget.isUnknown()) { + auto MBBI = std::find(NewMBB->succ_begin(), NewMBB->succ_end(), OrigTarget); + NewMBB->setSuccProbability(MBBI, ProbOrigTarget); + MBBI = std::find(NewMBB->succ_begin(), NewMBB->succ_end(), OrigFallThrough); + NewMBB->setSuccProbability(MBBI, ProbOrigFallThrough); + } - // Add the two successors to ThisMBB. The probabilities come from the - // existing blocks if available. + // Add the two successors to ThisMBB. ThisMBB->addSuccessor(NewBRTarget, ProbToNewTarget); - ThisMBB->addSuccessor(NewMBB, ProbToNewTarget.getCompl()); + ThisMBB->addSuccessor(NewMBB, ProbFallThrough); // Add the branches to ThisMBB. BuildMI(*ThisMBB, ThisMBB->end(), BSI.SplitBefore->getDebugLoc(), |

