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. for (auto J : I->operands()) { if (J.isRegMask()) AvailableRegs.clearBitsNotInMask(J.getRegMask()); } } // 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; }
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()) { MCRegAliasIterator AI(J.getReg(), TRI, /*IncludeSelf=*/true); if (J.isDead()) for (; AI.isValid(); ++AI) AvailableRegs.reset(*AI); #ifndef NDEBUG else for (; AI.isValid(); ++AI) assert(!AvailableRegs[*AI] && "Non-dead def should have been removed by now!"); #endif } } } // 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; }
// Find a scratch register that we can use at the start of the prologue to // re-align the stack pointer. We avoid using callee-save registers since they // may appear to be free when this is called from canUseAsPrologue (during // shrink wrapping), but then no longer be free when this is called from // emitPrologue. // // FIXME: This is a bit conservative, since in the above case we could use one // of the callee-save registers as a scratch temp to re-align the stack pointer, // but we would then have to make sure that we were in fact saving at least one // callee-save register in the prologue, which is additional complexity that // doesn't seem worth the benefit. static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) { MachineFunction *MF = MBB->getParent(); // If MBB is an entry block, use X9 as the scratch register if (&MF->front() == MBB) return AArch64::X9; RegScavenger RS; RS.enterBasicBlock(*MBB); // Prefer X9 since it was historically used for the prologue scratch reg. if (!RS.isRegUsed(AArch64::X9)) return AArch64::X9; // Find a free non callee-save reg. const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>(); const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo(); const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MF); BitVector CalleeSaveRegs(RegInfo->getNumRegs()); for (unsigned i = 0; CSRegs[i]; ++i) CalleeSaveRegs.set(CSRegs[i]); BitVector Available = RS.getRegsAvailable(&AArch64::GPR64RegClass); for (int AvailReg = Available.find_first(); AvailReg != -1; AvailReg = Available.find_next(AvailReg)) if (!CalleeSaveRegs.test(AvailReg)) return AvailReg; return AArch64::NoRegister; }
/// 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; }