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;
}
示例#3
0
// 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;
}