[llvm-commits] [llvm] r135202 - /llvm/trunk/lib/Target/X86/X86FrameLowering.cpp

Bill Wendling isanbard at gmail.com
Thu Jul 14 15:01:34 PDT 2011


Author: void
Date: Thu Jul 14 17:01:34 2011
New Revision: 135202

URL: http://llvm.org/viewvc/llvm-project?rev=135202&view=rev
Log:
* Redo the permutation encoding for frameless stacks to be more like what the
  unwind library expects.
* Comment the permutation encoding for frameless stacks.

Modified:
    llvm/trunk/lib/Target/X86/X86FrameLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=135202&r1=135201&r2=135202&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Thu Jul 14 17:01:34 2011
@@ -1031,45 +1031,67 @@
   }
 }
 
+/// permuteEncode - Create the permutation encoding used with frameless
+/// stacks. It is passed the number of registers to be saved and an array of the
+/// registers saved.
 static uint32_t permuteEncode(unsigned SavedCount, unsigned Registers[6]) {
-   uint32_t RenumRegs[6];
-   for (int i = 6 - SavedCount; i < 6; ++i) {
-       int countless = 0;
-       for (int j = 6 - SavedCount; j < i; ++j)
-           if (Registers[j] < Registers[i])
-               ++countless;
-
-       RenumRegs[i] = Registers[i] - countless - 1;
-   }
-
-   uint32_t permutationEncoding = 0;
-   switch (SavedCount) {
-   case 6:
-     permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] 
-                            + 6 * RenumRegs[2] +  2 * RenumRegs[3] 
-                            +     RenumRegs[4];
-     break;
-   case 5:
-     permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] 
-                            + 6 * RenumRegs[3] +  2 * RenumRegs[4] 
-                            +     RenumRegs[5];
-     break;
-   case 4:
-     permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] 
-                           + 3 * RenumRegs[4] +      RenumRegs[5];
-     break;
-   case 3:
-     permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] 
-                               + RenumRegs[5];
-     break;
-   case 2:
-     permutationEncoding |=  5 * RenumRegs[4] + RenumRegs[5];
-     break;
-   case 1:
-     permutationEncoding |= RenumRegs[5];
-     break;
-   }
-   return permutationEncoding;
+  // The saved registers are numbered from 1 to 6. In order to encode the order
+  // in which they were saved, we re-number them according to their place in the
+  // register order. The re-numbering is relative to the last re-numbered
+  // register. E.g., if we have registers {6, 2, 4, 5} saved in that order:
+  //
+  //    Orig  Re-Num
+  //    ----  ------
+  //     6       6
+  //     2       2
+  //     4       3
+  //     5       3
+  //
+  bool Used[7] = { false, false, false, false, false, false, false };
+  uint32_t RenumRegs[6];
+  for (unsigned I = 0; I < SavedCount; ++I) {
+    uint32_t Renum = 0;
+    for (unsigned U = 1; U < 7; ++U) {
+      if (U == Registers[I])
+        break;
+      if (!Used[U])
+        ++Renum;
+    }
+
+    Used[Registers[I]] = true;
+    RenumRegs[I] = Renum;
+  }
+
+  // Take the renumbered values and encode them into a 10-bit number.
+  uint32_t permutationEncoding = 0;
+  switch (SavedCount) {
+  case 6:
+    permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
+                           + 6 * RenumRegs[2] +  2 * RenumRegs[3]
+                           +     RenumRegs[4];
+    break;
+  case 5:
+    permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
+                           + 6 * RenumRegs[2] +  2 * RenumRegs[3]
+                           +     RenumRegs[4];
+    break;
+  case 4:
+    permutationEncoding |= 60 * RenumRegs[0] + 12 * RenumRegs[1]
+                          + 3 * RenumRegs[2] +      RenumRegs[3];
+    break;
+  case 3:
+    permutationEncoding |= 20 * RenumRegs[0] + 4 * RenumRegs[1]
+                              + RenumRegs[2];
+    break;
+  case 2:
+    permutationEncoding |=  5 * RenumRegs[0] +     RenumRegs[1];
+    break;
+  case 1:
+    permutationEncoding |=      RenumRegs[0];
+    break;
+  }
+
+  return permutationEncoding;
 }
 
 uint32_t X86FrameLowering::
@@ -1104,12 +1126,12 @@
       if (Src.getReg() != MachineLocation::VirtualFP) {
         // DW_CFA_def_cfa
         assert(FramePointerReg == -1 &&"Defining more than one frame pointer?");
-        FramePointerReg = Src.getReg();
-        if (TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::EBP &&
-            TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::RBP)
+        if (TRI->getLLVMRegNum(Src.getReg(), IsEH) != X86::EBP &&
+            TRI->getLLVMRegNum(Src.getReg(), IsEH) != X86::RBP)
           // The frame pointer isn't EBP/RBP. Cannot make unwind information
           // compact.
           return 0;
+        FramePointerReg = TRI->getCompactUnwindRegNum(Src.getReg(), IsEH);
       } // else DW_CFA_def_cfa_offset
 
       if (IsRelative)
@@ -1123,12 +1145,19 @@
     if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
       // DW_CFA_def_cfa_register
       assert(FramePointerReg == -1 && "Defining more than one frame pointer?");
-      FramePointerReg = Dst.getReg();
-      if (TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::EBP &&
-          TRI->getLLVMRegNum(FramePointerReg, IsEH) != X86::RBP)
+
+      if (TRI->getLLVMRegNum(Dst.getReg(), IsEH) != X86::EBP &&
+          TRI->getLLVMRegNum(Dst.getReg(), IsEH) != X86::RBP)
         // The frame pointer isn't EBP/RBP. Cannot make unwind information
         // compact.
         return 0;
+
+      FramePointerReg = TRI->getCompactUnwindRegNum(Dst.getReg(), IsEH);
+      if (SavedRegIdx != 1 || SavedRegs[0] != unsigned(FramePointerReg))
+        return 0;
+
+      SavedRegs[0] = 0;
+      SavedRegIdx = 0;
       continue;
     }
 





More information about the llvm-commits mailing list