//===-- DelaySlotFiller.cpp - MBlaze delay slot filler --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// A pass that attempts to fill instructions with delay slots. If no
// instructions can be moved into the delay slot then a NOP is placed there.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "delay-slot-filler"

#include "MBlaze.h"
#include "MBlazeTargetMachine.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

STATISTIC(FilledSlots, "Number of delay slots filled");

namespace llvm {
cl::opt<bool> DisableDelaySlotFiller(
  "disable-mblaze-delay-filler",
  cl::init(false),
  cl::desc("Disable the MBlaze delay slot filter."),
  cl::Hidden);
}

namespace {
  struct Filler : public MachineFunctionPass {

    TargetMachine &TM;
    const TargetInstrInfo *TII;

    static char ID;
    Filler(TargetMachine &tm)
      : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }

    virtual const char *getPassName() const {
      return "MBlaze Delay Slot Filler";
    }

    bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
    bool runOnMachineFunction(MachineFunction &F) {
      bool Changed = false;
      for (MachineFunction::iterator FI = F.begin(), FE = F.end();
           FI != FE; ++FI)
        Changed |= runOnMachineBasicBlock(*FI);
      return Changed;
    }

  };
  char Filler::ID = 0;
} // end of anonymous namespace

static bool hasImmInstruction(MachineBasicBlock::iterator &candidate) {
    // Any instruction with an immediate mode operand greater than
    // 16-bits requires an implicit IMM instruction.
    unsigned numOper = candidate->getNumOperands();
    for (unsigned op = 0; op < numOper; ++op) {
        MachineOperand &mop = candidate->getOperand(op);

        // The operand requires more than 16-bits to represent.
        if (mop.isImm() && (mop.getImm() < -0x8000 || mop.getImm() > 0x7fff))
          return true;

        // We must assume that unknown immediate values require more than
        // 16-bits to represent.
        if (mop.isGlobal() || mop.isSymbol())
          return true;

        // FIXME: we could probably check to see if the FP value happens
        //        to not need an IMM instruction. For now we just always
        //        assume that FP values do.
        if (mop.isFPImm())
          return true;
    }

    return false;
}

static unsigned getLastRealOperand(MachineBasicBlock::iterator &instr) {
  switch (instr->getOpcode()) {
  default: return instr->getNumOperands();

  // These instructions have a variable number of operands but the first two
  // are the "real" operands that we care about during hazard detection.
  case MBlaze::BRLID:
  case MBlaze::BRALID:
  case MBlaze::BRLD:
  case MBlaze::BRALD:
    return 2;
  }
}

