/// TransferDeadFlag - MI is a pseudo-instruction with DstReg dead, /// and the lowered replacement instructions immediately precede it. /// Mark the replacement instructions with the dead flag. void ExpandPostRA::TransferDeadFlag(MachineInstr *MI, unsigned DstReg, const TargetRegisterInfo *TRI) { for (MachineBasicBlock::iterator MII = prior(MachineBasicBlock::iterator(MI)); ; --MII) { if (MII->addRegisterDead(DstReg, TRI)) break; assert(MII != MI->getParent()->begin() && "copyPhysReg output doesn't reference destination register!"); } }
/// Allocate (scavenge) vregs inside a single basic block. /// Returns true if the target spill callback created new vregs and a 2nd pass /// is necessary. static bool scavengeFrameVirtualRegsInBlock(MachineRegisterInfo &MRI, RegScavenger &RS, MachineBasicBlock &MBB) { const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); RS.enterBasicBlockEnd(MBB); unsigned InitialNumVirtRegs = MRI.getNumVirtRegs(); bool NextInstructionReadsVReg = false; for (MachineBasicBlock::iterator I = MBB.end(); I != MBB.begin(); ) { --I; // Move RegScavenger to the position between *I and *std::next(I). RS.backward(I); // Look for unassigned vregs in the uses of *std::next(I). if (NextInstructionReadsVReg) { MachineBasicBlock::iterator N = std::next(I); const MachineInstr &NMI = *N; for (const MachineOperand &MO : NMI.operands()) { if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); // We only care about virtual registers and ignore virtual registers // created by the target callbacks in the process (those will be handled // in a scavenging round). if (!TargetRegisterInfo::isVirtualRegister(Reg) || TargetRegisterInfo::virtReg2Index(Reg) >= InitialNumVirtRegs) continue; if (!MO.readsReg()) continue; unsigned SReg = scavengeVReg(MRI, RS, Reg, true); N->addRegisterKilled(SReg, &TRI, false); RS.setRegUsed(SReg); } } // Look for unassigned vregs in the defs of *I. NextInstructionReadsVReg = false; const MachineInstr &MI = *I; for (const MachineOperand &MO : MI.operands()) { if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); // Only vregs, no newly created vregs (see above). if (!TargetRegisterInfo::isVirtualRegister(Reg) || TargetRegisterInfo::virtReg2Index(Reg) >= InitialNumVirtRegs) continue; // We have to look at all operands anyway so we can precalculate here // whether there is a reading operand. This allows use to skip the use // step in the next iteration if there was none. assert(!MO.isInternalRead() && "Cannot assign inside bundles"); assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses"); if (MO.readsReg()) { NextInstructionReadsVReg = true; } if (MO.isDef()) { unsigned SReg = scavengeVReg(MRI, RS, Reg, false); I->addRegisterDead(SReg, &TRI, false); } } } #ifndef NDEBUG for (const MachineOperand &MO : MBB.front().operands()) { if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue; assert(!MO.isInternalRead() && "Cannot assign inside bundles"); assert((!MO.isUndef() || MO.isDef()) && "Cannot handle undef uses"); assert(!MO.readsReg() && "Vreg use in first instruction not allowed"); } #endif return MRI.getNumVirtRegs() != InitialNumVirtRegs; }