//===--------------------- Backend.cpp --------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
///
/// Implementation of class Backend which emulates an hardware OoO backend.
///
//===----------------------------------------------------------------------===//

#include "Backend.h"
#include "HWEventListener.h"
#include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/Support/Debug.h"

namespace mca {

#define DEBUG_TYPE "llvm-mca"

using namespace llvm;

void Backend::addEventListener(HWEventListener *Listener) {
  if (Listener)
    Listeners.insert(Listener);
}

void Backend::runCycle(unsigned Cycle) {
  notifyCycleBegin(Cycle);

  if (!SM.hasNext()) {
    notifyCycleEnd(Cycle);
    return;
  }

  InstRef IR = SM.peekNext();
  const InstrDesc *Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
  while (DU->isAvailable(Desc->NumMicroOps) && DU->canDispatch(*Desc)) {
    Instruction *NewIS = IB->createInstruction(STI, *DU, IR.first, *IR.second);
    Instructions[IR.first] = std::unique_ptr<Instruction>(NewIS);
    NewIS->setRCUTokenID(DU->dispatch(IR.first, NewIS));

    // If this is a zero latency instruction, then we don't need to dispatch
    // it. Instead, we can mark it as executed.
    if (NewIS->isZeroLatency())
      notifyInstructionExecuted(IR.first);

    // Check if we have dispatched all the instructions.
    SM.updateNext();
    if (!SM.hasNext())
      break;

    // Prepare for the next round.
    IR = SM.peekNext();
    Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
  }

  notifyCycleEnd(Cycle);
}

void Backend::notifyCycleBegin(unsigned Cycle) {
  DEBUG(dbgs() << "[E] Cycle begin: " << Cycle << '\n');
  for (HWEventListener *Listener : Listeners)
    Listener->onCycleBegin(Cycle);

  DU->cycleEvent(Cycle);
  HWS->cycleEvent(Cycle);
}

void Backend::notifyInstructionDispatched(unsigned Index) {
  DEBUG(dbgs() << "[E] Instruction Dispatched: " << Index << '\n');
  for (HWEventListener *Listener : Listeners)
    Listener->onInstructionDispatched(Index);
}

void Backend::notifyInstructionReady(unsigned Index) {
  DEBUG(dbgs() << "[E] Instruction Ready: " << Index << '\n');
  for (HWEventListener *Listener : Listeners)
    Listener->onInstructionReady(Index);
}

void Backend::notifyInstructionIssued(
    unsigned Index, const ArrayRef<std::pair<ResourceRef, unsigned>> &Used) {
  DEBUG(
    dbgs() << "[E] Instruction Issued: " << Index << '\n';
    for (const std::pair<ResourceRef, unsigned> &Resource : Used) {
      dbgs() << "[E] Resource Used: [" << Resource.first.first << '.'
             << Resource.first.second << "]\n";
      dbgs() << "           cycles: " << Resource.second << '\n';
    }
  );

  for (HWEventListener *Listener : Listeners)
    Listener->onInstructionIssued(Index, Used);
}

void Backend::notifyInstructionExecuted(unsigned Index) {
  DEBUG(dbgs() << "[E] Instruction Executed: " << Index << '\n');
  for (HWEventListener *Listener : Listeners)
    Listener->onInstructionExecuted(Index);

  const Instruction &IS = *Instructions[Index];
  DU->onInstructionExecuted(IS.getRCUTokenID());
}

void Backend::notifyInstructionRetired(unsigned Index) {
  DEBUG(dbgs() << "[E] Instruction Retired: " << Index << '\n');
  for (HWEventListener *Listener : Listeners)
    Listener->onInstructionRetired(Index);

  const Instruction &IS = *Instructions[Index];
  DU->invalidateRegisterMappings(IS);
  Instructions.erase(Index);
}

void Backend::notifyResourceAvailable(const ResourceRef &RR) {
  DEBUG(dbgs() << "[E] Resource Available: [" << RR.first << '.' << RR.second
               << "]\n");
  for (HWEventListener *Listener : Listeners)
    Listener->onResourceAvailable(RR);
}

void Backend::notifyCycleEnd(unsigned Cycle) {
  DEBUG(dbgs() << "[E] Cycle end: " << Cycle << "\n\n");
  for (HWEventListener *Listener : Listeners)
    Listener->onCycleEnd(Cycle);
}

} // namespace mca.
