/// Changes operand OpNum in MI the refer the PhysReg, considering subregs. This /// may invalidate any operand pointers. Return true if the operand kills its /// register. bool RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg) { bool Dead = MO.isDead(); if (!MO.getSubReg()) { MO.setReg(PhysReg); MO.setIsRenamable(true); return MO.isKill() || Dead; } // Handle subregister index. MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : 0); MO.setIsRenamable(true); MO.setSubReg(0); // A kill flag implies killing the full register. Add corresponding super // register kill. if (MO.isKill()) { MI.addRegisterKilled(PhysReg, TRI, true); return true; } // A <def,read-undef> of a sub-register requires an implicit def of the full // register. if (MO.isDef() && MO.isUndef()) MI.addRegisterDefined(PhysReg, TRI); return Dead; }
void RegAllocFast::allocVirtRegUndef(MachineOperand &MO) { assert(MO.isUndef() && "expected undef use"); unsigned VirtReg = MO.getReg(); assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Expected virtreg"); LiveRegMap::const_iterator LRI = findLiveVirtReg(VirtReg); MCPhysReg PhysReg; if (LRI != LiveVirtRegs.end() && LRI->PhysReg) { PhysReg = LRI->PhysReg; } else { const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC); assert(!AllocationOrder.empty() && "Allocation order must not be empty"); PhysReg = AllocationOrder[0]; } unsigned SubRegIdx = MO.getSubReg(); if (SubRegIdx != 0) { PhysReg = TRI->getSubReg(PhysReg, SubRegIdx); MO.setSubReg(0); } MO.setReg(PhysReg); MO.setIsRenamable(true); }
/// Add the specified instruction to live intervals. This function is used /// to update the live intervals while the program code is being changed. /// Neither the expansion of a MUX, nor the predication are atomic, and this /// function is used to update the live intervals while these transformations /// are being done. void HexagonExpandCondsets::addInstrToLiveness(MachineInstr *MI) { SlotIndex MX = LIS->isNotInMIMap(*MI) ? LIS->InsertMachineInstrInMaps(*MI) : LIS->getInstructionIndex(*MI); DEBUG(dbgs() << "adding liveness info for instr\n " << MX << " " << *MI); MX = MX.getRegSlot(); bool Predicated = HII->isPredicated(*MI); MachineBasicBlock *MB = MI->getParent(); // Strip all implicit uses from predicated instructions. They will be // added again, according to the updated information. if (Predicated) removeImplicitUses(MI); // For each def in MI we need to insert a new live segment starting at MX // into the interval. If there already exists a live segment in the interval // that contains MX, we need to terminate it at MX. SmallVector<RegisterRef,2> Defs; for (auto &Op : MI->operands()) if (Op.isReg() && Op.isDef()) Defs.push_back(RegisterRef(Op)); for (unsigned i = 0, n = Defs.size(); i < n; ++i) { unsigned DefR = Defs[i].Reg; LiveInterval &LID = LIS->getInterval(DefR); DEBUG(dbgs() << "adding def " << PrintReg(DefR, TRI) << " with interval\n " << LID << "\n"); // If MX falls inside of an existing live segment, terminate it. LiveInterval::iterator LT = LID.FindSegmentContaining(MX); if (LT != LID.end()) terminateSegment(LT, MX, LID); DEBUG(dbgs() << "after terminating segment\n " << LID << "\n"); // Create a new segment starting from MX. LiveInterval::iterator P = prevSegment(LID, MX), N = nextSegment(LID, MX); SlotIndex EX; VNInfo *VN = LID.getNextValue(MX, LIS->getVNInfoAllocator()); if (N == LID.end()) { // There is no live segment after MX. End this segment at the end of // the block. EX = LIS->getMBBEndIdx(MB); } else { // If the next segment starts at the block boundary, end the new segment // at the boundary of the preceding block (i.e. the previous index). // Otherwise, end the segment at the beginning of the next segment. In // either case it will be "shrunk-to-uses" later. EX = N->start.isBlock() ? N->start.getPrevIndex() : N->start; } if (Predicated) { // Predicated instruction will have an implicit use of the defined // register. This is necessary so that this definition will not make // any previous definitions dead. If there are no previous live // segments, still add the implicit use, but make it "undef". // Because of the implicit use, the preceding definition is not // dead. Mark is as such (if necessary). MachineOperand ImpUse = MachineOperand::CreateReg(DefR, false, true); ImpUse.setSubReg(Defs[i].Sub); bool Undef = false; if (P == LID.end()) Undef = true; else { // If the previous segment extends to the end of the previous block, // the end index may actually be the beginning of this block. If // the previous segment ends at a block boundary, move it back by one, // to get the proper block for it. SlotIndex PE = P->end.isBlock() ? P->end.getPrevIndex() : P->end; MachineBasicBlock *PB = LIS->getMBBFromIndex(PE); if (PB != MB && !LIS->isLiveInToMBB(LID, MB)) Undef = true; } if (!Undef) { makeUndead(DefR, P->valno->def); // We are adding a live use, so extend the previous segment to // include it. P->end = MX; } else { ImpUse.setIsUndef(true); } if (!MI->readsRegister(DefR)) MI->addOperand(ImpUse); if (N != LID.end()) makeDefined(DefR, N->start, true); } LiveRange::Segment NR = LiveRange::Segment(MX, EX, VN); LID.addSegment(NR); DEBUG(dbgs() << "added a new segment " << NR << "\n " << LID << "\n"); shrinkToUses(DefR, LID); DEBUG(dbgs() << "updated imp-uses: " << *MI); LID.verify(); } // For each use in MI: // - If there is no live segment that contains MX for the used register, // extend the previous one. Ignore implicit uses. for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isUse() || Op.isImplicit() || Op.isUndef()) continue; unsigned UseR = Op.getReg(); LiveInterval &LIU = LIS->getInterval(UseR); // Find the last segment P that starts before MX. LiveInterval::iterator P = LIU.FindSegmentContaining(MX); if (P == LIU.end()) P = prevSegment(LIU, MX); assert(P != LIU.end() && "MI uses undefined register?"); SlotIndex EX = P->end; // If P contains MX, there is not much to do. if (EX > MX) { Op.setIsKill(false); continue; } // Otherwise, extend P to "next(MX)". P->end = MX.getNextIndex(); Op.setIsKill(true); // Get the old "kill" instruction, and remove the kill flag. if (MachineInstr *KI = LIS->getInstructionFromIndex(MX)) KI->clearRegisterKills(UseR, nullptr); shrinkToUses(UseR, LIU); LIU.verify(); } }