1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ARM] Allow findLoopPreheader to return headers with multiple loop successors

The findLoopPreheader function will currently not find a preheader if it
branches to multiple different loop headers. This patch adds an option
to relax that, allowing ARMLowOverheadLoops to process more loops
successfully. This helps with WhileLoopStart setup instructions that can
branch/fallthrough to the low overhead loop and to branch to a separate
loop from the same preheader (but I don't believe it is possible for
both loops to be low overhead loops).

Differential Revision: https://reviews.llvm.org/D102747
This commit is contained in:
David Green 2021-05-24 12:22:15 +01:00
parent 5f9b78cce6
commit 35e013cb3d
5 changed files with 33 additions and 45 deletions

View File

@ -110,8 +110,11 @@ public:
/// loop setup code. Code that cannot be speculated should not be placed /// loop setup code. Code that cannot be speculated should not be placed
/// here. SpeculativePreheader is controlling whether it also tries to /// here. SpeculativePreheader is controlling whether it also tries to
/// find the speculative preheader if the regular preheader is not present. /// find the speculative preheader if the regular preheader is not present.
MachineBasicBlock *findLoopPreheader(MachineLoop *L, /// With FindMultiLoopPreheader = false, nullptr will be returned if the found
bool SpeculativePreheader = false) const; /// preheader is the preheader of multiple loops.
MachineBasicBlock *
findLoopPreheader(MachineLoop *L, bool SpeculativePreheader = false,
bool FindMultiLoopPreheader = false) const;
/// The iterator interface to the top-level loops in the current function. /// The iterator interface to the top-level loops in the current function.
using iterator = LoopInfoBase<MachineBasicBlock, MachineLoop>::iterator; using iterator = LoopInfoBase<MachineBasicBlock, MachineLoop>::iterator;

View File

