From 8df08017d81ef3749acdc3234e3f33c15a6d0def Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 24 Jun 2010 16:19:28 +0000 Subject: [PATCH] Be more strict about subreg-to-subreg copies in CoalescerPair. Also keep track of the original DstREg before subregister adjustments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106753 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/RegisterCoalescer.h | 16 +++++++++++++++- lib/CodeGen/RegisterCoalescer.cpp | 20 +++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/include/llvm/CodeGen/RegisterCoalescer.h b/include/llvm/CodeGen/RegisterCoalescer.h index e3d3e796336..7aec10ccb38 100644 --- a/include/llvm/CodeGen/RegisterCoalescer.h +++ b/include/llvm/CodeGen/RegisterCoalescer.h @@ -165,9 +165,15 @@ namespace llvm { /// virtual register. unsigned subIdx_; + /// origDstReg_ - dstReg_ without subreg adjustments. + unsigned origDstReg_; + /// partial_ - True when the original copy was a partial subregister copy. bool partial_; + /// crossClass_ - True when both regs are virtual, and newRC is constrained. + bool crossClass_; + /// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy /// instruction. bool flipped_; @@ -186,7 +192,8 @@ namespace llvm { public: CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri) : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0), - partial_(false), flipped_(false), newRC_(0) {} + origDstReg_(0), partial_(false), crossClass_(false), flipped_(false), + newRC_(0) {} /// setRegisters - set registers to match the copy instruction MI. Return /// false if MI is not a coalescable copy instruction. @@ -207,6 +214,9 @@ namespace llvm { /// full register, but was a subreg operation. bool isPartial() const { return partial_; } + /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's. + bool isCrossClass() const { return crossClass_; } + /// isFlipped - Return true when getSrcReg is the register being defined by /// the original copy instruction. bool isFlipped() const { return flipped_; } @@ -222,6 +232,10 @@ namespace llvm { /// coalesced into, or 0. unsigned getSubIdx() const { return subIdx_; } + /// getOrigDstReg - Return DstReg as it appeared in the original copy + /// instruction before any subreg adjustments. + unsigned getOrigDstReg() const { return isPhys() ? origDstReg_ : dstReg_; } + /// getNewRC - Return the register class of the coalesced register. const TargetRegisterClass *getNewRC() const { return newRC_; } }; diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index b18f0957b62..b943a271b6f 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -63,7 +63,7 @@ bool CoalescerPair::isMoveInstr(const MachineInstr *MI, bool CoalescerPair::setRegisters(const MachineInstr *MI) { srcReg_ = dstReg_ = subIdx_ = 0; newRC_ = 0; - flipped_ = false; + flipped_ = crossClass_ = false; unsigned Src, Dst, SrcSub, DstSub; if (!isMoveInstr(MI, Src, Dst, SrcSub, DstSub)) @@ -78,6 +78,7 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { std::swap(SrcSub, DstSub); flipped_ = true; } + origDstReg_ = Dst; const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); @@ -100,11 +101,19 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { } else { // Both registers are virtual. - // Identical sub to sub. - if (SrcSub == DstSub) + // 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) + return false; + const TargetRegisterClass *SrcRC = MRI.getRegClass(Src); + const TargetRegisterClass *DstRC = MRI.getRegClass(Dst); + if (!getCommonSubClass(DstRC, SrcRC)) + return false; SrcSub = DstSub = 0; - else if (SrcSub && DstSub) - return false; // FIXME: Qreg:ssub_3 + Dreg:ssub_1 => QReg:dsub_1 + Dreg. + } // There can be no SrcSub. if (SrcSub) { @@ -124,6 +133,7 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { newRC_ = getCommonSubClass(DstRC, SrcRC); if (!newRC_) return false; + crossClass_ = newRC_ != DstRC || newRC_ != SrcRC; } // Check our invariants assert(TargetRegisterInfo::isVirtualRegister(Src) && "Src must be virtual");