static bool delayHasHazard(MachineBasicBlock::iterator &candidate,
                           MachineBasicBlock::iterator &slot) {
  // Hazard check
  MachineBasicBlock::iterator a = candidate;
  MachineBasicBlock::iterator b = slot;
  TargetInstrDesc desc = candidate->getDesc();

  // MBB layout:-
  //    candidate := a0 = operation(a1, a2)
  //    ...middle bit...
  //    slot := b0 = operation(b1, b2)

  // Possible hazards:-/
  // 1. a1 or a2 was written during the middle bit
  // 2. a0 was read or written during the middle bit
  // 3. a0 is one or more of {b0, b1, b2}
  // 4. b0 is one or more of {a1, a2}
  // 5. a accesses memory, and the middle bit
  //    contains a store operation.
  bool a_is_memory = desc.mayLoad() || desc.mayStore();

  // Determine the number of operands in the slot instruction and in the
  // candidate instruction.
  const unsigned aend = getLastRealOperand(a);
  const unsigned bend = getLastRealOperand(b);

  // Check hazards type 1, 2 and 5 by scanning the middle bit
  MachineBasicBlock::iterator m = a;
  for (++m; m != b; ++m) {
    for (unsigned aop = 0; aop<aend; ++aop) {
      bool aop_is_reg = a->getOperand(aop).isReg();
      if (!aop_is_reg) continue;

      bool aop_is_def = a->getOperand(aop).isDef();
      unsigned aop_reg = a->getOperand(aop).getReg();

      const unsigned mend = getLastRealOperand(m);
      for (unsigned mop = 0; mop<mend; ++mop) {
        bool mop_is_reg = m->getOperand(mop).isReg();
        if (!mop_is_reg) continue;

        bool mop_is_def = m->getOperand(mop).isDef();
        unsigned mop_reg = m->getOperand(mop).getReg();

        if (aop_is_def && (mop_reg == aop_reg))
            return true; // Hazard type 2, because aop = a0
        else if (mop_is_def && (mop_reg == aop_reg))
            return true; // Hazard type 1, because aop in {a1, a2}
      }
    }

    // Check hazard type 5
    if (a_is_memory && m->getDesc().mayStore())
      return true;
  }

  // Check hazard type 3 & 4
  for (unsigned aop = 0; aop<aend; ++aop) {
    if (a->getOperand(aop).isReg()) {
      unsigned aop_reg = a->getOperand(aop).getReg();

      for (unsigned bop = 0; bop<bend; ++bop) {
        if (b->getOperand(bop).isReg() && !b->getOperand(bop).isImplicit()) {
          unsigned bop_reg = b->getOperand(bop).getReg();
          if (aop_reg == bop_reg)
            return true;
        }
      }
    }
  }

  return false;
}

static bool isDelayFiller(MachineBasicBlock &MBB,
                          MachineBasicBlock::iterator candidate) {
  if (candidate == MBB.begin())
    return false;

  TargetInstrDesc brdesc = (--candidate)->getDesc();
  return (brdesc.hasDelaySlot());
}

static bool hasUnknownSideEffects(MachineBasicBlock::iterator &I) {
  if (!I->hasUnmodeledSideEffects())
    return false;

  unsigned op = I->getOpcode();
  if (op == MBlaze::ADDK || op == MBlaze::ADDIK ||
      op == MBlaze::ADDC || op == MBlaze::ADDIC ||
      op == MBlaze::ADDKC || op == MBlaze::ADDIKC ||
      op == MBlaze::RSUBK || op == MBlaze::RSUBIK ||
      op == MBlaze::RSUBC || op == MBlaze::RSUBIC ||
      op == MBlaze::RSUBKC || op == MBlaze::RSUBIKC)
    return false;

  return true;
}

static MachineBasicBlock::iterator
findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator slot) {
  MachineBasicBlock::iterator I = slot;
  while (true) {
    if (I == MBB.begin())
      break;

    --I;
    TargetInstrDesc desc = I->getDesc();
    if (desc.hasDelaySlot() || desc.isBranch() || isDelayFiller(MBB,I) ||
        desc.isCall() || desc.isReturn() || desc.isBarrier() ||
        hasUnknownSideEffects(I))
      break;

    if (hasImmInstruction(I) || delayHasHazard(I,slot))
      continue;

    return I;
  }

  return MBB.end();
}

/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
/// Currently, we fill delay slots with NOPs. We assume there is only one
/// delay slot per delayed instruction.
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
  bool Changed = false;
  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
    if (I->getDesc().hasDelaySlot()) {
      MachineBasicBlock::iterator D = MBB.end();
      MachineBasicBlock::iterator J = I;

      if (!DisableDelaySlotFiller)
        D = findDelayInstr(MBB,I);

      ++FilledSlots;
      Changed = true;

      if (D == MBB.end())
        BuildMI(MBB, ++J, I->getDebugLoc(), TII->get(MBlaze::NOP));
      else
        MBB.splice(++J, &MBB, D);
    }
  return Changed;
}

/// createMBlazeDelaySlotFillerPass - Returns a pass that fills in delay
/// slots in MBlaze MachineFunctions
FunctionPass *llvm::createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &tm) {
  return new Filler(tm);
}