@ -115,8 +115,8 @@ DebugLoc MachineLoop::getStartLoc() const {
} }
MachineBasicBlock * MachineBasicBlock *
MachineLoopInfo::findLoopPreheader(MachineLoop *L, MachineLoopInfo::findLoopPreheader(MachineLoop *L, bool SpeculativePreheader,
bool SpeculativePreheader) const { bool FindMultiLoopPreheader) const {
if (MachineBasicBlock *PB = L->getLoopPreheader()) if (MachineBasicBlock *PB = L->getLoopPreheader())
return PB; return PB;
@ -139,12 +139,14 @@ MachineLoopInfo::findLoopPreheader(MachineLoop *L,
// Check if the preheader candidate is a successor of any other loop // Check if the preheader candidate is a successor of any other loop
// headers. We want to avoid having two loop setups in the same block. // headers. We want to avoid having two loop setups in the same block.
for (MachineBasicBlock *S : Preheader->successors()) { if (!FindMultiLoopPreheader) {
if (S == HB) for (MachineBasicBlock *S : Preheader->successors()) {
continue; if (S == HB)
MachineLoop *T = getLoopFor(S); continue;
if (T && T->getHeader() == S) MachineLoop *T = getLoopFor(S);
return nullptr; if (T && T->getHeader() == S)
return nullptr;
}
} }
return Preheader; return Preheader;
} }

View File

@ -158,7 +158,7 @@ namespace {
if (auto *Preheader = ML.getLoopPreheader()) if (auto *Preheader = ML.getLoopPreheader())
GetPredecessor(Preheader); GetPredecessor(Preheader);
else if (auto *Preheader = MLI.findLoopPreheader(&ML, true)) else if (auto *Preheader = MLI.findLoopPreheader(&ML, true, true))
GetPredecessor(Preheader); GetPredecessor(Preheader);
} }
}; };
@ -386,7 +386,7 @@ namespace {
MF = ML.getHeader()->getParent(); MF = ML.getHeader()->getParent();
if (auto *MBB = ML.getLoopPreheader()) if (auto *MBB = ML.getLoopPreheader())
Preheader = MBB; Preheader = MBB;
else if (auto *MBB = MLI.findLoopPreheader(&ML, true)) else if (auto *MBB = MLI.findLoopPreheader(&ML, true, true))
Preheader = MBB; Preheader = MBB;
VPTState::reset(); VPTState::reset();
} }
@ -1197,16 +1197,15 @@ bool ARMLowOverheadLoops::ProcessLoop(MachineLoop *ML) {
for (auto I = ML->begin(), E = ML->end(); I != E; ++I) for (auto I = ML->begin(), E = ML->end(); I != E; ++I)
Changed |= ProcessLoop(*I); Changed |= ProcessLoop(*I);
LLVM_DEBUG(dbgs() << "ARM Loops: Processing loop containing:\n"; LLVM_DEBUG({
if (auto *Preheader = ML->getLoopPreheader()) dbgs() << "ARM Loops: Processing loop containing:\n";
dbgs() << " - " << Preheader->getName() << "\n"; if (auto *Preheader = ML->getLoopPreheader())
else if (auto *Preheader = MLI->findLoopPreheader(ML)) dbgs() << " - Preheader: " << printMBBReference(*Preheader) << "\n";
dbgs() << " - " << Preheader->getName() << "\n"; else if (auto *Preheader = MLI->findLoopPreheader(ML, true, true))
else if (auto *Preheader = MLI->findLoopPreheader(ML, true)) dbgs() << " - Preheader: " << printMBBReference(*Preheader) << "\n";
dbgs() << " - " << Preheader->getName() << "\n"; for (auto *MBB : ML->getBlocks())
for (auto *MBB : ML->getBlocks()) dbgs() << " - Block: " << printMBBReference(*MBB) << "\n";
dbgs() << " - " << MBB->getName() << "\n"; });
);
// Search the given block for a loop start instruction. If one isn't found, // Search the given block for a loop start instruction. If one isn't found,
// and there's only one predecessor block, search that one too. // and there's only one predecessor block, search that one too.

View File

@ -117,10 +117,7 @@ define i32 @a(i8 zeroext %b, [3 x i8]* nocapture readonly %c, [3 x i32]* nocaptu
; CHECK-NEXT: add.w r5, r12, r3 ; CHECK-NEXT: add.w r5, r12, r3
; CHECK-NEXT: rsb.w r3, r3, #108 ; CHECK-NEXT: rsb.w r3, r3, #108
; CHECK-NEXT: add.w r4, r5, #19 ; CHECK-NEXT: add.w r4, r5, #19
; CHECK-NEXT: add.w r5, r3, #15 ; CHECK-NEXT: wlstp.8 lr, r3, .LBB0_13
; CHECK-NEXT: lsrs r5, r5, #4
; CHECK-NEXT: subs.w lr, r5, #0
; CHECK-NEXT: beq .LBB0_13
; CHECK-NEXT: b .LBB0_23 ; CHECK-NEXT: b .LBB0_23
; CHECK-NEXT: .LBB0_13: @ %for.cond ; CHECK-NEXT: .LBB0_13: @ %for.cond
; CHECK-NEXT: @ =>This Loop Header: Depth=1 ; CHECK-NEXT: @ =>This Loop Header: Depth=1
@ -190,12 +187,8 @@ define i32 @a(i8 zeroext %b, [3 x i8]* nocapture readonly %c, [3 x i32]* nocaptu
; CHECK-NEXT: b .LBB0_12 ; CHECK-NEXT: b .LBB0_12
; CHECK-NEXT: .LBB0_23: @ Parent Loop BB0_13 Depth=1 ; CHECK-NEXT: .LBB0_23: @ Parent Loop BB0_13 Depth=1
; CHECK-NEXT: @ => This Inner Loop Header: Depth=2 ; CHECK-NEXT: @ => This Inner Loop Header: Depth=2
; CHECK-NEXT: vctp.8 r3 ; CHECK-NEXT: vstrb.8 q3, [r4], #16
; CHECK-NEXT: subs r3, #16 ; CHECK-NEXT: letp lr, .LBB0_23
; CHECK-NEXT: vpst
; CHECK-NEXT: vstrbt.8 q3, [r4], #16
; CHECK-NEXT: subs.w lr, lr, #1
; CHECK-NEXT: bne .LBB0_23
; CHECK-NEXT: b .LBB0_13 ; CHECK-NEXT: b .LBB0_13
entry: entry:
%cmp = icmp ugt i8 %b, 1 %cmp = icmp ugt i8 %b, 1

View File

@ -233,23 +233,14 @@ define void @test11(i8* nocapture %x, i8* nocapture %y, i32 %n) {
; CHECK-NEXT: it gt ; CHECK-NEXT: it gt
; CHECK-NEXT: popgt {r4, pc} ; CHECK-NEXT: popgt {r4, pc}
; CHECK-NEXT: .LBB10_1: @ %prehead ; CHECK-NEXT: .LBB10_1: @ %prehead
; CHECK-NEXT: add.w r3, r2, #15
; CHECK-NEXT: mov r12, r1 ; CHECK-NEXT: mov r12, r1
; CHECK-NEXT: mov r4, r0 ; CHECK-NEXT: mov r4, r0
; CHECK-NEXT: lsr.w lr, r3, #4
; CHECK-NEXT: mov r3, r2 ; CHECK-NEXT: mov r3, r2
; CHECK-NEXT: subs.w lr, lr, #0 ; CHECK-NEXT: wlstp.8 lr, r3, .LBB10_3
; CHECK-NEXT: beq .LBB10_3
; CHECK-NEXT: b .LBB10_2
; CHECK-NEXT: .LBB10_2: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: .LBB10_2: @ =>This Inner Loop Header: Depth=1
; CHECK-NEXT: vctp.8 r3 ; CHECK-NEXT: vldrb.u8 q0, [r12], #16
; CHECK-NEXT: subs r3, #16 ; CHECK-NEXT: vstrb.8 q0, [r4], #16
; CHECK-NEXT: vpstt ; CHECK-NEXT: letp lr, .LBB10_2
; CHECK-NEXT: vldrbt.u8 q0, [r12], #16
; CHECK-NEXT: vstrbt.8 q0, [r4], #16
; CHECK-NEXT: subs.w lr, lr, #1
; CHECK-NEXT: bne .LBB10_2
; CHECK-NEXT: b .LBB10_3
; CHECK-NEXT: .LBB10_3: @ %for.body ; CHECK-NEXT: .LBB10_3: @ %for.body
; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1
; CHECK-NEXT: ldrb r3, [r0], #1 ; CHECK-NEXT: ldrb r3, [r0], #1