Get allocation orders from RegisterClassInfo when possible.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Mon, 6 Jun 2011 21:02:04 +0000 (21:02 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Mon, 6 Jun 2011 21:02:04 +0000 (21:02 +0000)
Only target-dependent hints require callbacks. The RCI allocation order
has CSR aliases last according to their order of appearance in the
getCalleeSavedRegs list. This can depend on the calling convention.

This way, AllocationOrder::next doesn't have to check for reserved
registers, and CSRs are always allocated last, even with weird calling
conventions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132690 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AllocationOrder.cpp
lib/CodeGen/AllocationOrder.h

index 0b7cd4950e1b18c60cb07cd4ae685302b5d7a537..a8ee2b6357c3677c530d9cebda82a27697f82b1f 100644 (file)
@@ -25,7 +25,7 @@ using namespace llvm;
 AllocationOrder::AllocationOrder(unsigned VirtReg,
                                  const VirtRegMap &VRM,
                                  const RegisterClassInfo &RegClassInfo)
-  : Pos(0), RCI(RegClassInfo) {
+  : Begin(0), End(0), Pos(0), RCI(RegClassInfo), OwnedBegin(false) {
   const TargetRegisterClass *RC = VRM.getRegInfo().getRegClass(VirtReg);
   std::pair<unsigned, unsigned> HintPair =
     VRM.getRegInfo().getRegAllocationHint(VirtReg);
@@ -37,14 +37,37 @@ AllocationOrder::AllocationOrder(unsigned VirtReg,
   if (TargetRegisterInfo::isVirtualRegister(Hint))
     Hint = VRM.getPhys(Hint);
 
-  // The remaining allocation order may depend on the hint.
-  tie(Begin, End) = VRM.getTargetRegInfo()
-        .getAllocationOrder(RC, HintPair.first, Hint, VRM.getMachineFunction());
+  // The first hint pair component indicates a target-specific hint.
+  if (HintPair.first) {
+    const TargetRegisterInfo &TRI = VRM.getTargetRegInfo();
+    // The remaining allocation order may depend on the hint.
+    const unsigned *B, *E;
+    tie(B, E) = TRI.getAllocationOrder(RC, HintPair.first, Hint,
+                                       VRM.getMachineFunction());
 
-  // Target-dependent hints require resolution.
-  if (HintPair.first)
-    Hint = VRM.getTargetRegInfo().ResolveRegAllocHint(HintPair.first, Hint,
-                                                      VRM.getMachineFunction());
+    // Empty allocation order?
+    if (B == E)
+      return;
+
+    // Copy the allocation order with reserved registers removed.
+    OwnedBegin = true;
+    unsigned *P = new unsigned[E - B];
+    Begin = P;
+    for (; B != E; ++B)
+      if (!RCI.isReserved(*B))
+        *P++ = *B;
+    End = P;
+
+    // Target-dependent hints require resolution.
+    Hint = TRI.ResolveRegAllocHint(HintPair.first, Hint,
+                                   VRM.getMachineFunction());
+  } else {
+    // If there is no hint or just a normal hint, use the cached allocation
+    // order from RegisterClassInfo.
+    ArrayRef<unsigned> O = RCI.getOrder(RC);
+    Begin = O.begin();
+    End = O.end();
+  }
 
   // The hint must be a valid physreg for allocation.
   if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) ||
@@ -52,18 +75,7 @@ AllocationOrder::AllocationOrder(unsigned VirtReg,
     Hint = 0;
 }
 
-unsigned AllocationOrder::next() {
-  // First take the hint.
-  if (!Pos) {
-    Pos = Begin;
-    if (Hint)
-      return Hint;
-  }
-  // Then look at the order from TRI.
-  while(Pos != End) {
-    unsigned Reg = *Pos++;
-    if (Reg != Hint && !RCI.isReserved(Reg))
-      return Reg;
-  }
-  return 0;
+AllocationOrder::~AllocationOrder() {
+  if (OwnedBegin)
+    delete [] Begin;
 }
index 4742e8e1968e54f08dc05c961e52223b2db62e57..d1e48a1f2e962a9273af336598900ab007b42554 100644 (file)
@@ -28,6 +28,7 @@ class AllocationOrder {
   const unsigned *Pos;
   const RegisterClassInfo &RCI;
   unsigned Hint;
+  bool OwnedBegin;
 public:
 
   /// AllocationOrder - Create a new AllocationOrder for VirtReg.
@@ -39,10 +40,26 @@ public:
                   const VirtRegMap &VRM,
                   const RegisterClassInfo &RegClassInfo);
 
+  ~AllocationOrder();
+
   /// next - Return the next physical register in the allocation order, or 0.
   /// It is safe to call next again after it returned 0.
   /// It will keep returning 0 until rewind() is called.
-  unsigned next();
+  unsigned next() {
+    // First take the hint.
+    if (!Pos) {
+      Pos = Begin;
+      if (Hint)
+        return Hint;
+    }
+    // Then look at the order from TRI.
+    while (Pos != End) {
+      unsigned Reg = *Pos++;
+      if (Reg != Hint)
+        return Reg;
+    }
+    return 0;
+  }
 
   /// rewind - Start over from the beginning.
   void rewind() { Pos = 0; }