summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2009-04-30 21:23:32 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2009-04-30 21:23:32 +0000
commite651f25a7b3e6e0ef955a5f325ffb2ddcce51019 (patch)
treeff49e6c9b15bf1a1991acf84f3a7453c968da413 /llvm/lib
parentc8124976af23968a50c94dff21783280e1fd004c (diff)
downloadbcm5719-llvm-e651f25a7b3e6e0ef955a5f325ffb2ddcce51019.tar.gz
bcm5719-llvm-e651f25a7b3e6e0ef955a5f325ffb2ddcce51019.zip
getCommonSubClass() - Calculate the largest common sub-class of two register
classes. This is implemented as a function rather than a method on TargetRegisterClass because it is symmetric in its arguments. llvm-svn: 70512
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/TargetRegisterInfo.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/Target/TargetRegisterInfo.cpp b/llvm/lib/Target/TargetRegisterInfo.cpp
index eca074cc743..d075c5787b7 100644
--- a/llvm/lib/Target/TargetRegisterInfo.cpp
+++ b/llvm/lib/Target/TargetRegisterInfo.cpp
@@ -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;
+}
OpenPOWER on IntegriCloud