From 08e791fdb301d3a4c6c9fa6b7f5c3e33921f38a6 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 28 Apr 2009 16:34:35 +0000 Subject: [PATCH] Don't coalesce a physical register with an incompatible virtual register. If the physical register does not belong to the virtual register's regclass, don't coalesce. The physical register could be an invalid operand for an instruction using the vreg. The regclass matching is done after determining the actual subregisters being copied. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70298 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SimpleRegisterCoalescing.cpp | 47 +++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 520ecb3c4d6..cbbd2ce2197 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1160,22 +1160,25 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI; - unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; + unsigned SrcReg, DstReg, SrcSubIdx = 0, DstSubIdx = 0; bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG; bool isInsSubReg = CopyMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG; bool isSubRegToReg = CopyMI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG; unsigned SubIdx = 0; if (isExtSubReg) { - DstReg = CopyMI->getOperand(0).getReg(); - SrcReg = CopyMI->getOperand(1).getReg(); + DstReg = CopyMI->getOperand(0).getReg(); + DstSubIdx = CopyMI->getOperand(0).getSubReg(); + SrcReg = CopyMI->getOperand(1).getReg(); + SrcSubIdx = CopyMI->getOperand(2).getImm(); } else if (isInsSubReg || isSubRegToReg) { if (CopyMI->getOperand(2).getSubReg()) { DOUT << "\tSource of insert_subreg is already coalesced " << "to another register.\n"; return false; // Not coalescable. } - DstReg = CopyMI->getOperand(0).getReg(); - SrcReg = CopyMI->getOperand(2).getReg(); + DstReg = CopyMI->getOperand(0).getReg(); + DstSubIdx = CopyMI->getOperand(3).getImm(); + SrcReg = CopyMI->getOperand(2).getReg(); } else if (!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)){ assert(0 && "Unrecognized copy instruction!"); return false; @@ -1206,6 +1209,40 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { return false; // Not coalescable. } + // Check that a physical source register is compatible with dst regclass + if (SrcIsPhys) { + unsigned SrcSubReg = SrcSubIdx ? + tri_->getSubReg(SrcReg, SrcSubIdx) : SrcReg; + const TargetRegisterClass *DstRC = mri_->getRegClass(DstReg); + const TargetRegisterClass *DstSubRC = DstRC; + if (DstSubIdx) + DstSubRC = DstRC->getSubRegisterRegClass(DstSubIdx); + assert(DstSubRC && "Illegal subregister index"); + if (!DstSubRC->contains(SrcSubReg)) { + DOUT << "\tIncompatible destination regclass: " + << tri_->getName(SrcSubReg) << " not in " << DstSubRC->getName() + << ".\n"; + return false; // Not coalescable. + } + } + + // Check that a physical dst register is compatible with source regclass + if (DstIsPhys) { + unsigned DstSubReg = DstSubIdx ? + tri_->getSubReg(DstReg, DstSubIdx) : DstReg; + const TargetRegisterClass *SrcRC = mri_->getRegClass(SrcReg); + const TargetRegisterClass *SrcSubRC = SrcRC; + if (SrcSubIdx) + SrcSubRC = SrcRC->getSubRegisterRegClass(SrcSubIdx); + assert(SrcSubRC && "Illegal subregister index"); + if (!SrcSubRC->contains(DstReg)) { + DOUT << "\tIncompatible source regclass: " + << tri_->getName(DstSubReg) << " not in " << SrcSubRC->getName() + << ".\n"; + return false; // Not coalescable. + } + } + // Should be non-null only when coalescing to a sub-register class. bool CrossRC = false; const TargetRegisterClass *NewRC = NULL; -- 2.34.1