int AArch64A57FPLoadBalancing::scavengeRegister(Chain *G, Color C, MachineBasicBlock &MBB) { RegScavenger RS; RS.enterBasicBlock(&MBB); RS.forward(MachineBasicBlock::iterator(G->getStart())); // Can we find an appropriate register that is available throughout the life // of the chain? unsigned RegClassID = G->getStart()->getDesc().OpInfo[0].RegClass; BitVector AvailableRegs = RS.getRegsAvailable(TRI->getRegClass(RegClassID)); for (MachineBasicBlock::iterator I = G->getStart(), E = G->getEnd(); I != E; ++I) { RS.forward(I); AvailableRegs &= RS.getRegsAvailable(TRI->getRegClass(RegClassID)); // Remove any registers clobbered by a regmask or any def register that is // immediately dead. for (auto J : I->operands()) { if (J.isRegMask()) AvailableRegs.clearBitsNotInMask(J.getRegMask()); if (J.isReg() && J.isDef() && AvailableRegs[J.getReg()]) { assert(J.isDead() && "Non-dead def should have been removed by now!"); AvailableRegs.reset(J.getReg()); } } } // Make sure we allocate in-order, to get the cheapest registers first. auto Ord = RCI.getOrder(TRI->getRegClass(RegClassID)); for (auto Reg : Ord) { if (!AvailableRegs[Reg]) continue; if ((C == Color::Even && (Reg % 2) == 0) || (C == Color::Odd && (Reg % 2) == 1)) return Reg; } return -1; }
/// This function generates the sequence of instructions needed to get the /// result of adding register REG and immediate IMM. unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, unsigned &NewImm) const { // // given original instruction is: // Instr rx, T[offset] where offset is too big. // // lo = offset & 0xFFFF // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF; // // let T = temporary register // li T, hi // shl T, 16 // add T, Rx, T // RegScavenger rs; int32_t lo = Imm & 0xFFFF; NewImm = lo; int Reg =0; int SpReg = 0; rs.enterBasicBlock(MBB); rs.forward(II); // // We need to know which registers can be used, in the case where there // are not enough free registers. We exclude all registers that // are used in the instruction that we are helping. // // Consider all allocatable registers in the register class initially BitVector Candidates = RI.getAllocatableSet (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass); // Exclude all the registers being used by the instruction. for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { MachineOperand &MO = II->getOperand(i); if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && !TargetRegisterInfo::isVirtualRegister(MO.getReg())) Candidates.reset(MO.getReg()); } // If the same register was used and defined in an instruction, then // it will not be in the list of candidates. // // we need to analyze the instruction that we are helping. // we need to know if it defines register x but register x is not // present as an operand of the instruction. this tells // whether the register is live before the instruction. if it's not // then we don't need to save it in case there are no free registers. int DefReg = 0; for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) { MachineOperand &MO = II->getOperand(i); if (MO.isReg() && MO.isDef()) { DefReg = MO.getReg(); break; } } BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass); Available &= Candidates; // // we use T0 for the first register, if we need to save something away. // we use T1 for the second register, if we need to save something away. // unsigned FirstRegSaved =0, SecondRegSaved=0; unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; Reg = Available.find_first(); if (Reg == -1) { Reg = Candidates.find_first(); Candidates.reset(Reg); if (DefReg != Reg) { FirstRegSaved = Reg; FirstRegSavedTo = Mips::T0; copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); } } else Available.reset(Reg); BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm).addImm(-1); NewImm = 0; if (FrameReg == Mips::SP) { SpReg = Available.find_first(); if (SpReg == -1) { SpReg = Candidates.find_first(); // Candidates.reset(SpReg); // not really needed if (DefReg!= SpReg) { SecondRegSaved = SpReg; SecondRegSavedTo = Mips::T1; } if (SecondRegSaved) copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); } else Available.reset(SpReg); copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill) .addReg(Reg); } else BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg) .addReg(Reg, RegState::Kill); if (FirstRegSaved || SecondRegSaved) { II = std::next(II); if (FirstRegSaved) copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true); if (SecondRegSaved) copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true); } return Reg; }
/// 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; }