//===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements hazard recognizers for scheduling on PowerPC processors.
//
//===----------------------------------------------------------------------===//

#include "PPCHazardRecognizers.h"
#include "PPC.h"
#include "PPCInstrInfo.h"
#include "PPCTargetMachine.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "pre-RA-sched"

bool PPCDispatchGroupSBHazardRecognizer::isLoadAfterStore(SUnit *SU) {
  // FIXME: Move this.
  if (isBCTRAfterSet(SU))
    return true;

  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
  if (!MCID)
    return false;

  if (!MCID->mayLoad())
    return false;

  // SU is a load; for any predecessors in this dispatch group, that are stores,
  // and with which we have an ordering dependency, return true.
  for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
    const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
    if (!PredMCID || !PredMCID->mayStore())
      continue;

    if (!SU->Preds[i].isNormalMemory() && !SU->Preds[i].isBarrier())
      continue;

    for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
      if (SU->Preds[i].getSUnit() == CurGroup[j])
        return true;
  }

  return false; 
}

bool PPCDispatchGroupSBHazardRecognizer::isBCTRAfterSet(SUnit *SU) {
  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
  if (!MCID)
    return false;

  if (!MCID->isBranch())
    return false;

  // SU is a branch; for any predecessors in this dispatch group, with which we
  // have a data dependence and set the counter register, return true.
  for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
    const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
    if (!PredMCID || PredMCID->getSchedClass() != PPC::Sched::IIC_SprMTSPR)
      continue;

    if (SU->Preds[i].isCtrl())
      continue;

    for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
      if (SU->Preds[i].getSUnit() == CurGroup[j])
        return true;
  }

  return false; 
}

// FIXME: Remove this when we don't need this:
namespace llvm { namespace PPC { extern int getNonRecordFormOpcode(uint16_t); } }

// FIXME: A lot of code in PPCDispatchGroupSBHazardRecognizer is P7 specific.

bool PPCDispatchGroupSBHazardRecognizer::mustComeFirst(const MCInstrDesc *MCID,
                                                       unsigned &NSlots) {
  // FIXME: Indirectly, this information is contained in the itinerary, and
  // we should derive it from there instead of separately specifying it
  // here.
  unsigned IIC = MCID->getSchedClass();
  switch (IIC) {
  default:
    NSlots = 1;
    break;
  case PPC::Sched::IIC_IntDivW:
  case PPC::Sched::IIC_IntDivD:
  case PPC::Sched::IIC_LdStLoadUpd:
  case PPC::Sched::IIC_LdStLDU:
  case PPC::Sched::IIC_LdStLFDU:
  case PPC::Sched::IIC_LdStLFDUX:
  case PPC::Sched::IIC_LdStLHA:
  case PPC::Sched::IIC_LdStLHAU:
  case PPC::Sched::IIC_LdStLWA:
  case PPC::Sched::IIC_LdStSTDU:
  case PPC::Sched::IIC_LdStSTFDU:
    NSlots = 2;
    break;
  case PPC::Sched::IIC_LdStLoadUpdX:
  case PPC::Sched::IIC_LdStLDUX:
  case PPC::Sched::IIC_LdStLHAUX:
  case PPC::Sched::IIC_LdStLWARX:
  case PPC::Sched::IIC_LdStLDARX:
  case PPC::Sched::IIC_LdStSTDUX:
  case PPC::Sched::IIC_LdStSTDCX:
  case PPC::Sched::IIC_LdStSTWCX:
  case PPC::Sched::IIC_BrMCRX: // mtcr
  // FIXME: Add sync/isync (here and in the itinerary).
    NSlots = 4;
    break;
  }

  // FIXME: record-form instructions need a different itinerary class.
  if (NSlots == 1 && PPC::getNonRecordFormOpcode(MCID->getOpcode()) != -1)
    NSlots = 2;

  switch (IIC) {
  default:
    // All multi-slot instructions must come first.
    return NSlots > 1;
  case PPC::Sched::IIC_BrCR: // cr logicals
  case PPC::Sched::IIC_SprMFCR:
  case PPC::Sched::IIC_SprMFCRF:
  case PPC::Sched::IIC_SprMTSPR:
    return true;
  }
}

ScheduleHazardRecognizer::HazardType
PPCDispatchGroupSBHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
  if (Stalls == 0 && isLoadAfterStore(SU))
    return NoopHazard;

  return ScoreboardHazardRecognizer::getHazardType(SU, Stalls);
}

bool PPCDispatchGroupSBHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
  unsigned NSlots;
  if (MCID && mustComeFirst(MCID, NSlots) && CurSlots)
    return true;

  return ScoreboardHazardRecognizer::ShouldPreferAnother(SU);
}

