//===-- SchedInfo.cpp - Generic code to support target schedulers ----------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the generic part of a Scheduler description for a
// target.  This functionality is defined in the llvm/Target/SchedInfo.h file.
//
//===----------------------------------------------------------------------===//

#include "llvm/Config/alloca.h"
#include "llvm/Target/TargetSchedInfo.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <iostream>
using namespace llvm;

resourceId_t llvm::CPUResource::nextId = 0;
static std::vector<CPUResource*> *CPUResourceMap = 0;

CPUResource::CPUResource(const std::string& resourceName, int maxUsers)
    : rname(resourceName), rid(nextId++), maxNumUsers(maxUsers) {
  if(!CPUResourceMap)
    CPUResourceMap = new std::vector<CPUResource*>;

  //Put Resource in the map
  CPUResourceMap->push_back(this);
}

///Get CPUResource if you only have the resource ID
CPUResource* CPUResource::getCPUResource(resourceId_t id) {
  return (*CPUResourceMap)[id];
}

// Check if fromRVec and toRVec have *any* common entries.
// Assume the vectors are sorted in increasing order.
// Algorithm copied from function set_intersection() for sorted ranges
// (stl_algo.h).
//
inline static bool
RUConflict(const std::vector<resourceId_t>& fromRVec,
           const std::vector<resourceId_t>& toRVec)
{

  unsigned fN = fromRVec.size(), tN = toRVec.size();
  unsigned fi = 0, ti = 0;

  while (fi < fN && ti < tN) {
    if (fromRVec[fi] < toRVec[ti])
      ++fi;
    else if (toRVec[ti] < fromRVec[fi])
      ++ti;
    else
      return true;
  }
  return false;
}


static CycleCount_t
ComputeMinGap(const InstrRUsage &fromRU,
              const InstrRUsage &toRU)
{
  CycleCount_t minGap = 0;

  if (fromRU.numBubbles > 0)
    minGap = fromRU.numBubbles;

  if (minGap < fromRU.numCycles) {
    // only need to check from cycle `minGap' onwards
    for (CycleCount_t gap=minGap; gap <= fromRU.numCycles-1; gap++) {
      // check if instr. #2 can start executing `gap' cycles after #1
      // by checking for resource conflicts in each overlapping cycle
      CycleCount_t numOverlap =std::min(fromRU.numCycles - gap, toRU.numCycles);
      for (CycleCount_t c = 0; c <= numOverlap-1; c++)
        if (RUConflict(fromRU.resourcesByCycle[gap + c],
                       toRU.resourcesByCycle[c])) {
          // conflict found so minGap must be more than `gap'
          minGap = gap+1;
          break;
        }
    }
  }

  return minGap;
}


//---------------------------------------------------------------------------
// class TargetSchedInfo
// Interface to machine description for instruction scheduling
//---------------------------------------------------------------------------

TargetSchedInfo::TargetSchedInfo(const TargetMachine&    tgt,
                                 int                     NumSchedClasses,
                                 const InstrClassRUsage* ClassRUsages,
                                 const InstrRUsageDelta* UsageDeltas,
                                 const InstrIssueDelta*  IssueDeltas,
                                 unsigned NumUsageDeltas,
                                 unsigned NumIssueDeltas)
  : target(tgt),
    numSchedClasses(NumSchedClasses), mii(tgt.getInstrInfo()),
    classRUsages(ClassRUsages), usageDeltas(UsageDeltas),
    issueDeltas(IssueDeltas), numUsageDeltas(NumUsageDeltas),
    numIssueDeltas(NumIssueDeltas)
{}

void
TargetSchedInfo::initializeResources()
{
  assert(MAX_NUM_SLOTS >= (int)getMaxNumIssueTotal() &&
         "Insufficient slots for static data! Increase MAX_NUM_SLOTS");

  // First, compute common resource usage info for each class because
  // most instructions will probably behave the same as their class.
  // Cannot allocate a vector of InstrRUsage so new each one.
  //
  std::vector<InstrRUsage> instrRUForClasses;
  instrRUForClasses.resize(numSchedClasses);
  for (InstrSchedClass sc = 0; sc < numSchedClasses; sc++) {
    // instrRUForClasses.push_back(new InstrRUsage);
    instrRUForClasses[sc].setMaxSlots(getMaxNumIssueTotal());
    instrRUForClasses[sc].setTo(classRUsages[sc]);
  }

  computeInstrResources(instrRUForClasses);
  computeIssueGaps(instrRUForClasses);
}


