diff options
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/LiveIntervalAnalysis.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp | 39 |
2 files changed, 34 insertions, 16 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index 8e8e8ff6d0c..985a3fa1634 100644 --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -824,11 +824,18 @@ bool LiveIntervals::findReachableMBBs(unsigned Start, unsigned End, } LiveInterval* LiveIntervals::createInterval(unsigned reg) { - float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? - HUGE_VALF : 0.0F; + float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F; return new LiveInterval(reg, Weight); } +/// dupInterval - Duplicate a live interval. The caller is responsible for +/// managing the allocated memory. +LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) { + LiveInterval *NewLI = createInterval(li->reg); + NewLI->Copy(*li, getVNInfoAllocator()); + return NewLI; +} + /// getVNInfoSourceReg - Helper function that parses the specified VNInfo /// copy field and returns the source register that defines it. unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const { diff --git a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp index db7109e7a63..7a8ea6f6d8f 100644 --- a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1354,6 +1354,15 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { DOUT << " and "; DstInt.print(DOUT, tri_); DOUT << ": "; + // Save a copy of the virtual register live interval. We'll manually + // merge this into the "real" physical register live interval this is + // coalesced with. + LiveInterval *SavedLI = 0; + if (RealDstReg) + SavedLI = li_->dupInterval(&SrcInt); + else if (RealSrcReg) + SavedLI = li_->dupInterval(&DstInt); + // Check if it is necessary to propagate "isDead" property. if (!isExtSubReg && !isInsSubReg) { MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg, false); @@ -1445,21 +1454,17 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { if (RealDstReg || RealSrcReg) { LiveInterval &RealInt = li_->getOrCreateInterval(RealDstReg ? RealDstReg : RealSrcReg); - SmallSet<const VNInfo*, 4> CopiedValNos; - for (LiveInterval::Ranges::const_iterator I = ResSrcInt->ranges.begin(), - E = ResSrcInt->ranges.end(); I != E; ++I) { - const LiveRange *DstLR = ResDstInt->getLiveRangeContaining(I->start); - assert(DstLR && "Invalid joined interval!"); - const VNInfo *DstValNo = DstLR->valno; - if (CopiedValNos.insert(DstValNo)) { - VNInfo *ValNo = RealInt.getNextValue(DstValNo->def, DstValNo->copy, - li_->getVNInfoAllocator()); - ValNo->hasPHIKill = DstValNo->hasPHIKill; - RealInt.addKills(ValNo, DstValNo->kills); - RealInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo); - } + for (LiveInterval::const_vni_iterator I = SavedLI->vni_begin(), + E = SavedLI->vni_end(); I != E; ++I) { + const VNInfo *ValNo = *I; + VNInfo *NewValNo = RealInt.getNextValue(ValNo->def, ValNo->copy, + li_->getVNInfoAllocator()); + NewValNo->hasPHIKill = ValNo->hasPHIKill; + NewValNo->redefByEC = ValNo->redefByEC; + RealInt.addKills(NewValNo, ValNo->kills); + RealInt.MergeValueInAsValue(*SavedLI, ValNo, NewValNo); } - + RealInt.weight += SavedLI->weight; DstReg = RealDstReg ? RealDstReg : RealSrcReg; } @@ -1529,6 +1534,12 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { // being merged. li_->removeInterval(SrcReg); + // Manually deleted the live interval copy. + if (SavedLI) { + SavedLI->clear(); + delete SavedLI; + } + if (isEmpty) { // Now the copy is being coalesced away, the val# previously defined // by the copy is being defined by an IMPLICIT_DEF which defines a zero |

