/// transferValues - Transfer all possible values to the new live ranges. /// Values that were rematerialized are left alone, they need LRCalc.extend(). bool SplitEditor::transferValues() { bool Skipped = false; RegAssignMap::const_iterator AssignI = RegAssign.begin(); for (LiveInterval::const_iterator ParentI = Edit->getParent().begin(), ParentE = Edit->getParent().end(); ParentI != ParentE; ++ParentI) { DEBUG(dbgs() << " blit " << *ParentI << ':'); VNInfo *ParentVNI = ParentI->valno; // RegAssign has holes where RegIdx 0 should be used. SlotIndex Start = ParentI->start; AssignI.advanceTo(Start); do { unsigned RegIdx; SlotIndex End = ParentI->end; if (!AssignI.valid()) { RegIdx = 0; } else if (AssignI.start() <= Start) { RegIdx = AssignI.value(); if (AssignI.stop() < End) { End = AssignI.stop(); ++AssignI; } } else { RegIdx = 0; End = std::min(End, AssignI.start()); } // The interval [Start;End) is continuously mapped to RegIdx, ParentVNI. DEBUG(dbgs() << " [" << Start << ';' << End << ")=" << RegIdx); LiveInterval *LI = Edit->get(RegIdx); // Check for a simply defined value that can be blitted directly. ValueForcePair VFP = Values.lookup(std::make_pair(RegIdx, ParentVNI->id)); if (VNInfo *VNI = VFP.getPointer()) { DEBUG(dbgs() << ':' << VNI->id); LI->addRange(LiveRange(Start, End, VNI)); Start = End; continue; } // Skip values with forced recomputation. if (VFP.getInt()) { DEBUG(dbgs() << "(recalc)"); Skipped = true; Start = End; continue; } LiveRangeCalc &LRC = getLRCalc(RegIdx); // This value has multiple defs in RegIdx, but it wasn't rematerialized, // so the live range is accurate. Add live-in blocks in [Start;End) to the // LiveInBlocks. MachineFunction::iterator MBB = LIS.getMBBFromIndex(Start); SlotIndex BlockStart, BlockEnd; tie(BlockStart, BlockEnd) = LIS.getSlotIndexes()->getMBBRange(MBB); // The first block may be live-in, or it may have its own def. if (Start != BlockStart) { VNInfo *VNI = LI->extendInBlock(BlockStart, std::min(BlockEnd, End)); assert(VNI && "Missing def for complex mapped value"); DEBUG(dbgs() << ':' << VNI->id << "*BB#" << MBB->getNumber()); // MBB has its own def. Is it also live-out? if (BlockEnd <= End) LRC.setLiveOutValue(MBB, VNI); // Skip to the next block for live-in. ++MBB; BlockStart = BlockEnd; } // Handle the live-in blocks covered by [Start;End). assert(Start <= BlockStart && "Expected live-in block"); while (BlockStart < End) { DEBUG(dbgs() << ">BB#" << MBB->getNumber()); BlockEnd = LIS.getMBBEndIdx(MBB); if (BlockStart == ParentVNI->def) { // This block has the def of a parent PHI, so it isn't live-in. assert(ParentVNI->isPHIDef() && "Non-phi defined at block start?"); VNInfo *VNI = LI->extendInBlock(BlockStart, std::min(BlockEnd, End)); assert(VNI && "Missing def for complex mapped parent PHI"); if (End >= BlockEnd) LRC.setLiveOutValue(MBB, VNI); // Live-out as well. } else { // This block needs a live-in value. The last block covered may not // be live-out. if (End < BlockEnd) LRC.addLiveInBlock(LI, MDT[MBB], End); else { // Live-through, and we don't know the value. LRC.addLiveInBlock(LI, MDT[MBB]); LRC.setLiveOutValue(MBB, 0); } } BlockStart = BlockEnd; ++MBB; } Start = End; } while (Start != ParentI->end); DEBUG(dbgs() << '\n'); } LRCalc[0].calculateValues(LIS.getSlotIndexes(), &MDT, &LIS.getVNInfoAllocator()); if (SpillMode) LRCalc[1].calculateValues(LIS.getSlotIndexes(), &MDT, &LIS.getVNInfoAllocator()); return Skipped; }