//===----------------------- LSUnit.cpp --------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
///
/// A Load-Store Unit for the llvm-mca tool.
///
//===----------------------------------------------------------------------===//

#include "llvm/MCA/HardwareUnits/LSUnit.h"
#include "llvm/MCA/Instruction.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

#define DEBUG_TYPE "llvm-mca"

namespace llvm {
namespace mca {

LSUnit::LSUnit(const MCSchedModel &SM, unsigned LQ, unsigned SQ,
               bool AssumeNoAlias)
    : LQ_Size(LQ), SQ_Size(SQ), NoAlias(AssumeNoAlias) {
  if (SM.hasExtraProcessorInfo()) {
    const MCExtraProcessorInfo &EPI = SM.getExtraProcessorInfo();
    if (!LQ_Size && EPI.LoadQueueID) {
      const MCProcResourceDesc &LdQDesc = *SM.getProcResource(EPI.LoadQueueID);
      LQ_Size = LdQDesc.BufferSize;
    }

    if (!SQ_Size && EPI.StoreQueueID) {
      const MCProcResourceDesc &StQDesc = *SM.getProcResource(EPI.StoreQueueID);
      SQ_Size = StQDesc.BufferSize;
    }
  }
}

#ifndef NDEBUG
void LSUnit::dump() const {
  dbgs() << "[LSUnit] LQ_Size = " << LQ_Size << '\n';
  dbgs() << "[LSUnit] SQ_Size = " << SQ_Size << '\n';
  dbgs() << "[LSUnit] NextLQSlotIdx = " << LoadQueue.size() << '\n';
  dbgs() << "[LSUnit] NextSQSlotIdx = " << StoreQueue.size() << '\n';
}
#endif

void LSUnit::assignLQSlot(unsigned Index) {
  assert(!isLQFull());
  assert(LoadQueue.count(Index) == 0);

  LLVM_DEBUG(dbgs() << "[LSUnit] - AssignLQSlot <Idx=" << Index
                    << ",slot=" << LoadQueue.size() << ">\n");
  LoadQueue.insert(Index);
}

void LSUnit::assignSQSlot(unsigned Index) {
  assert(!isSQFull());
  assert(StoreQueue.count(Index) == 0);

  LLVM_DEBUG(dbgs() << "[LSUnit] - AssignSQSlot <Idx=" << Index
                    << ",slot=" << StoreQueue.size() << ">\n");
  StoreQueue.insert(Index);
}

void LSUnit::dispatch(const InstRef &IR) {
  const InstrDesc &Desc = IR.getInstruction()->getDesc();
  unsigned IsMemBarrier = Desc.HasSideEffects;
  assert((Desc.MayLoad || Desc.MayStore) && "Not a memory operation!");

  const unsigned Index = IR.getSourceIndex();
  if (Desc.MayLoad) {
    if (IsMemBarrier)
      LoadBarriers.insert(Index);
    assignLQSlot(Index);
  }

  if (Desc.MayStore) {
    if (IsMemBarrier)
      StoreBarriers.insert(Index);
    assignSQSlot(Index);
  }
}

LSUnit::Status LSUnit::isAvailable(const InstRef &IR) const {
  const InstrDesc &Desc = IR.getInstruction()->getDesc();
  if (Desc.MayLoad && isLQFull())
    return LSUnit::LSU_LQUEUE_FULL;
  if (Desc.MayStore && isSQFull())
    return LSUnit::LSU_SQUEUE_FULL;
  return LSUnit::LSU_AVAILABLE;
}

unsigned LSUnit::isReady(const InstRef &IR) const {
  const InstrDesc &Desc = IR.getInstruction()->getDesc();
  const unsigned Index = IR.getSourceIndex();
  bool IsALoad = Desc.MayLoad;
  bool IsAStore = Desc.MayStore;
  assert((IsALoad || IsAStore) && "Not a memory operation!");
  assert((!IsALoad || LoadQueue.count(Index) == 1) && "Load not in queue!");
  assert((!IsAStore || StoreQueue.count(Index) == 1) && "Store not in queue!");

  if (IsALoad && !LoadBarriers.empty()) {
    unsigned LoadBarrierIndex = *LoadBarriers.begin();
    // A younger load cannot pass a older load barrier.
    if (Index > LoadBarrierIndex)
      return LoadBarrierIndex;
    // A load barrier cannot pass a older load.
    if (Index == LoadBarrierIndex && Index != *LoadQueue.begin())
      return *LoadQueue.begin();
  }

  if (IsAStore && !StoreBarriers.empty()) {
    unsigned StoreBarrierIndex = *StoreBarriers.begin();
    // A younger store cannot pass a older store barrier.
    if (Index > StoreBarrierIndex)
      return StoreBarrierIndex;
    // A store barrier cannot pass a older store.
    if (Index == StoreBarrierIndex && Index != *StoreQueue.begin())
      return *StoreQueue.begin();
  }

  // A load may not pass a previous store unless flag 'NoAlias' is set.
  // A load may pass a previous load.
  if (NoAlias && IsALoad)
    return Index;

  if (StoreQueue.size()) {
    // A load may not pass a previous store.
    // A store may not pass a previous store.
    if (Index > *StoreQueue.begin())
      return *StoreQueue.begin();
  }

  // Okay, we are older than the oldest store in the queue.
  // If there are no pending loads, then we can say for sure that this
  // instruction is ready.
  if (isLQEmpty())
    return Index;

  // Check if there are no older loads.
  if (Index <= *LoadQueue.begin())
    return Index;

  // There is at least one younger load.
  //
  // A load may pass a previous load.
  if (IsALoad)
    return Index;

  // A store may not pass a previous load.
  return *LoadQueue.begin();
}

void LSUnit::onInstructionExecuted(const InstRef &IR) {
  const InstrDesc &Desc = IR.getInstruction()->getDesc();
  const unsigned Index = IR.getSourceIndex();
  bool IsALoad = Desc.MayLoad;
  bool IsAStore = Desc.MayStore;

  if (IsALoad) {
    if (LoadQueue.erase(Index)) {
      LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
                        << " has been removed from the load queue.\n");
    }
    if (!LoadBarriers.empty() && Index == *LoadBarriers.begin()) {
      LLVM_DEBUG(
          dbgs() << "[LSUnit]: Instruction idx=" << Index
                 << " has been removed from the set of load barriers.\n");
      LoadBarriers.erase(Index);
    }
  }

  if (IsAStore) {
    if (StoreQueue.erase(Index)) {
      LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
                        << " has been removed from the store queue.\n");
    }

    if (!StoreBarriers.empty() && Index == *StoreBarriers.begin()) {
      LLVM_DEBUG(
          dbgs() << "[LSUnit]: Instruction idx=" << Index
                 << " has been removed from the set of store barriers.\n");
      StoreBarriers.erase(Index);
    }
  }
}

} // namespace mca
} // namespace llvm
