summaryrefslogtreecommitdiff
path: root/lib/Target/TargetRegisterInfo.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-07 19:14:58 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-07 19:14:58 +0000
commitfd87839a4888840ab5718fd116ab169ac04126af (patch)
tree753573b52cf749d258ce5ebbaee7ffea4e60c133 /lib/Target/TargetRegisterInfo.cpp
parent42726835e38dd1b41c587187ddd04f5c9276ff08 (diff)
downloadllvm-fd87839a4888840ab5718fd116ab169ac04126af.tar.gz
llvm-fd87839a4888840ab5718fd116ab169ac04126af.tar.bz2
llvm-fd87839a4888840ab5718fd116ab169ac04126af.tar.xz
Add TRI::getCommonSuperRegClass().
This function is a generalization of getMatchingSuperRegClass() to the symmetric case where both sides are using a sub-register index. It will find a super-register class and sub-register indexes that make this diagram commute: PreA SuperRC ----------> RCA | | | | PreB | | SubA | | | | V V RCB ----------> SubRC SubB This can be used to coalesce copies like: %vreg1:sub16 = COPY %vreg2:sub16; GR64:%vreg1, GR32: %vreg2 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156317 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/TargetRegisterInfo.cpp')
-rw-r--r--lib/Target/TargetRegisterInfo.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp
index d5518ea2c1..532e6d2318 100644
--- a/lib/Target/TargetRegisterInfo.cpp
+++ b/lib/Target/TargetRegisterInfo.cpp
@@ -122,6 +122,16 @@ BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF,
return Allocatable;
}
+static inline
+const TargetRegisterClass *firstCommonClass(const uint32_t *A,
+ const uint32_t *B,
+ const TargetRegisterInfo *TRI) {
+ for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; I += 32)
+ if (unsigned Common = *A++ & *B++)
+ return TRI->getRegClass(I + CountTrailingZeros_32(Common));
+ return 0;
+}
+
const TargetRegisterClass *
TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A,
const TargetRegisterClass *B) const {
@@ -173,3 +183,64 @@ TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
return getRegClass(Base + CountTrailingZeros_32(Common));
return 0;
}
+
+const TargetRegisterClass *TargetRegisterInfo::
+getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
+ const TargetRegisterClass *RCB, unsigned SubB,
+ unsigned &PreA, unsigned &PreB) const {
+ assert(RCA && SubA && RCB && SubB && "Invalid arguments");
+
+ // Search all pairs of sub-register indices that project into RCA and RCB
+ // respectively. This is quadratic, but usually the sets are very small. On
+ // most targets like X86, there will only be a single sub-register index
+ // (e.g., sub_16bit projecting into GR16).
+ //
+ // The worst case is a register class like DPR on ARM.
+ // We have indices dsub_0..dsub_7 projecting into that class.
+ //
+ // It is very common that one register class is a sub-register of the other.
+ // Arrange for RCA to be the larger register so the answer will be found in
+ // the first iteration. This makes the search linear for the most common
+ // case.
+ const TargetRegisterClass *BestRC = 0;
+ unsigned *BestPreA = &PreA;
+ unsigned *BestPreB = &PreB;
+ if (RCA->getSize() < RCB->getSize()) {
+ std::swap(RCA, RCB);
+ std::swap(BestPreA, BestPreB);
+ }
+
+ // Also terminate the search one we have found a register class as small as
+ // RCA.
+ unsigned MinSize = RCA->getSize();
+
+ for (SuperRegClassIterator IA(RCA, this, true); IA.isValid(); ++IA) {
+ unsigned FinalA = composeSubRegIndices(IA.getSubReg(), SubA);
+ for (SuperRegClassIterator IB(RCB, this, true); IB.isValid(); ++IB) {
+ // Check if a common super-register class exists for this index pair.
+ const TargetRegisterClass *RC =
+ firstCommonClass(IA.getMask(), IB.getMask(), this);
+ if (!RC || RC->getSize() < MinSize)
+ continue;
+
+ // The indexes must compose identically: PreA+SubA == PreB+SubB.
+ unsigned FinalB = composeSubRegIndices(IB.getSubReg(), SubB);
+ if (FinalA != FinalB)
+ continue;
+
+ // Is RC a better candidate than BestRC?
+ if (BestRC && RC->getSize() >= BestRC->getSize())
+ continue;
+
+ // Yes, RC is the smallest super-register seen so far.
+ BestRC = RC;
+ *BestPreA = IA.getSubReg();
+ *BestPreB = IB.getSubReg();
+
+ // Bail early if we reached MinSize. We won't find a better candidate.
+ if (BestRC->getSize() == MinSize)
+ return BestRC;
+ }
+ }
+ return BestRC;
+}