1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[AArch64] Update successor probabilities after ccmp-conversion

This patch modifies the conditional compares pass so that it keeps successor
probabilities up-to-date after the conversion. Previously, successor
probabilities were being normalized to a uniform distribution, even though they
may have been heavily biased prior to the conversion (e.g., if one of the edges
was the back edge of a loop). This loss of information affected passes later in
the pipeline.

Differential Revision: https://reviews.llvm.org/D34109

llvm-svn: 306412
This commit is contained in:
Matthew Simpson 2017-06-27 15:00:22 +00:00
parent 1b7caf4638
commit e0219a8c24
3 changed files with 93 additions and 7 deletions

View File

@ -22,6 +22,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@ -139,6 +140,7 @@ class SSACCmpConv {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
MachineRegisterInfo *MRI;
const MachineBranchProbabilityInfo *MBPI;
public:
/// The first block containing a conditional branch, dominating everything
@ -186,8 +188,10 @@ private:
public:
/// runOnMachineFunction - Initialize per-function data structures.
void runOnMachineFunction(MachineFunction &MF) {
void runOnMachineFunction(MachineFunction &MF,
const MachineBranchProbabilityInfo *MBPI) {
this->MF = &MF;
this->MBPI = MBPI;
TII = MF.getSubtarget().getInstrInfo();
TRI = MF.getSubtarget().getRegisterInfo();
MRI = &MF.getRegInfo();
@ -564,8 +568,40 @@ void SSACCmpConv::convert(SmallVectorImpl<MachineBasicBlock *> &RemovedBlocks) {
// All CmpBB instructions are moved into Head, and CmpBB is deleted.
// Update the CFG first.
updateTailPHIs();
Head->removeSuccessor(CmpBB, true);
CmpBB->removeSuccessor(Tail, true);
// Save successor probabilties before removing CmpBB and Tail from their
// parents.
BranchProbability Head2CmpBB = MBPI->getEdgeProbability(Head, CmpBB);
BranchProbability CmpBB2Tail = MBPI->getEdgeProbability(CmpBB, Tail);
Head->removeSuccessor(CmpBB);
CmpBB->removeSuccessor(Tail);
// If Head and CmpBB had successor probabilties, udpate the probabilities to
// reflect the ccmp-conversion.
if (Head->hasSuccessorProbabilities() && CmpBB->hasSuccessorProbabilities()) {
// Head is allowed two successors. We've removed CmpBB, so the remaining
// successor is Tail. We need to increase the successor probability for
// Tail to account for the CmpBB path we removed.
//
// Pr(Tail|Head) += Pr(CmpBB|Head) * Pr(Tail|CmpBB).
assert(*Head->succ_begin() == Tail && "Head successor is not Tail");
BranchProbability Head2Tail = MBPI->getEdgeProbability(Head, Tail);
Head->setSuccProbability(Head->succ_begin(),
Head2Tail + Head2CmpBB * CmpBB2Tail);
// We will transfer successors of CmpBB to Head in a moment without
// normalizing the successor probabilities. Set the successor probabilites
// before doing so.
//
// Pr(I|Head) = Pr(CmpBB|Head) * Pr(I|CmpBB).
for (auto I = CmpBB->succ_begin(), E = CmpBB->succ_end(); I != E; ++I) {
BranchProbability CmpBB2I = MBPI->getEdgeProbability(CmpBB, *I);
CmpBB->setSuccProbability(I, Head2CmpBB * CmpBB2I);
}
}
Head->transferSuccessorsAndUpdatePHIs(CmpBB);
DebugLoc TermDL = Head->getFirstTerminator()->getDebugLoc();
TII->removeBranch(*Head);
@ -717,6 +753,7 @@ int SSACCmpConv::expectedCodeSizeDelta() const {
namespace {
class AArch64ConditionalCompares : public MachineFunctionPass {
const MachineBranchProbabilityInfo *MBPI;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
MCSchedModel SchedModel;
@ -753,6 +790,7 @@ char AArch64ConditionalCompares::ID = 0;
INITIALIZE_PASS_BEGIN(AArch64ConditionalCompares, "aarch64-ccmp",
"AArch64 CCMP Pass", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineTraceMetrics)
INITIALIZE_PASS_END(AArch64ConditionalCompares, "aarch64-ccmp",
@ -763,6 +801,7 @@ FunctionPass *llvm::createAArch64ConditionalCompares() {
}
void AArch64ConditionalCompares::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineBranchProbabilityInfo>();
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<MachineLoopInfo>();
@ -892,12 +931,13 @@ bool AArch64ConditionalCompares::runOnMachineFunction(MachineFunction &MF) {
MRI = &MF.getRegInfo();
DomTree = &getAnalysis<MachineDominatorTree>();
Loops = getAnalysisIfAvailable<MachineLoopInfo>();
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
Traces = &getAnalysis<MachineTraceMetrics>();
MinInstr = nullptr;
MinSize = MF.getFunction()->optForMinSize();
bool Changed = false;
CmpConv.runOnMachineFunction(MF);
CmpConv.runOnMachineFunction(MF, MBPI);
// Visit blocks in dominator tree pre-order. The pre-order enables multiple
// cmp-conversions from the same head block.

View File

@ -108,9 +108,9 @@ if.end: ; preds = %if.then, %lor.lhs.f
; CHECK: cmp w0, #1
; CHECK: sdiv [[DIVRES:w[0-9]+]], w1, w0
; CHECK: ccmp [[DIVRES]], #16, #0, ge
; CHECK: b.gt [[BLOCK:LBB[0-9_]+]]
; CHECK: bl _foo
; CHECK: b.le [[BLOCK:LBB[0-9_]+]]
; CHECK: [[BLOCK]]:
; CHECK: bl _foo
; CHECK: orr w0, wzr, #0x7
define i32 @speculate_division(i32 %a, i32 %b) nounwind ssp {
entry:
@ -135,7 +135,7 @@ if.end:
; CHECK: cmp
; CHECK-NOT: b.
; CHECK: fccmp {{.*}}, #8, ge
; CHECK: b.lt
; CHECK: b.ge
define i32 @single_fcmp(i32 %a, float %b) nounwind ssp {
entry:
%cmp = icmp sgt i32 %a, 0

View File

@ -0,0 +1,46 @@
# RUN: llc -o - %s -mtriple=aarch64--linux-gnu -mcpu=falkor -run-pass=aarch64-ccmp | FileCheck %s
---
# This test checks that successor probabilties are properly updated after a
# ccmp-conversion.
#
# CHECK-LABEL: name: aarch64-ccmp-successor-probs
# CHECK: bb.0:
# CHECK-NEXT: successors: %bb.2(0x04000000), %bb.3(0x7c000000)
# CHECK: CCMPXr %5, %4, 0, 10, implicit-def %nzcv, implicit %nzcv
#
name: aarch64-ccmp-successor-probs
registers:
- { id: 0, class: gpr64 }
- { id: 1, class: gpr64 }
- { id: 2, class: gpr64 }
- { id: 3, class: gpr64 }
- { id: 4, class: gpr64 }
- { id: 5, class: gpr64 }
- { id: 6, class: gpr64 }
- { id: 7, class: gpr64 }
body : |
bb.0:
successors: %bb.1(0x7e000000), %bb.2(0x02000000)
%0 = LDRXui killed %x0, 69
%1 = COPY %xzr
%2 = SUBSXrr %1, %0, implicit-def dead %nzcv
%3 = SUBSXri %x1, 1, 0, implicit-def dead %nzcv
%4 = COPY %0
%5 = COPY %3
%6 = SUBSXrr %x1, killed %2, implicit-def %nzcv
Bcc 11, %bb.2, implicit %nzcv
B %bb.1
bb.1:
successors: %bb.2(0x02082082), %bb.3(0x7df7df7e)
%7 = SUBSXrr %5, %4, implicit-def %nzcv
Bcc 12, %bb.2, implicit %nzcv
B %bb.3
bb.2:
successors: %bb.3(0x80000000)
bb.3:
...