This is an archive of the discontinued LLVM Phabricator instance.

PowerPC: Mark super regs of reserved regs reserved.
ClosedPublic

Authored by MatzeB on Jan 23 2017, 3:39 PM.

Details

Summary

When a register like R1 is reserved, X1 should be reserved as well. This
was already done "manually" when 64bit code was enabled, however using
the markSuperRegs() function on the base register is more convenient and
allows to use the checksAllSuperRegsMarked() function even in 32bit mode
to avoid accidental breakage in the future. markSuperRegs() is used even
on registers without superregs for consistency.

And more importantly for me: It allows me to make progress in
https://reviews.llvm.org/D28881

Diff Detail

Repository
rL LLVM

Event Timeline

MatzeB created this revision.Jan 23 2017, 3:39 PM
hfinkel accepted this revision.Jan 23 2017, 4:18 PM

LGTM

This revision is now accepted and ready to land.Jan 23 2017, 4:18 PM
This revision was automatically updated to reflect the committed changes.
nemanjai added inline comments.Jan 24 2017, 5:02 AM
llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
254

I think it would be nice to have a function to do this just like there's a function to do the reverse. Maybe unmarkSuperRegs()? That way we can accomplish both setting the bits and resetting them for all the super registers with just a single call.

Is there a specific reason such a function was not added when markSuperRegs() was added?

MatzeB added inline comments.Jan 24 2017, 12:39 PM
llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
254

There simply is no other user for this functionality yet. And actually you even could rewrite the PowerPC code so it doesn't first set and later clear the reserved bits (IMO even looks slightly cleaner than the current code):

diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 5afe412..aad9139 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -234,30 +234,21 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {

   // The SVR4 ABI reserves r2 and r13
   if (Subtarget.isSVR4ABI()) {
-    markSuperRegs(Reserved, PPC::R2);  // System-reserved register
+    // We only reserve r2 if we need to use the TOC pointer. If we have no
+    // explicit uses of the TOC pointer (meaning we're a leaf function with
+    // no constant-pool loads, etc.) and we have no potential uses inside an
+    // inline asm block, then we can treat r2 has an ordinary callee-saved
+    // register.
+    const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+    if (!TM.isPPC64() || FuncInfo->usesTOCBasePtr() || MF.hasInlineAsm())
+      markSuperRegs(Reserved, PPC::R2);  // System-reserved register
     markSuperRegs(Reserved, PPC::R13); // Small Data Area pointer register
   }

-  if (TM.isPPC64()) {
-    // On PPC64, r13 is the thread pointer. Never allocate this register.
+  // On PPC64, r13 is the thread pointer. Never allocate this register.
+  if (TM.isPPC64())
     markSuperRegs(Reserved, PPC::R13);

-    // The 64-bit SVR4 ABI reserves r2 for the TOC pointer.
-    if (Subtarget.isSVR4ABI()) {
-      // We only reserve r2 if we need to use the TOC pointer. If we have no
-      // explicit uses of the TOC pointer (meaning we're a leaf function with
-      // no constant-pool loads, etc.) and we have no potential uses inside an
-      // inline asm block, then we can treat r2 has an ordinary callee-saved
-      // register.
-      const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
-      if (!FuncInfo->usesTOCBasePtr() && !MF.hasInlineAsm()) {
-        for (MCSuperRegIterator Super(PPC::R2, this, true); Super.isValid();
-             ++Super)
-          Reserved.reset(*Super);
-      }
-    }
-  }
-
   if (TFI->needsFP(MF))
     markSuperRegs(Reserved, PPC::R31);
hfinkel added inline comments.Jan 24 2017, 3:54 PM
llvm/trunk/lib/Target/PowerPC/PPCRegisterInfo.cpp
254

I agree, this is nicer (LGTM).