Ejemplo n.º 1
0
bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
                         RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot,
                         IterTy &Filler) const {
  bool IsReverseIter = std::is_convertible<IterTy, ReverseIter>::value;

  for (IterTy I = Begin; I != End;) {
    IterTy CurrI = I;
    ++I;

    // skip debug value
    if (CurrI->isDebugValue())
      continue;

    if (terminateSearch(*CurrI))
      break;

    assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&
           "Cannot put calls, returns or branches in delay slot.");

    if (CurrI->isKill()) {
      CurrI->eraseFromParent();

      // This special case is needed for reverse iterators, because when we
      // erase an instruction, the iterators are updated to point to the next
      // instruction.
      if (IsReverseIter && I != End)
        I = CurrI;
      continue;
    }

    if (delayHasHazard(*CurrI, RegDU, IM))
      continue;

    const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
    if (STI.isTargetNaCl()) {
      // In NaCl, instructions that must be masked are forbidden in delay slots.
      // We only check for loads, stores and SP changes.  Calls, returns and
      // branches are not checked because non-NaCl targets never put them in
      // delay slots.
      unsigned AddrIdx;
      if ((isBasePlusOffsetMemoryAccess(CurrI->getOpcode(), &AddrIdx) &&
           baseRegNeedsLoadStoreMask(CurrI->getOperand(AddrIdx).getReg())) ||
          CurrI->modifiesRegister(Mips::SP, STI.getRegisterInfo()))
        continue;
    }

    bool InMicroMipsMode = STI.inMicroMipsMode();
    const MipsInstrInfo *TII = STI.getInstrInfo();
    unsigned Opcode = (*Slot).getOpcode();
    if (InMicroMipsMode && TII->GetInstSizeInBytes(&(*CurrI)) == 2 &&
        (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
         Opcode == Mips::PseudoReturn))
      continue;

    Filler = CurrI;
    return true;
  }

  return false;
}
Ejemplo n.º 2
0
bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
                         RegDefsUses &RegDU, InspectMemInstr& IM,
                         IterTy &Filler) const {
  for (IterTy I = Begin; I != End; ++I) {
    // skip debug value
    if (I->isDebugValue())
      continue;

    if (terminateSearch(*I))
      break;

    assert((!I->isCall() && !I->isReturn() && !I->isBranch()) &&
           "Cannot put calls, returns or branches in delay slot.");

    if (delayHasHazard(*I, RegDU, IM))
      continue;

    if (TM.getSubtarget<MipsSubtarget>().isTargetNaCl()) {
      // In NaCl, instructions that must be masked are forbidden in delay slots.
      // We only check for loads, stores and SP changes.  Calls, returns and
      // branches are not checked because non-NaCl targets never put them in
      // delay slots.
      unsigned AddrIdx;
      if ((isBasePlusOffsetMemoryAccess(I->getOpcode(), &AddrIdx)
           && baseRegNeedsLoadStoreMask(I->getOperand(AddrIdx).getReg()))
          || I->modifiesRegister(Mips::SP, TM.getRegisterInfo()))
        continue;
    }

    Filler = I;
    return true;
  }

  return false;
}
bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
                         RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot,
                         IterTy &Filler) const {
  for (IterTy I = Begin; I != End; ++I) {
    // skip debug value
    if (I->isDebugValue())
      continue;

    if (terminateSearch(*I))
      break;

    assert((!I->isCall() && !I->isReturn() && !I->isBranch()) &&
           "Cannot put calls, returns or branches in delay slot.");

    if (delayHasHazard(*I, RegDU, IM))
      continue;

    const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
    if (STI.isTargetNaCl()) {
      // In NaCl, instructions that must be masked are forbidden in delay slots.
      // We only check for loads, stores and SP changes.  Calls, returns and
      // branches are not checked because non-NaCl targets never put them in
      // delay slots.
      unsigned AddrIdx;
      if ((isBasePlusOffsetMemoryAccess(I->getOpcode(), &AddrIdx) &&
           baseRegNeedsLoadStoreMask(I->getOperand(AddrIdx).getReg())) ||
          I->modifiesRegister(Mips::SP, STI.getRegisterInfo()))
        continue;
    }

    bool InMicroMipsMode = STI.inMicroMipsMode();
    const MipsInstrInfo *TII = STI.getInstrInfo();
    unsigned Opcode = (*Slot).getOpcode();
    if (InMicroMipsMode && TII->GetInstSizeInBytes(&(*I)) == 2 &&
        (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
         Opcode == Mips::PseudoReturn))
      continue;

    Filler = I;
    return true;
  }

  return false;
}
Ejemplo n.º 4
0
bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
                         RegDefsUses &RegDU, InspectMemInstr& IM,
                         IterTy &Filler) const {
  for (IterTy I = Begin; I != End; ++I) {
    // skip debug value
    if (I->isDebugValue())
      continue;

    // @LOCALMOD-START
    // Don't put in delay slot instructions that could be masked.
    // Should not allow:
    // ERET, DERET or WAIT, PAUSE. Need to add these to instruction
    // list. TBD.
    if (Triple(TM.getTargetTriple()).isOSNaCl()) {
      int Dummy;
      if (terminateSearch(*I) || (IsDangerousLoad(*I, &Dummy)
                              || IsDangerousStore(*I, &Dummy)
                              || I->modifiesRegister(Mips::SP,
                                                     TM.getRegisterInfo())))
        break;
    } else {
      if (terminateSearch(*I))
        break;
    }
    // @LOCALMOD-END

    assert((!I->isCall() && !I->isReturn() && !I->isBranch()) &&
           "Cannot put calls, returns or branches in delay slot.");

    if (delayHasHazard(*I, RegDU, IM))
      continue;

    Filler = I;
    return true;
  }

  return false;
}