+
+ bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG;
+ unsigned RealDstReg = 0;
+ if (isExtSubReg) {
+ unsigned SubIdx = CopyMI->getOperand(2).getImm();
+ if (SrcIsPhys)
+ // r1024 = EXTRACT_SUBREG EAX, 0 then r1024 is really going to be
+ // coalesced with AX.
+ repSrcReg = mri_->getSubReg(repSrcReg, SubIdx);
+ else if (DstIsPhys) {
+ // If this is a extract_subreg where dst is a physical register, e.g.
+ // cl = EXTRACT_SUBREG reg1024, 1
+ // then create and update the actual physical register allocated to RHS.
+ const TargetRegisterClass *RC=mf_->getSSARegMap()->getRegClass(repSrcReg);
+ for (const unsigned *SRs = mri_->getSuperRegisters(repDstReg);
+ unsigned SR = *SRs; ++SRs) {
+ if (repDstReg == mri_->getSubReg(SR, SubIdx) &&
+ RC->contains(SR)) {
+ RealDstReg = SR;
+ break;
+ }
+ }
+ assert(RealDstReg && "Invalid extra_subreg instruction!");
+
+ // For this type of EXTRACT_SUBREG, conservatively
+ // check if the live interval of the source register interfere with the
+ // actual super physical register we are trying to coalesce with.
+ LiveInterval &RHS = li_->getInterval(repSrcReg);
+ if (li_->hasInterval(RealDstReg) &&
+ RHS.overlaps(li_->getInterval(RealDstReg))) {
+ DOUT << "Interfere with register ";
+ DEBUG(li_->getInterval(RealDstReg).print(DOUT, mri_));
+ return false; // Not coalescable
+ }
+ for (const unsigned* SR = mri_->getSubRegisters(RealDstReg); *SR; ++SR)
+ if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
+ DOUT << "Interfere with sub-register ";
+ DEBUG(li_->getInterval(*SR).print(DOUT, mri_));
+ return false; // Not coalescable
+ }
+ } else {
+ unsigned SrcSize= li_->getInterval(repSrcReg).getSize() / InstrSlots::NUM;
+ unsigned DstSize= li_->getInterval(repDstReg).getSize() / InstrSlots::NUM;
+ const TargetRegisterClass *RC=mf_->getSSARegMap()->getRegClass(repDstReg);
+ unsigned Threshold = allocatableRCRegs_[RC].count();
+ // Be conservative. If both sides are virtual registers, do not coalesce
+ // if this will cause a high use density interval to target a smaller set
+ // of registers.
+ if (DstSize > Threshold || SrcSize > Threshold) {
+ LiveVariables::VarInfo &svi = lv_->getVarInfo(repSrcReg);
+ LiveVariables::VarInfo &dvi = lv_->getVarInfo(repDstReg);
+ if ((float)dvi.NumUses / DstSize < (float)svi.NumUses / SrcSize) {
+ Again = true; // May be possible to coalesce later.
+ return false;
+ }
+ }
+ }
+ } else if (differingRegisterClasses(repSrcReg, repDstReg)) {
+ // If they are not of the same register class, we cannot join them.