/// leaveIntvAfter - Leave openli after the instruction at Idx. void SplitEditor::leaveIntvAfter(SlotIndex Idx) { assert(openli_ && "openIntv not called before leaveIntvAfter"); const LiveRange *CurLR = curli_->getLiveRangeContaining(Idx.getDefIndex()); if (!CurLR || CurLR->end <= Idx.getBoundaryIndex()) { DEBUG(dbgs() << " leaveIntvAfter " << Idx << ": not live\n"); return; } // Was this value of curli live through openli? if (!openli_->liveAt(CurLR->valno->def)) { DEBUG(dbgs() << " leaveIntvAfter " << Idx << ": using external value\n"); liveThrough_ = true; return; } // We are going to insert a back copy, so we must have a dupli_. LiveRange *DupLR = getDupLI()->getLiveRangeContaining(Idx.getDefIndex()); assert(DupLR && "dupli not live into black, but curli is?"); // Insert the COPY instruction. MachineBasicBlock::iterator I = lis_.getInstructionFromIndex(Idx); MachineInstr *MI = BuildMI(*I->getParent(), llvm::next(I), I->getDebugLoc(), tii_.get(TargetOpcode::COPY), dupli_->reg) .addReg(openli_->reg); SlotIndex CopyIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex(); openli_->addRange(LiveRange(Idx.getDefIndex(), CopyIdx, mapValue(CurLR->valno))); DupLR->valno->def = CopyIdx; DEBUG(dbgs() << " leaveIntvAfter " << Idx << ": " << *openli_ << '\n'); }
SlotIndex SplitEditor::enterIntvAfter(SlotIndex Idx) { assert(OpenIdx && "openIntv not called before enterIntvAfter"); DEBUG(dbgs() << " enterIntvAfter " << Idx); Idx = Idx.getBoundaryIndex(); VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx); if (!ParentVNI) { DEBUG(dbgs() << ": not live\n"); return Idx; } DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n'); MachineInstr *MI = LIS.getInstructionFromIndex(Idx); assert(MI && "enterIntvAfter called with invalid index"); VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Idx, *MI->getParent(), llvm::next(MachineBasicBlock::iterator(MI))); return VNI->def; }
SlotIndex SplitEditor::leaveIntvAfter(SlotIndex Idx) { assert(OpenIdx && "openIntv not called before leaveIntvAfter"); DEBUG(dbgs() << " leaveIntvAfter " << Idx); // The interval must be live beyond the instruction at Idx. Idx = Idx.getBoundaryIndex(); VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx); if (!ParentVNI) { DEBUG(dbgs() << ": not live\n"); return Idx.getNextSlot(); } DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n'); MachineInstr *MI = LIS.getInstructionFromIndex(Idx); assert(MI && "No instruction at index"); VNInfo *VNI = defFromParent(0, ParentVNI, Idx, *MI->getParent(), llvm::next(MachineBasicBlock::iterator(MI))); return VNI->def; }
/// Check whether (part of) \p SuperPhysReg is live through \p MI. /// \pre \p MI defines a subregister of a virtual register that /// has been assigned to \p SuperPhysReg. bool VirtRegRewriter::subRegLiveThrough(const MachineInstr &MI, unsigned SuperPhysReg) const { SlotIndex MIIndex = LIS->getInstructionIndex(MI); SlotIndex BeforeMIUses = MIIndex.getBaseIndex(); SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex(); for (MCRegUnitIterator Unit(SuperPhysReg, TRI); Unit.isValid(); ++Unit) { const LiveRange &UnitRange = LIS->getRegUnit(*Unit); // If the regunit is live both before and after MI, // we assume it is live through. // Generally speaking, this is not true, because something like // "RU = op RU" would match that description. // However, we know that we are trying to assess whether // a def of a virtual reg, vreg, is live at the same time of RU. // If we are in the "RU = op RU" situation, that means that vreg // is defined at the same time as RU (i.e., "vreg, RU = op RU"). // Thus, vreg and RU interferes and vreg cannot be assigned to // SuperPhysReg. Therefore, this situation cannot happen. if (UnitRange.liveAt(AfterMIDefs) && UnitRange.liveAt(BeforeMIUses)) return true; } return false; }
void SplitEditor::splitLiveThroughBlock(unsigned MBBNum, unsigned IntvIn, SlotIndex LeaveBefore, unsigned IntvOut, SlotIndex EnterAfter){ SlotIndex Start, Stop; tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(MBBNum); DEBUG(dbgs() << "BB#" << MBBNum << " [" << Start << ';' << Stop << ") intf " << LeaveBefore << '-' << EnterAfter << ", live-through " << IntvIn << " -> " << IntvOut); assert((IntvIn || IntvOut) && "Use splitSingleBlock for isolated blocks"); assert((!LeaveBefore || LeaveBefore < Stop) && "Interference after block"); assert((!IntvIn || !LeaveBefore || LeaveBefore > Start) && "Impossible intf"); assert((!EnterAfter || EnterAfter >= Start) && "Interference before block"); MachineBasicBlock *MBB = VRM.getMachineFunction().getBlockNumbered(MBBNum); if (!IntvOut) { DEBUG(dbgs() << ", spill on entry.\n"); // // <<<<<<<<< Possible LeaveBefore interference. // |-----------| Live through. // -____________ Spill on entry. // selectIntv(IntvIn); SlotIndex Idx = leaveIntvAtTop(*MBB); assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); (void)Idx; return; } if (!IntvIn) { DEBUG(dbgs() << ", reload on exit.\n"); // // >>>>>>> Possible EnterAfter interference. // |-----------| Live through. // ___________-- Reload on exit. // selectIntv(IntvOut); SlotIndex Idx = enterIntvAtEnd(*MBB); assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); (void)Idx; return; } if (IntvIn == IntvOut && !LeaveBefore && !EnterAfter) { DEBUG(dbgs() << ", straight through.\n"); // // |-----------| Live through. // ------------- Straight through, same intv, no interference. // selectIntv(IntvOut); useIntv(Start, Stop); return; } // We cannot legally insert splits after LSP. SlotIndex LSP = SA.getLastSplitPoint(MBBNum); assert((!IntvOut || !EnterAfter || EnterAfter < LSP) && "Impossible intf"); if (IntvIn != IntvOut && (!LeaveBefore || !EnterAfter || LeaveBefore.getBaseIndex() > EnterAfter.getBoundaryIndex())) { DEBUG(dbgs() << ", switch avoiding interference.\n"); // // >>>> <<<< Non-overlapping EnterAfter/LeaveBefore interference. // |-----------| Live through. // ------======= Switch intervals between interference. // selectIntv(IntvOut); SlotIndex Idx; if (LeaveBefore && LeaveBefore < LSP) { Idx = enterIntvBefore(LeaveBefore); useIntv(Idx, Stop); } else { Idx = enterIntvAtEnd(*MBB); } selectIntv(IntvIn); useIntv(Start, Idx); assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); return; } DEBUG(dbgs() << ", create local intv for interference.\n"); // // >>><><><><<<< Overlapping EnterAfter/LeaveBefore interference. // |-----------| Live through. // ==---------== Switch intervals before/after interference. // assert(LeaveBefore <= EnterAfter && "Missed case"); selectIntv(IntvOut); SlotIndex Idx = enterIntvAfter(EnterAfter); useIntv(Idx, Stop); assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); selectIntv(IntvIn); Idx = leaveIntvBefore(LeaveBefore); useIntv(Start, Idx); assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); }