From: Jakob Stoklund Olesen Date: Thu, 30 Apr 2009 21:23:32 +0000 (+0000) Subject: getCommonSubClass() - Calculate the largest common sub-class of two register X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=ba67d87fe4f0ec9a3d9729f1b0f3b70d85ac8357;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70512 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 16cec2d647e..fbb8ffe8128 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -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 diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp index eca074cc743..d075c5787b7 100644 --- a/lib/Target/TargetRegisterInfo.cpp +++ b/lib/Target/TargetRegisterInfo.cpp @@ -100,3 +100,45 @@ TargetRegisterInfo::getInitialFrameState(std::vector &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; +}