unsigned PPCDispatchGroupSBHazardRecognizer::PreEmitNoops(SUnit *SU) {
  // We only need to fill out a maximum of 5 slots here: The 6th slot could
  // only be a second branch, and otherwise the next instruction will start a
  // new group.
  if (isLoadAfterStore(SU) && CurSlots < 6) {
    unsigned Directive =
        DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective();
    // If we're using a special group-terminating nop, then we need only one.
    // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready
    if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
        Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR9)
      return 1;

    return 5 - CurSlots;
  }

  return ScoreboardHazardRecognizer::PreEmitNoops(SU);
}

void PPCDispatchGroupSBHazardRecognizer::EmitInstruction(SUnit *SU) {
  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
  if (MCID) {
    if (CurSlots == 5 || (MCID->isBranch() && CurBranches == 1)) {
      CurGroup.clear();
      CurSlots = CurBranches = 0;
    } else {
      DEBUG(dbgs() << "**** Adding to dispatch group: SU(" <<
                      SU->NodeNum << "): ");
      DEBUG(DAG->dumpNode(SU));

      unsigned NSlots;
      bool MustBeFirst = mustComeFirst(MCID, NSlots);

      // If this instruction must come first, but does not, then it starts a
      // new group.
      if (MustBeFirst && CurSlots) {
        CurSlots = CurBranches = 0;
        CurGroup.clear();
      }

      CurSlots += NSlots;
      CurGroup.push_back(SU);

      if (MCID->isBranch())
        ++CurBranches;
    }
  }

  return ScoreboardHazardRecognizer::EmitInstruction(SU);
}

void PPCDispatchGroupSBHazardRecognizer::AdvanceCycle() {
  return ScoreboardHazardRecognizer::AdvanceCycle();
}

void PPCDispatchGroupSBHazardRecognizer::RecedeCycle() {
  llvm_unreachable("Bottom-up scheduling not supported");
}

void PPCDispatchGroupSBHazardRecognizer::Reset() {
  CurGroup.clear();
  CurSlots = CurBranches = 0;
  return ScoreboardHazardRecognizer::Reset();
}

void PPCDispatchGroupSBHazardRecognizer::EmitNoop() {
  unsigned Directive =
      DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective();
  // If the group has now filled all of its slots, or if we're using a special
  // group-terminating nop, the group is complete.
  // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready
  if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
      Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR9 ||
      CurSlots == 6) {
    CurGroup.clear();
    CurSlots = CurBranches = 0;
  } else {
    CurGroup.push_back(nullptr);
    ++CurSlots;
  }
}

//===----------------------------------------------------------------------===//
// PowerPC 970 Hazard Recognizer
//
// This models the dispatch group formation of the PPC970 processor.  Dispatch
// groups are bundles of up to five instructions that can contain various mixes
// of instructions.  The PPC970 can dispatch a peak of 4 non-branch and one
// branch instruction per-cycle.
//
// There are a number of restrictions to dispatch group formation: some
// instructions can only be issued in the first slot of a dispatch group, & some
// instructions fill an entire dispatch group.  Additionally, only branches can
// issue in the 5th (last) slot.
//
// Finally, there are a number of "structural" hazards on the PPC970.  These
// conditions cause large performance penalties due to misprediction, recovery,
// and replay logic that has to happen.  These cases include setting a CTR and
// branching through it in the same dispatch group, and storing to an address,
// then loading from the same address within a dispatch group.  To avoid these
// conditions, we insert no-op instructions when appropriate.
//
// FIXME: This is missing some significant cases:
//   1. Modeling of microcoded instructions.
//   2. Handling of serialized operations.
//   3. Handling of the esoteric cases in "Resource-based Instruction Grouping".
//

PPCHazardRecognizer970::PPCHazardRecognizer970(const ScheduleDAG &DAG)
    : DAG(DAG) {
  EndDispatchGroup();
}

void PPCHazardRecognizer970::EndDispatchGroup() {
  DEBUG(errs() << "=== Start of dispatch group\n");
  NumIssued = 0;

  // Structural hazard info.
  HasCTRSet = false;
  NumStores = 0;
}


PPCII::PPC970_Unit
PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
                                     bool &isFirst, bool &isSingle,
                                     bool &isCracked,
                                     bool &isLoad, bool &isStore) {
  const MCInstrDesc &MCID = DAG.TII->get(Opcode);

  isLoad  = MCID.mayLoad();
  isStore = MCID.mayStore();

  uint64_t TSFlags = MCID.TSFlags;

  isFirst   = TSFlags & PPCII::PPC970_First;
  isSingle  = TSFlags & PPCII::PPC970_Single;
  isCracked = TSFlags & PPCII::PPC970_Cracked;
  return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask);
}