void
TargetSchedInfo::computeInstrResources(const std::vector<InstrRUsage>&
                                        instrRUForClasses) {
  int numOpCodes =  mii->getNumOpcodes();
  instrRUsages.resize(numOpCodes);

  // First get the resource usage information from the class resource usages.
  for (MachineOpCode op = 0; op < numOpCodes; ++op) {
    InstrSchedClass sc = getSchedClass(op);
    assert(sc < numSchedClasses);
    instrRUsages[op] = instrRUForClasses[sc];
  }

  // Now, modify the resource usages as specified in the deltas.
  for (unsigned i = 0; i < numUsageDeltas; ++i) {
    MachineOpCode op = usageDeltas[i].opCode;
    assert(op < numOpCodes);
    instrRUsages[op].addUsageDelta(usageDeltas[i]);
  }

  // Then modify the issue restrictions as specified in the deltas.
  for (unsigned i = 0; i < numIssueDeltas; ++i) {
    MachineOpCode op = issueDeltas[i].opCode;
    assert(op < numOpCodes);
    instrRUsages[issueDeltas[i].opCode].addIssueDelta(issueDeltas[i]);
  }
}


void
TargetSchedInfo::computeIssueGaps(const std::vector<InstrRUsage>&
                                   instrRUForClasses) {
  int numOpCodes =  mii->getNumOpcodes();
  issueGaps.resize(numOpCodes);
  conflictLists.resize(numOpCodes);

  // First, compute issue gaps between pairs of classes based on common
  // resources usages for each class, because most instruction pairs will
  // usually behave the same as their class.
  //
  int* classPairGaps =
    static_cast<int*>(alloca(sizeof(int) * numSchedClasses * numSchedClasses));
  for (InstrSchedClass fromSC=0; fromSC < numSchedClasses; fromSC++)
    for (InstrSchedClass toSC=0; toSC < numSchedClasses; toSC++) {
      int classPairGap = ComputeMinGap(instrRUForClasses[fromSC],
                                       instrRUForClasses[toSC]);
      classPairGaps[fromSC*numSchedClasses + toSC] = classPairGap;
    }

  // Now, for each pair of instructions, use the class pair gap if both
  // instructions have identical resource usage as their respective classes.
  // If not, recompute the gap for the pair from scratch.

  longestIssueConflict = 0;

  for (MachineOpCode fromOp=0; fromOp < numOpCodes; fromOp++)
    for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++) {
      int instrPairGap =
        (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass)
        ? classPairGaps[getSchedClass(fromOp)*numSchedClasses + getSchedClass(toOp)]
        : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]);

      if (instrPairGap > 0) {
        this->setGap(instrPairGap, fromOp, toOp);
        conflictLists[fromOp].push_back(toOp);
        longestIssueConflict=std::max(longestIssueConflict, instrPairGap);
      }
    }
}


void InstrRUsage::setTo(const InstrClassRUsage& classRU) {
  sameAsClass   = true;
  isSingleIssue = classRU.isSingleIssue;
  breaksGroup   = classRU.breaksGroup;
  numBubbles    = classRU.numBubbles;

  for (unsigned i=0; i < classRU.numSlots; i++) {
    unsigned slot = classRU.feasibleSlots[i];
    assert(slot < feasibleSlots.size() && "Invalid slot specified!");
    this->feasibleSlots[slot] = true;
  }

  numCycles   = classRU.totCycles;
  resourcesByCycle.resize(this->numCycles);

  for (unsigned i=0; i < classRU.numRUEntries; i++)
    for (unsigned c=classRU.V[i].startCycle, NC = c + classRU.V[i].numCycles;
         c < NC; c++)
      this->resourcesByCycle[c].push_back(classRU.V[i].resourceId);

  // Sort each resource usage vector by resourceId_t to speed up conflict
  // checking
  for (unsigned i=0; i < this->resourcesByCycle.size(); i++)
    std::sort(resourcesByCycle[i].begin(), resourcesByCycle[i].end());
}

// Add the extra resource usage requirements specified in the delta.
// Note that a negative value of `numCycles' means one entry for that
// resource should be deleted for each cycle.
//
void InstrRUsage::addUsageDelta(const InstrRUsageDelta &delta) {
  int NC = delta.numCycles;
  sameAsClass = false;

  // resize the resources vector if more cycles are specified
  unsigned maxCycles = this->numCycles;
  maxCycles = std::max(maxCycles, delta.startCycle + abs(NC) - 1);
  if (maxCycles > this->numCycles) {
    this->resourcesByCycle.resize(maxCycles);
    this->numCycles = maxCycles;
  }

  if (NC >= 0)
    for (unsigned c=delta.startCycle, last=c+NC-1; c <= last; c++)
      this->resourcesByCycle[c].push_back(delta.resourceId);
  else
    // Remove the resource from all NC cycles.
    for (unsigned c=delta.startCycle, last=(c-NC)-1; c <= last; c++) {
      // Look for the resource backwards so we remove the last entry
      // for that resource in each cycle.
      std::vector<resourceId_t>& rvec = this->resourcesByCycle[c];
      int r;
      for (r = rvec.size() - 1; r >= 0; r--)
        if (rvec[r] == delta.resourceId) {
          // found last entry for the resource
          rvec.erase(rvec.begin() + r);
          break;
        }
      assert(r >= 0 && "Resource to remove was unused in cycle c!");
    }
}
