getCommonSubClass() - Calculate the largest common sub-class of two register
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 30 Apr 2009 21:23:32 +0000 (21:23 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 30 Apr 2009 21:23:32 +0000 (21:23 +0000)
classes.

This is implemented as a function rather than a method on TargetRegisterClass
because it is symmetric in its arguments.

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

include/llvm/Target/TargetRegisterInfo.h
lib/Target/TargetRegisterInfo.cpp

index 16cec2d647e867aaf37d0d95ee5efd045fb3d44b..fbb8ffe8128709ffd001e108758c9a3ff5abce28 100644 (file)
@@ -254,6 +254,10 @@ public:
   int getCopyCost() const { return CopyCost; }
 };
 
+/// getCommonSubClass - find the largest common subclass of A and B. Return NULL
+/// if there is no common subclass.
+const TargetRegisterClass *getCommonSubClass(const TargetRegisterClass *A,
+                                             const TargetRegisterClass *B);
 
 /// TargetRegisterInfo base class - We assume that the target defines a static
 /// array of TargetRegisterDesc objects that represent all of the machine
index eca074cc7439327f45eae036185b4d5ea9392772..d075c5787b71c9e60399dc0e0dd8eac109e213ca 100644 (file)
@@ -100,3 +100,45 @@ TargetRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const
   // Default is to do nothing.
 }
 
+const TargetRegisterClass *
+llvm::getCommonSubClass(const TargetRegisterClass *A,
+                        const TargetRegisterClass *B) {
+  // First take care of the trivial cases
+  if (A == B)
+    return A;
+  if (!A || !B)
+    return 0;
+
+  // If B is a subclass of A, it will be handled in the loop below
+  if (B->hasSubClass(A))
+    return A;
+
+  const TargetRegisterClass *Best = 0;
+  for (TargetRegisterClass::sc_iterator I = A->subclasses_begin();
+       const TargetRegisterClass *X = *I; ++I) {
+    if (X == B)
+      return B;                 // B is a subclass of A
+
+    // X must be a common subclass of A and B
+    if (!B->hasSubClass(X))
+      continue;
+
+    // A superclass is definitely better.
+    if (!Best || Best->hasSuperClass(X)) {
+      Best = X;
+      continue;
+    }
+
+    // A subclass is definitely worse
+    if (Best->hasSubClass(X))
+      continue;
+
+    // Best and *I have no super/sub class relation - pick the larger class, or
+    // the smaller spill size.
+    int nb = std::distance(Best->begin(), Best->end());
+    int ni = std::distance(X->begin(), X->end());
+    if (ni>nb || (ni==nb && X->getSize() < Best->getSize()))
+      Best = X;
+  }
+  return Best;
+}