/// isLoadOfStoredAddress - If we have a load from the previously stored pointer
/// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
bool PPCHazardRecognizer970::
isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
  const Value *LoadValue) const {
  for (unsigned i = 0, e = NumStores; i != e; ++i) {
    // Handle exact and commuted addresses.
    if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])
      return true;

    // Okay, we don't have an exact match, if this is an indexed offset, see if
    // we have overlap (which happens during fp->int conversion for example).
    if (StoreValue[i] == LoadValue) {
      // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check
      // to see if the load and store actually overlap.
      if (StoreOffset[i] < LoadOffset) {
        if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true;
      } else {
        if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true;
      }
    }
  }
  return false;
}

/// getHazardType - We return hazard for any non-branch instruction that would
/// terminate the dispatch group.  We turn NoopHazard for any
/// instructions that wouldn't terminate the dispatch group that would cause a
/// pipeline flush.
ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
getHazardType(SUnit *SU, int Stalls) {
  assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead");

  MachineInstr *MI = SU->getInstr();

  if (MI->isDebugValue())
    return NoHazard;

  unsigned Opcode = MI->getOpcode();
  bool isFirst, isSingle, isCracked, isLoad, isStore;
  PPCII::PPC970_Unit InstrType =
    GetInstrType(Opcode, isFirst, isSingle, isCracked,
                 isLoad, isStore);
  if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;

  // We can only issue a PPC970_First/PPC970_Single instruction (such as
  // crand/mtspr/etc) if this is the first cycle of the dispatch group.
  if (NumIssued != 0 && (isFirst || isSingle))
    return Hazard;

  // If this instruction is cracked into two ops by the decoder, we know that
  // it is not a branch and that it cannot issue if 3 other instructions are
  // already in the dispatch group.
  if (isCracked && NumIssued > 2)
    return Hazard;

  switch (InstrType) {
  default: llvm_unreachable("Unknown instruction type!");
  case PPCII::PPC970_FXU:
  case PPCII::PPC970_LSU:
  case PPCII::PPC970_FPU:
  case PPCII::PPC970_VALU:
  case PPCII::PPC970_VPERM:
    // We can only issue a branch as the last instruction in a group.
    if (NumIssued == 4) return Hazard;
    break;
  case PPCII::PPC970_CRU:
    // We can only issue a CR instruction in the first two slots.
    if (NumIssued >= 2) return Hazard;
    break;
  case PPCII::PPC970_BRU:
    break;
  }

  // Do not allow MTCTR and BCTRL to be in the same dispatch group.
  if (HasCTRSet && Opcode == PPC::BCTRL)
    return NoopHazard;

  // If this is a load following a store, make sure it's not to the same or
  // overlapping address.
  if (isLoad && NumStores && !MI->memoperands_empty()) {
    MachineMemOperand *MO = *MI->memoperands_begin();
    if (isLoadOfStoredAddress(MO->getSize(),
                              MO->getOffset(), MO->getValue()))
      return NoopHazard;
  }

  return NoHazard;
}

void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
  MachineInstr *MI = SU->getInstr();

  if (MI->isDebugValue())
    return;

  unsigned Opcode = MI->getOpcode();
  bool isFirst, isSingle, isCracked, isLoad, isStore;
  PPCII::PPC970_Unit InstrType =
    GetInstrType(Opcode, isFirst, isSingle, isCracked,
                 isLoad, isStore);
  if (InstrType == PPCII::PPC970_Pseudo) return;

  // Update structural hazard information.
  if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true;

  // Track the address stored to.
  if (isStore && NumStores < 4 && !MI->memoperands_empty()) {
    MachineMemOperand *MO = *MI->memoperands_begin();
    StoreSize[NumStores] = MO->getSize();
    StoreOffset[NumStores] = MO->getOffset();
    StoreValue[NumStores] = MO->getValue();
    ++NumStores;
  }

  if (InstrType == PPCII::PPC970_BRU || isSingle)
    NumIssued = 4;  // Terminate a d-group.
  ++NumIssued;

  // If this instruction is cracked into two ops by the decoder, remember that
  // we issued two pieces.
  if (isCracked)
    ++NumIssued;

  if (NumIssued == 5)
    EndDispatchGroup();
}

void PPCHazardRecognizer970::AdvanceCycle() {
  assert(NumIssued < 5 && "Illegal dispatch group!");
  ++NumIssued;
  if (NumIssued == 5)
    EndDispatchGroup();
}

void PPCHazardRecognizer970::Reset() {
  EndDispatchGroup();
}

