// Insert Defs and Uses of MI into the sets RegDefs and RegUses.
void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI,
                            SmallSet<unsigned, 32> &RegDefs,
                            SmallSet<unsigned, 32> &RegUses) {
  // If MI is a call or return, just examine the explicit non-variadic operands.
  MCInstrDesc MCID = MI->getDesc();
  unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands()
                                              : MI->getNumOperands();
  for (unsigned I = 0; I != E; ++I) {
    const MachineOperand &MO = MI->getOperand(I);
    unsigned Reg;

    if (!MO.isReg() || !(Reg = MO.getReg()))
      continue;

    if (MO.isDef())
      RegDefs.insert(Reg);
    else if (MO.isUse())
      RegUses.insert(Reg);
  }

  // Call & return instructions defines SP implicitly. Implicit defines are not
  // included in the RegDefs set of calls but instructions modifying SP cannot
  // be inserted in the delay slot of a call/return as these instructions are
  // expanded to multiple instructions with SP modified before the branch that
  // has the delay slot.
  if (MI->isCall() || MI->isReturn())
    RegDefs.insert(Lanai::SP);
}
Пример #2
0
// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
// There is one or two delay slot per delayed instruction.
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
  bool Changed = false;
  LastFiller = MBB.instr_end();

  for (MachineBasicBlock::instr_iterator I = MBB.instr_begin();
       I != MBB.instr_end(); ++I) {
    if (I->getDesc().hasDelaySlot()) {
      MachineBasicBlock::instr_iterator InstrWithSlot = I;
      MachineBasicBlock::instr_iterator J = I;

      // Treat RET specially as it is only instruction with 2 delay slots
      // generated while all others generated have 1 delay slot.
      if (I->getOpcode() == Lanai::RET) {
        // RET is generated as part of epilogue generation and hence we know
        // what the two instructions preceding it are and that it is safe to
        // insert RET above them.
        MachineBasicBlock::reverse_instr_iterator RI(I);
        assert(RI->getOpcode() == Lanai::LDW_RI && RI->getOperand(0).isReg() &&
               RI->getOperand(0).getReg() == Lanai::FP &&
               RI->getOperand(1).isReg() &&
               RI->getOperand(1).getReg() == Lanai::FP &&
               RI->getOperand(2).isImm() && RI->getOperand(2).getImm() == -8);
        ++RI;
        assert(RI->getOpcode() == Lanai::ADD_I_LO &&
               RI->getOperand(0).isReg() &&
               RI->getOperand(0).getReg() == Lanai::SP &&
               RI->getOperand(1).isReg() &&
               RI->getOperand(1).getReg() == Lanai::FP);
        ++RI;
        MachineBasicBlock::instr_iterator FI(RI.base());
        MBB.splice(std::next(I), &MBB, FI, I);
        FilledSlots += 2;
      } else {
        if (!NopDelaySlotFiller && findDelayInstr(MBB, I, J)) {
          MBB.splice(std::next(I), &MBB, J);
        } else {
          BuildMI(MBB, std::next(I), DebugLoc(), TII->get(Lanai::NOP));
        }
        ++FilledSlots;
      }

      Changed = true;
      // Record the filler instruction that filled the delay slot.
      // The instruction after it will be visited in the next iteration.
      LastFiller = ++I;

      // Bundle the delay slot filler to InstrWithSlot so that the machine
      // verifier doesn't expect this instruction to be a terminator.
      MIBundleBuilder(MBB, InstrWithSlot, std::next(LastFiller));
    }
  }
  return Changed;
}
Пример #3
0
void MipsCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI,
                                      MachineBasicBlock &MBB) {
  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI);

  // Expand pseudo instruction. Skip if MI was not expanded.
  if (((MI->getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) &&
      !expandPseudos(MI, MBB))
    return;

  MCE.processDebugLoc(MI->getDebugLoc(), true);

  emitWord(getBinaryCodeForInstr(*MI));
  ++NumEmitted;  // Keep track of the # of mi's emitted

  MCE.processDebugLoc(MI->getDebugLoc(), false);
}
// Insert Defs and Uses of MI into the sets RegDefs and RegUses.
void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI,
                            SmallSet<unsigned, 32> &RegDefs,
                            SmallSet<unsigned, 32> &RegUses) {
  // If MI is a call or return, just examine the explicit non-variadic operands.
  MCInstrDesc MCID = MI->getDesc();
  unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands()
                                              : MI->getNumOperands();
  for (unsigned I = 0; I != E; ++I) {
    const MachineOperand &MO = MI->getOperand(I);
    unsigned Reg;

    if (!MO.isReg() || !(Reg = MO.getReg()))
      continue;

    if (MO.isDef())
      RegDefs.insert(Reg);
    else if (MO.isUse())
      RegUses.insert(Reg);
  }
}