1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00

[PowerPC] Enable redundant TOC save removal on AIX

Reviewed By: shchenz

Differential Revision: https://reviews.llvm.org/D97039
This commit is contained in:
Qiu Chaofan 2021-03-22 14:29:22 +08:00
parent edd216b650
commit 7c18c33042
3 changed files with 70 additions and 21 deletions

View File

@ -5156,7 +5156,8 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
unsigned StackOffset = MI.getOperand(1).getImm();
Register StackReg = MI.getOperand(2).getReg();
if (StackReg == PPC::X1 && StackOffset == TOCSaveOffset)
Register SPReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
if (StackReg == SPReg && StackOffset == TOCSaveOffset)
return true;
return false;

View File

@ -226,28 +226,30 @@ getKnownLeadingZeroCount(MachineInstr *MI, const PPCInstrInfo *TII) {
void PPCMIPeephole::UpdateTOCSaves(
std::map<MachineInstr *, bool> &TOCSaves, MachineInstr *MI) {
assert(TII->isTOCSaveMI(*MI) && "Expecting a TOC save instruction here");
assert(MF->getSubtarget<PPCSubtarget>().isELFv2ABI() &&
"TOC-save removal only supported on ELFv2");
PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
// FIXME: Saving TOC in prologue hasn't been implemented well in AIX ABI part,
// here only support it under ELFv2.
if (MF->getSubtarget<PPCSubtarget>().isELFv2ABI()) {
PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
MachineBasicBlock *Entry = &MF->front();
uint64_t CurrBlockFreq = MBFI->getBlockFreq(MI->getParent()).getFrequency();
MachineBasicBlock *Entry = &MF->front();
uint64_t CurrBlockFreq = MBFI->getBlockFreq(MI->getParent()).getFrequency();
// If the block in which the TOC save resides is in a block that
// post-dominates Entry, or a block that is hotter than entry (keep in mind
// that early MachineLICM has already run so the TOC save won't be hoisted)
// we can just do the save in the prologue.
if (CurrBlockFreq > EntryFreq || MPDT->dominates(MI->getParent(), Entry))
FI->setMustSaveTOC(true);
// If the block in which the TOC save resides is in a block that
// post-dominates Entry, or a block that is hotter than entry (keep in mind
// that early MachineLICM has already run so the TOC save won't be hoisted)
// we can just do the save in the prologue.
if (CurrBlockFreq > EntryFreq || MPDT->dominates(MI->getParent(), Entry))
FI->setMustSaveTOC(true);
// If we are saving the TOC in the prologue, all the TOC saves can be removed
// from the code.
if (FI->mustSaveTOC()) {
for (auto &TOCSave : TOCSaves)
TOCSave.second = false;
// Add new instruction to map.
TOCSaves[MI] = false;
return;
// If we are saving the TOC in the prologue, all the TOC saves can be
// removed from the code.
if (FI->mustSaveTOC()) {
for (auto &TOCSave : TOCSaves)
TOCSave.second = false;
// Add new instruction to map.
TOCSaves[MI] = false;
return;
}
}
bool Keep = true;
@ -476,10 +478,12 @@ bool PPCMIPeephole::simplifyCode(void) {
}
break;
}
case PPC::STW:
case PPC::STD: {
MachineFrameInfo &MFI = MF->getFrameInfo();
if (MFI.hasVarSizedObjects() ||
!MF->getSubtarget<PPCSubtarget>().isELFv2ABI())
(!MF->getSubtarget<PPCSubtarget>().isELFv2ABI() &&
!MF->getSubtarget<PPCSubtarget>().isAIXABI()))
break;
// When encountering a TOC save instruction, call UpdateTOCSaves
// to add it to the TOCSaves map and mark any existing TOC saves

View File

@ -1,9 +1,20 @@
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-ibm-aix-xcoff < %s | FileCheck %s --check-prefix=AIX64
; RUN: llc -verify-machineinstrs -mtriple=powerpc-ibm-aix-xcoff < %s | FileCheck %s --check-prefix=AIX32
define signext i32 @test1(i32 signext %i, i32 (i32)* nocapture %Func, i32 (i32)* nocapture %Func2) {
entry:
; CHECK-LABEL: test1:
; CHECK: std 2, 24(1)
; CHECK-NOT: std 2, 24(1)
; AIX64-LABEL: test1:
; AIX64: std 2, 40(1)
; AIX64-NOT: std 2, 40(1)
; AIX32-LABEL: test1:
; AIX32: stw 2, 20(1)
; AIX32-NOT: std 2, 20(1)
%call = tail call signext i32 %Func(i32 signext %i)
%call1 = tail call signext i32 %Func2(i32 signext %i)
%add2 = add nsw i32 %call1, %call
@ -15,6 +26,14 @@ entry:
; CHECK-LABEL: test2:
; CHECK: std 2, 24(1)
; CHECK-NOT: std 2, 24(1)
; AIX64-LABEL: test2:
; AIX64: std 2, 40(1)
; AIX64-NOT: std 2, 40(1)
; AIX32-LABEL: test2:
; AIX32: stw 2, 20(1)
; AIX32-NOT: std 2, 20(1)
%call = tail call signext i32 %Func(i32 signext %i)
%tobool = icmp eq i32 %j, 0
br i1 %tobool, label %if.end, label %if.then
@ -38,6 +57,12 @@ define signext i32 @test3(i32 signext %i, i32 (i32)* nocapture %Func, i32 (i32)*
; CHECK-LABEL: test3:
; CHECK: std 2, 24(1)
; CHECK-NOT: std 2, 24(1)
; AIX64-LABEL: test3:
; AIX64-COUNT-3: std 2, 40(1)
; AIX32-LABEL: test3:
; AIX32-COUNT-3: stw 2, 20(1)
entry:
%tobool = icmp eq i32 %i, 0
br i1 %tobool, label %if.else, label %if.then
@ -62,6 +87,13 @@ define signext i32 @test4(i32 signext %i, i32 (i32)* nocapture %Func, i32 (i32)*
; CHECK: std 2, 24(1)
; CHECK-NOT: std 2, 24(1)
; AIX64-LABEL: test4:
; AIX64: std 2, 40(1)
; AIX64-NOT: std 2, 40(1)
; AIX32-LABEL: test4:
; AIX32: stw 2, 20(1)
; AIX32-NOT: std 2, 20(1)
entry:
%call = tail call signext i32 %Func(i32 signext %i)
%tobool = icmp eq i32 %i, 0
@ -87,6 +119,11 @@ entry:
; CHECK-LABEL: test5:
; CHECK: std 2, 24(1)
; AIX64-LABEL: test5:
; AIX64: std 2, 40(1)
; AIX32-LABEL: test5:
; AIX32: stw 2, 20(1)
%tobool = icmp eq i32 %i, 0
br i1 %tobool, label %if.end, label %if.then
@ -108,6 +145,13 @@ entry:
; CHECK: std 2, 24(1)
; CHECK: std 2, 24(1)
; AIX64-LABEL: test6:
; AIX64: std 2, 40(1)
; AIX64: std 2, 40(1)
; AIX32-LABEL: test6:
; AIX32: stw 2, 20(1)
; AIX32: stw 2, 20(1)
%conv = sext i32 %i to i64
%0 = alloca i8, i64 %conv, align 16
%1 = bitcast i8* %0 to i32*