[llvm] r213492 - [PowerPC] ELFv2 explicit CFI for CR fields

Ulrich Weigand ulrich.weigand at de.ibm.com
Sun Jul 20 17:03:18 PDT 2014


Author: uweigand
Date: Sun Jul 20 19:03:18 2014
New Revision: 213492

URL: http://llvm.org/viewvc/llvm-project?rev=213492&view=rev
Log:
[PowerPC] ELFv2 explicit CFI for CR fields

This is a minor improvement in the ELFv2 ABI.   In ELFv1, DWARF CFI
would represent a saved CR word (holding CR fields CR2, CR3, and CR4)
using just a single CFI record refering to CR2.   In ELFv2 instead,
each of the CR fields is represented by its own CFI record.  The
advantage is that the compiler can now chose to save just a single
(or two) CR fields instead of all of them, if those are the only ones
that actually need saving.  That can lead to more efficient code using
mf(o)crf instead of the (slow) mfcr instruction.

Note that this patch does not (yet) implement this more efficient
code generation, but it does implement the part that is required to
be ABI compliant: creating multiple CFI records if multiple CR fields
are saved.

Reviewed by Hal Finkel.

Added:
    llvm/trunk/test/CodeGen/PowerPC/ppc64le-crsave.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp?rev=213492&r1=213491&r2=213492&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFrameLowering.cpp Sun Jul 20 19:03:18 2014
@@ -514,6 +514,7 @@ void PPCFrameLowering::emitPrologue(Mach
   // Get the ABI.
   bool isDarwinABI = Subtarget.isDarwinABI();
   bool isSVR4ABI = Subtarget.isSVR4ABI();
+  bool isELFv2ABI = Subtarget.isELFv2ABI();
   assert((isDarwinABI || isSVR4ABI) &&
          "Currently only Darwin and SVR4 ABIs are supported for PowerPC.");
 
@@ -627,6 +628,9 @@ void PPCFrameLowering::emitPrologue(Mach
          "Prologue CR saving supported only in 64-bit mode");
 
   if (!MustSaveCRs.empty()) { // 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.
     MachineInstrBuilder MIB =
       BuildMI(MBB, MBBI, dl, TII.get(PPC::MFCR8), TempReg);
     for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
@@ -795,8 +799,12 @@ void PPCFrameLowering::emitPrologue(Mach
       // For 64-bit SVR4 when we have spilled CRs, the spill location
       // is SP+8, not a frame-relative slot.
       if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
+        // In the ELFv1 ABI, only CR2 is noted in CFI and stands in for
+        // the whole CR word.  In the ELFv2 ABI, every CR that was
+        // actually saved gets its own CFI record.
+        unsigned CRReg = isELFv2ABI? Reg : (unsigned) PPC::CR2;
         unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
-            nullptr, MRI->getDwarfRegNum(PPC::CR2, true), 8));
+            nullptr, MRI->getDwarfRegNum(CRReg, true), 8));
         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
             .addCFIIndex(CFIIndex);
         continue;

Added: llvm/trunk/test/CodeGen/PowerPC/ppc64le-crsave.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/ppc64le-crsave.ll?rev=213492&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/ppc64le-crsave.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/ppc64le-crsave.ll Sun Jul 20 19:03:18 2014
@@ -0,0 +1,28 @@
+; RUN: llc < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-n32:64"
+target triple = "powerpc64le-unknown-linux-gnu"
+
+ at _ZTIi = external constant i8*
+declare i8* @__cxa_allocate_exception(i64)
+declare void @__cxa_throw(i8*, i8*, i8*)
+
+define void @crsave() {
+entry:
+  call void asm sideeffect "", "~{cr2}"()
+  call void asm sideeffect "", "~{cr3}"()
+  call void asm sideeffect "", "~{cr4}"()
+
+  %exception = call i8* @__cxa_allocate_exception(i64 4)
+  %0 = bitcast i8* %exception to i32*
+  store i32 0, i32* %0
+  call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+  unreachable
+
+return:                                           ; No predecessors!
+  ret void
+}
+; CHECK-LABEL: @crsave
+; CHECK: .cfi_offset cr2, 8
+; CHECK: .cfi_offset cr3, 8
+; CHECK: .cfi_offset cr4, 8
+





More information about the llvm-commits mailing list