summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-07 22:57:55 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-07 22:57:55 +0000
commit98595b5a617145d2b6a4fdca7df4cdbecdd32a1c (patch)
tree083d3f6fcb30e7a457c11dddda3d58afdc6761de /llvm/lib/CodeGen
parent54d5f6489f9cf73a76e835ec9d6a8801fd31527c (diff)
downloadbcm5719-llvm-98595b5a617145d2b6a4fdca7df4cdbecdd32a1c.tar.gz
bcm5719-llvm-98595b5a617145d2b6a4fdca7df4cdbecdd32a1c.zip
Coalesce subreg-subreg copies.
At least some of them: %vreg1:sub_16bit = COPY %vreg2:sub_16bit; GR64:%vreg1, GR32: %vreg2 Previously, we couldn't figure out that the above copy could be eliminated by coalescing %vreg2 with %vreg1:sub_32bit. The new getCommonSuperRegClass() hook makes it possible. This is not very useful yet since the unmodified part of the destination register usually interferes with the source register. The coalescer needs to understand sub-register interference checking first. llvm-svn: 156334
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp39
1 files changed, 25 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 567ce1940c9..8ab927ac357 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -258,24 +258,35 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) {
}
} else {
// Both registers are virtual.
+ const TargetRegisterClass *SrcRC = MRI.getRegClass(Src);
+ const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
// Both registers have subreg indices.
if (SrcSub && DstSub) {
- // For now we only handle the case of identical indices in commensurate
- // registers: Dreg:ssub_1 + Dreg:ssub_1 -> Dreg
- // FIXME: Handle Qreg:ssub_3 + Dreg:ssub_1 as QReg:dsub_1 + Dreg.
- if (SrcSub != DstSub)
+ unsigned SrcPre, DstPre;
+ NewRC = TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub,
+ SrcPre, DstPre);
+ if (!NewRC)
return false;
- const TargetRegisterClass *SrcRC = MRI.getRegClass(Src);
- const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
- if (!TRI.getCommonSubClass(DstRC, SrcRC))
+
+ // We cannot handle the case where both Src and Dst would be a
+ // sub-register. Yet.
+ if (SrcPre && DstPre) {
+ DEBUG(dbgs() << "\tCannot handle " << NewRC->getName()
+ << " with subregs " << TRI.getSubRegIndexName(SrcPre)
+ << " and " << TRI.getSubRegIndexName(DstPre) << '\n');
return false;
- SrcSub = DstSub = 0;
+ }
+
+ // One of these will be 0, so one register is a sub-register of the other.
+ SrcSub = DstPre;
+ DstSub = SrcPre;
}
// There can be no SrcSub.
if (SrcSub) {
std::swap(Src, Dst);
+ std::swap(SrcRC, DstRC);
DstSub = SrcSub;
SrcSub = 0;
assert(!Flipped && "Unexpected flip");
@@ -283,12 +294,12 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) {
}
// Find the new register class.
- const TargetRegisterClass *SrcRC = MRI.getRegClass(Src);
- const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
- if (DstSub)
- NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
- else
- NewRC = TRI.getCommonSubClass(DstRC, SrcRC);
+ if (!NewRC) {
+ if (DstSub)
+ NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
+ else
+ NewRC = TRI.getCommonSubClass(DstRC, SrcRC);
+ }
if (!NewRC)
return false;
CrossClass = NewRC != DstRC || NewRC != SrcRC;
OpenPOWER on IntegriCloud