diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-04-28 16:34:35 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-04-28 16:34:35 +0000 |
commit | 08e791fdb301d3a4c6c9fa6b7f5c3e33921f38a6 (patch) | |
tree | a540da32df05b71d515dc34ab3513fdfec4bfa58 /lib/CodeGen | |
parent | d3d965714b89c5d5aeb65fb5ce06e081f0b3c049 (diff) | |
download | external_llvm-08e791fdb301d3a4c6c9fa6b7f5c3e33921f38a6.zip external_llvm-08e791fdb301d3a4c6c9fa6b7f5c3e33921f38a6.tar.gz external_llvm-08e791fdb301d3a4c6c9fa6b7f5c3e33921f38a6.tar.bz2 |
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SimpleRegisterCoalescing.cpp | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 520ecb3..cbbd2ce 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; |