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:
parent
1b7caf4638
commit
e0219a8c24
@ -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.
|
||||
|
@ -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
|
||||
|
46
test/CodeGen/AArch64/ccmp-successor-probs.mir
Normal file
46
test/CodeGen/AArch64/ccmp-successor-probs.mir
Normal 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:
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user