Loading llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h +4 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,10 @@ namespace llvm { return *I->second; } /// dupInterval - Duplicate a live interval. The caller is responsible for /// managing the allocated memory. LiveInterval *dupInterval(LiveInterval *li); /// addLiveRangeToEndOfBlock - Given a register and an instruction, /// adds a live range from that instruction to the end of its MBB. LiveRange addLiveRangeToEndOfBlock(unsigned reg, Loading llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +25 −14 Original line number Diff line number Diff line Loading @@ -1322,6 +1322,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); Loading Loading @@ -1413,21 +1422,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, 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()); ValNo->hasPHIKill = DstValNo->hasPHIKill; RealInt.addKills(ValNo, DstValNo->kills); RealInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo); } 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; } Loading Loading @@ -1497,6 +1502,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 Loading llvm/test/CodeGen/X86/2009-02-08-CoalescerBug.ll 0 → 100644 +22 −0 Original line number Diff line number Diff line ; RUN: llvm-as < %s | llc -march=x86 ; PR3486 define i32 @foo(i8 signext %p_26) nounwind { entry: %0 = icmp eq i8 %p_26, 0 ; <i1> [#uses=2] %or.cond = or i1 false, %0 ; <i1> [#uses=2] %iftmp.1.0 = zext i1 %or.cond to i16 ; <i16> [#uses=1] br i1 %0, label %bb.i, label %bar.exit bb.i: ; preds = %entry %1 = zext i1 %or.cond to i32 ; <i32> [#uses=1] %2 = sdiv i32 %1, 0 ; <i32> [#uses=1] %3 = trunc i32 %2 to i16 ; <i16> [#uses=1] br label %bar.exit bar.exit: ; preds = %bb.i, %entry %4 = phi i16 [ %3, %bb.i ], [ %iftmp.1.0, %entry ] ; <i16> [#uses=1] %5 = trunc i16 %4 to i8 ; <i8> [#uses=1] %6 = sext i8 %5 to i32 ; <i32> [#uses=1] ret i32 %6 } Loading
llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h +4 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,10 @@ namespace llvm { return *I->second; } /// dupInterval - Duplicate a live interval. The caller is responsible for /// managing the allocated memory. LiveInterval *dupInterval(LiveInterval *li); /// addLiveRangeToEndOfBlock - Given a register and an instruction, /// adds a live range from that instruction to the end of its MBB. LiveRange addLiveRangeToEndOfBlock(unsigned reg, Loading
llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading
llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +25 −14 Original line number Diff line number Diff line Loading @@ -1322,6 +1322,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); Loading Loading @@ -1413,21 +1422,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, 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()); ValNo->hasPHIKill = DstValNo->hasPHIKill; RealInt.addKills(ValNo, DstValNo->kills); RealInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo); } 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; } Loading Loading @@ -1497,6 +1502,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 Loading
llvm/test/CodeGen/X86/2009-02-08-CoalescerBug.ll 0 → 100644 +22 −0 Original line number Diff line number Diff line ; RUN: llvm-as < %s | llc -march=x86 ; PR3486 define i32 @foo(i8 signext %p_26) nounwind { entry: %0 = icmp eq i8 %p_26, 0 ; <i1> [#uses=2] %or.cond = or i1 false, %0 ; <i1> [#uses=2] %iftmp.1.0 = zext i1 %or.cond to i16 ; <i16> [#uses=1] br i1 %0, label %bb.i, label %bar.exit bb.i: ; preds = %entry %1 = zext i1 %or.cond to i32 ; <i32> [#uses=1] %2 = sdiv i32 %1, 0 ; <i32> [#uses=1] %3 = trunc i32 %2 to i16 ; <i16> [#uses=1] br label %bar.exit bar.exit: ; preds = %bb.i, %entry %4 = phi i16 [ %3, %bb.i ], [ %iftmp.1.0, %entry ] ; <i16> [#uses=1] %5 = trunc i16 %4 to i8 ; <i8> [#uses=1] %6 = sext i8 %5 to i32 ; <i32> [#uses=1] ret i32 %6 }