[llvm] r266038 - [PPC64] Use mfocrf in prologue when we only need to save 1 nonvolatile CR field

Chuang-Yu Cheng via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 20:04:44 PDT 2016


Author: cycheng
Date: Mon Apr 11 22:04:44 2016
New Revision: 266038

URL: http://llvm.org/viewvc/llvm-project?rev=266038&view=rev
Log:
[PPC64] Use mfocrf in prologue when we only need to save 1 nonvolatile CR field

In the ELFv2 ABI, we are not required to save all CR fields. If only one
nonvolatile CR field is clobbered, use mfocrf instead of mfcr to
selectively save the field, because mfocrf has short latency compares to
mfcr.

Thanks Nemanja's invaluable hint!
Reviewers: nemanjai tjablin hfinkel kbarton

http://reviews.llvm.org/D17749

Modified:
    llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
    llvm/trunk/test/CodeGen/PowerPC/crsave.ll
    llvm/trunk/test/CodeGen/PowerPC/pr26690.ll

Modified: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp?rev=266038&r1=266037&r2=266038&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp Mon Apr 11 22:04:44 2016
@@ -838,11 +838,15 @@ void PPCFrameLowering::emitPrologue(Mach
   // If we need to spill the CR and the LR but we don't have two separate
   // registers available, we must spill them one at a time
   if (MustSaveCR && SingleScratchReg && MustSaveLR) {
-    // FIXME: In the ELFv2 ABI, we are not required to save all CR fields.
-    // If only one or two CR fields are clobbered, it could be more
-    // efficient to use mfocrf to selectively save just those fields.
+    // In the ELFv2 ABI, we are not required to save all CR fields.
+    // If only one or two CR fields are clobbered, it is more efficient to use
+    // mfocrf to selectively save just those fields, because mfocrf has short
+    // latency compares to mfcr.
+    unsigned MfcrOpcode = PPC::MFCR8;
+    if (isELFv2ABI && MustSaveCRs.size() == 1)
+      MfcrOpcode = PPC::MFOCRF8;
     MachineInstrBuilder MIB =
-      BuildMI(MBB, MBBI, dl, TII.get(PPC::MFCR8), TempReg);
+      BuildMI(MBB, MBBI, dl, TII.get(MfcrOpcode), TempReg);
     for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
       MIB.addReg(MustSaveCRs[i], RegState::ImplicitKill);
     BuildMI(MBB, MBBI, dl, TII.get(PPC::STW8))
@@ -856,11 +860,15 @@ void PPCFrameLowering::emitPrologue(Mach
 
   if (MustSaveCR &&
       !(SingleScratchReg && MustSaveLR)) { // will only occur for PPC64
-    // FIXME: In the ELFv2 ABI, we are not required to save all CR fields.
-    // If only one or two CR fields are clobbered, it could be more
-    // efficient to use mfocrf to selectively save just those fields.
+    // In the ELFv2 ABI, we are not required to save all CR fields.
+    // If only one or two CR fields are clobbered, it is more efficient to use
+    // mfocrf to selectively save just those fields, because mfocrf has short
+    // latency compares to mfcr.
+    unsigned MfcrOpcode = PPC::MFCR8;
+    if (isELFv2ABI && MustSaveCRs.size() == 1)
+      MfcrOpcode = PPC::MFOCRF8;
     MachineInstrBuilder MIB =
-      BuildMI(MBB, MBBI, dl, TII.get(PPC::MFCR8), TempReg);
+      BuildMI(MBB, MBBI, dl, TII.get(MfcrOpcode), TempReg);
     for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
       MIB.addReg(MustSaveCRs[i], RegState::ImplicitKill);
   }

Modified: llvm/trunk/test/CodeGen/PowerPC/crsave.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/crsave.ll?rev=266038&r1=266037&r2=266038&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/crsave.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/crsave.ll Mon Apr 11 22:04:44 2016
@@ -1,5 +1,6 @@
 ; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc-unknown-linux-gnu -mcpu=g5 < %s | FileCheck %s -check-prefix=PPC32
 ; RUN: llc -O0 -mtriple=powerpc64-unknown-linux-gnu -mcpu=g5 < %s | FileCheck %s -check-prefix=PPC64
+; RUN: llc -O0 -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC64-ELFv2
 
 declare void @foo()
 
@@ -60,3 +61,22 @@ entry:
 ; PPC64: mtocrf 16, 12
 ; PPC64: mtocrf 8, 12
 
+; Generate mfocrf in prologue when we need to save 1 nonvolatile CR field
+define void @cloberOneNvCrField() {
+entry:
+  tail call void asm sideeffect "# clobbers", "~{cr2}"()
+  ret void
+
+; PPC64-ELFv2-LABEL: @cloberOneNvCrField
+; PPC64-ELFv2: mfocrf [[REG1:[0-9]+]], 32
+}
+
+; Generate mfcr in prologue when we need to save all nonvolatile CR field
+define void @cloberAllNvCrField() {
+entry:
+  tail call void asm sideeffect "# clobbers", "~{cr2},~{cr3},~{cr4}"()
+  ret void
+
+; PPC64-ELFv2-LABEL: @cloberAllNvCrField
+; PPC64-ELFv2: mfcr [[REG1:[0-9]+]]
+}

Modified: llvm/trunk/test/CodeGen/PowerPC/pr26690.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/pr26690.ll?rev=266038&r1=266037&r2=266038&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/pr26690.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/pr26690.ll Mon Apr 11 22:04:44 2016
@@ -101,7 +101,7 @@ if.end16:
   ret i32 2
 }
 
-; CHECK: mfcr {{[0-9]+}}
+; CHECK: mfocrf {{[0-9]+}}
 
 !llvm.ident = !{!0}
 




More information about the llvm-commits mailing list