diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/SimpleRegisterCoalescing.cpp | 30 | ||||
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.cpp | 59 |
2 files changed, 55 insertions, 34 deletions
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 0ce603cc6a..daf7d4d582 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -614,15 +614,17 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, return false; if (TID.getNumDefs() != 1) return false; - // Make sure the copy destination register class fits the instruction - // definition register class. The mismatch can happen as a result of earlier - // extract_subreg, insert_subreg, subreg_to_reg coalescing. - const TargetRegisterClass *RC = getInstrOperandRegClass(tri_, TID, 0); - if (TargetRegisterInfo::isVirtualRegister(DstReg)) { - if (mri_->getRegClass(DstReg) != RC) + if (DefMI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) { + // Make sure the copy destination register class fits the instruction + // definition register class. The mismatch can happen as a result of earlier + // extract_subreg, insert_subreg, subreg_to_reg coalescing. + const TargetRegisterClass *RC = getInstrOperandRegClass(tri_, TID, 0); + if (TargetRegisterInfo::isVirtualRegister(DstReg)) { + if (mri_->getRegClass(DstReg) != RC) + return false; + } else if (!RC->contains(DstReg)) return false; - } else if (!RC->contains(DstReg)) - return false; + } unsigned DefIdx = li_->getDefIndex(CopyIdx); const LiveRange *DLR= li_->getInterval(DstReg).getLiveRangeContaining(DefIdx); @@ -1378,13 +1380,17 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { } } if (SubIdx) { - if (isInsSubReg || isSubRegToReg) { - if (!DstIsPhys && !SrcIsPhys) { + if (!DstIsPhys && !SrcIsPhys) { + if (isInsSubReg || isSubRegToReg) { NewRC = tri_->getMatchingSuperRegClass(DstRC, SrcRC, SubIdx); - if (!NewRC) - return false; + } else // extract_subreg { + NewRC = tri_->getMatchingSuperRegClass(SrcRC, DstRC, SubIdx); } + if (!NewRC) { + DOUT << "\t Conflicting sub-register indices.\n"; + return false; // Not coalescable } + unsigned LargeReg = isExtSubReg ? SrcReg : DstReg; unsigned SmallReg = isExtSubReg ? DstReg : SrcReg; unsigned Limit= allocatableRCRegs_[mri_->getRegClass(SmallReg)].count(); diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 0dc63ef9a6..751b20598b 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -161,69 +161,84 @@ X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, case 1: // 8-bit if (B == &X86::GR8RegClass) { - if (A == &X86::GR64RegClass) - return &X86::GR64RegClass; - else if (A == &X86::GR32RegClass) - return &X86::GR32RegClass; - else if (A == &X86::GR16RegClass) - return &X86::GR16RegClass; + if (A->getSize() == 2 || A->getSize() == 4 || A->getSize() == 8) + return A; } else if (B == &X86::GR8_ABCD_LRegClass || B == &X86::GR8_ABCD_HRegClass) { - if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass) + if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass || + A == &X86::GR64_NOREXRegClass) return &X86::GR64_ABCDRegClass; - else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass) + else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass || + A == &X86::GR32_NOREXRegClass) return &X86::GR32_ABCDRegClass; - else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass) + else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass || + A == &X86::GR16_NOREXRegClass) return &X86::GR16_ABCDRegClass; } else if (B == &X86::GR8_NOREXRegClass) { if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass) return &X86::GR64_NOREXRegClass; + else if (A == &X86::GR64_ABCDRegClass) + return &X86::GR64_ABCDRegClass; else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass) return &X86::GR32_NOREXRegClass; + else if (A == &X86::GR32_ABCDRegClass) + return &X86::GR32_ABCDRegClass; else if (A == &X86::GR16RegClass || A == &X86::GR16_NOREXRegClass) return &X86::GR16_NOREXRegClass; + else if (A == &X86::GR16_ABCDRegClass) + return &X86::GR16_ABCDRegClass; } break; case 2: // 8-bit hi if (B == &X86::GR8_ABCD_HRegClass) { - if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass) + if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass || + A == &X86::GR64_NOREXRegClass) return &X86::GR64_ABCDRegClass; - else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass) + else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass || + A == &X86::GR32_NOREXRegClass) return &X86::GR32_ABCDRegClass; - else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass) + else if (A == &X86::GR16RegClass || A == &X86::GR16_ABCDRegClass || + A == &X86::GR16_NOREXRegClass) return &X86::GR16_ABCDRegClass; } break; case 3: // 16-bit if (B == &X86::GR16RegClass) { - if (A == &X86::GR64RegClass) - return &X86::GR64RegClass; - else if (A == &X86::GR32RegClass) - return &X86::GR32RegClass; + if (A->getSize() == 4 || A->getSize() == 8) + return A; } else if (B == &X86::GR16_ABCDRegClass) { - if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass) + if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass || + A == &X86::GR64_NOREXRegClass) return &X86::GR64_ABCDRegClass; - else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass) + else if (A == &X86::GR32RegClass || A == &X86::GR32_ABCDRegClass || + A == &X86::GR32_NOREXRegClass) return &X86::GR32_ABCDRegClass; } else if (B == &X86::GR16_NOREXRegClass) { if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass) return &X86::GR64_NOREXRegClass; - else if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass) + else if (A == &X86::GR64_ABCDRegClass) + return &X86::GR64_ABCDRegClass; + else if (A == &X86::GR32RegClass || A == &X86::GR32_NOREXRegClass) + return &X86::GR32_NOREXRegClass; + else if (A == &X86::GR32_ABCDRegClass) return &X86::GR64_ABCDRegClass; } break; case 4: // 32-bit if (B == &X86::GR32RegClass) { - if (A == &X86::GR64RegClass) - return &X86::GR64RegClass; + if (A->getSize() == 8) + return A; } else if (B == &X86::GR32_ABCDRegClass) { - if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass) + if (A == &X86::GR64RegClass || A == &X86::GR64_ABCDRegClass || + A == &X86::GR64_NOREXRegClass) return &X86::GR64_ABCDRegClass; } else if (B == &X86::GR32_NOREXRegClass) { if (A == &X86::GR64RegClass || A == &X86::GR64_NOREXRegClass) return &X86::GR64_NOREXRegClass; + else if (A == &X86::GR64_ABCDRegClass) + return &X86::GR64_ABCDRegClass; } break; } |