//===-- R600MachineScheduler.cpp - R600 Scheduler Interface -*- C++ -*-----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// \brief R600 Machine Scheduler interface
// TODO: Scheduling is optimised for VLIW4 arch, modify it to support TRANS slot
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "misched"

#include "R600MachineScheduler.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include <set>
#include <iostream>
using namespace llvm;

void R600SchedStrategy::initialize(ScheduleDAGMI *dag) {

  DAG = dag;
  TII = static_cast<const R600InstrInfo*>(DAG->TII);
  TRI = static_cast<const R600RegisterInfo*>(DAG->TRI);
  MRI = &DAG->MRI;
  Available[IDAlu]->clear();
  Available[IDFetch]->clear();
  Available[IDOther]->clear();
  CurInstKind = IDOther;
  CurEmitted = 0;
  OccupedSlotsMask = 15;
  memset(InstructionsGroupCandidate, 0, sizeof(InstructionsGroupCandidate));
  InstKindLimit[IDAlu] = 120; // 120 minus 8 for security


  const AMDGPUSubtarget &ST = DAG->TM.getSubtarget<AMDGPUSubtarget>();
  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD5XXX) {
    InstKindLimit[IDFetch] = 7; // 8 minus 1 for security
  } else {
    InstKindLimit[IDFetch] = 15; // 16 minus 1 for security
  }
}

void R600SchedStrategy::MoveUnits(ReadyQueue *QSrc, ReadyQueue *QDst)
{
  if (QSrc->empty())
    return;
  for (ReadyQueue::iterator I = QSrc->begin(),
      E = QSrc->end(); I != E; ++I) {
    (*I)->NodeQueueId &= ~QSrc->getID();
    QDst->push(*I);
  }
  QSrc->clear();
}

SUnit* R600SchedStrategy::pickNode(bool &IsTopNode) {
  SUnit *SU = 0;
  IsTopNode = true;
  NextInstKind = IDOther;

  // check if we might want to switch current clause type
  bool AllowSwitchToAlu = (CurInstKind == IDOther) ||
      (CurEmitted > InstKindLimit[CurInstKind]) ||
      (Available[CurInstKind]->empty());
  bool AllowSwitchFromAlu = (CurEmitted > InstKindLimit[CurInstKind]) &&
      (!Available[IDFetch]->empty() || !Available[IDOther]->empty());

  if ((AllowSwitchToAlu && CurInstKind != IDAlu) ||
      (!AllowSwitchFromAlu && CurInstKind == IDAlu)) {
    // try to pick ALU
    SU = pickAlu();
    if (SU) {
      if (CurEmitted >  InstKindLimit[IDAlu])
        CurEmitted = 0;
      NextInstKind = IDAlu;
    }
  }

  if (!SU) {
    // try to pick FETCH
    SU = pickOther(IDFetch);
    if (SU)
      NextInstKind = IDFetch;
  }

  // try to pick other
  if (!SU) {
    SU = pickOther(IDOther);
    if (SU)
      NextInstKind = IDOther;
  }

  DEBUG(
      if (SU) {
        dbgs() << "picked node: ";
        SU->dump(DAG);
      } else {
        dbgs() << "NO NODE ";
        for (int i = 0; i < IDLast; ++i) {
          Available[i]->dump();
          Pending[i]->dump();
        }
        for (unsigned i = 0; i < DAG->SUnits.size(); i++) {
          const SUnit &S = DAG->SUnits[i];
          if (!S.isScheduled)
            S.dump(DAG);
        }
      }
  );

  return SU;
}

void R600SchedStrategy::schedNode(SUnit *SU, bool IsTopNode) {

  DEBUG(dbgs() << "scheduled: ");
  DEBUG(SU->dump(DAG));

  if (NextInstKind != CurInstKind) {
    DEBUG(dbgs() << "Instruction Type Switch\n");
    if (NextInstKind != IDAlu)
      OccupedSlotsMask = 15;
    CurEmitted = 0;
    CurInstKind = NextInstKind;
  }

  if (CurInstKind == IDAlu) {
    switch (getAluKind(SU)) {
    case AluT_XYZW:
      CurEmitted += 4;
      break;
    case AluDiscarded:
      break;
    default: {
      ++CurEmitted;
      for (MachineInstr::mop_iterator It = SU->getInstr()->operands_begin(),
          E = SU->getInstr()->operands_end(); It != E; ++It) {
        MachineOperand &MO = *It;
        if (MO.isReg() && MO.getReg() == AMDGPU::ALU_LITERAL_X)
          ++CurEmitted;
      }
    }
    }
  } else {
    ++CurEmitted;
  }


  DEBUG(dbgs() << CurEmitted << " Instructions Emitted in this clause\n");

  if (CurInstKind != IDFetch) {
    MoveUnits(Pending[IDFetch], Available[IDFetch]);
  }
  MoveUnits(Pending[IDOther], Available[IDOther]);
}

void R600SchedStrategy::releaseTopNode(SUnit *SU) {
  int IK = getInstKind(SU);

  DEBUG(dbgs() << IK << " <= ");
  DEBUG(SU->dump(DAG));

  Pending[IK]->push(SU);
}

void R600SchedStrategy::releaseBottomNode(SUnit *SU) {
}

bool R600SchedStrategy::regBelongsToClass(unsigned Reg,
                                          const TargetRegisterClass *RC) const {
  if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
    return RC->contains(Reg);
  } else {
    return MRI->getRegClass(Reg) == RC;
  }
}

R600SchedStrategy::AluKind R600SchedStrategy::getAluKind(SUnit *SU) const {
  MachineInstr *MI = SU->getInstr();

    switch (MI->getOpcode()) {
    case AMDGPU::INTERP_PAIR_XY:
    case AMDGPU::INTERP_PAIR_ZW:
    case AMDGPU::INTERP_VEC_LOAD:
      return AluT_XYZW;
    case AMDGPU::COPY:
      if (TargetRegisterInfo::isPhysicalRegister(MI->getOperand(1).getReg())) {
        // %vregX = COPY Tn_X is likely to be discarded in favor of an
        // assignement of Tn_X to %vregX, don't considers it in scheduling
        return AluDiscarded;
      }
      else if (MI->getOperand(1).isUndef()) {
        // MI will become a KILL, don't considers it in scheduling
        return AluDiscarded;
      }
    default:
      break;
    }

    // Does the instruction take a whole IG ?
    if(TII->isVector(*MI) ||
        TII->isCubeOp(MI->getOpcode()) ||
        TII->isReductionOp(MI->getOpcode()))
      return AluT_XYZW;

    // Is the result already assigned to a channel ?
    unsigned DestSubReg = MI->getOperand(0).getSubReg();
    switch (DestSubReg) {
    case AMDGPU::sub0:
      return AluT_X;
    case AMDGPU::sub1:
      return AluT_Y;
    case AMDGPU::sub2:
      return AluT_Z;
    case AMDGPU::sub3:
      return AluT_W;
    default:
      break;
    }

    // Is the result already member of a X/Y/Z/W class ?
    unsigned DestReg = MI->getOperand(0).getReg();
    if (regBelongsToClass(DestReg, &AMDGPU::R600_TReg32_XRegClass) ||
        regBelongsToClass(DestReg, &AMDGPU::R600_AddrRegClass))
      return AluT_X;
    if (regBelongsToClass(DestReg, &AMDGPU::R600_TReg32_YRegClass))
      return AluT_Y;
    if (regBelongsToClass(DestReg, &AMDGPU::R600_TReg32_ZRegClass))
      return AluT_Z;
    if (regBelongsToClass(DestReg, &AMDGPU::R600_TReg32_WRegClass))
      return AluT_W;
    if (regBelongsToClass(DestReg, &AMDGPU::R600_Reg128RegClass))
      return AluT_XYZW;

    return AluAny;

}

int R600SchedStrategy::getInstKind(SUnit* SU) {
  int Opcode = SU->getInstr()->getOpcode();

  if (TII->isALUInstr(Opcode)) {
    return IDAlu;
  }

  switch (Opcode) {
  case AMDGPU::COPY:
  case AMDGPU::CONST_COPY:
  case AMDGPU::INTERP_PAIR_XY:
  case AMDGPU::INTERP_PAIR_ZW:
  case AMDGPU::INTERP_VEC_LOAD:
  case AMDGPU::DOT4_eg_pseudo:
  case AMDGPU::DOT4_r600_pseudo:
    return IDAlu;
  case AMDGPU::TEX_VTX_CONSTBUF:
  case AMDGPU::TEX_VTX_TEXBUF:
  case AMDGPU::TEX_LD:
  case AMDGPU::TEX_GET_TEXTURE_RESINFO:
  case AMDGPU::TEX_GET_GRADIENTS_H:
  case AMDGPU::TEX_GET_GRADIENTS_V:
  case AMDGPU::TEX_SET_GRADIENTS_H:
  case AMDGPU::TEX_SET_GRADIENTS_V:
  case AMDGPU::TEX_SAMPLE:
  case AMDGPU::TEX_SAMPLE_C:
  case AMDGPU::TEX_SAMPLE_L:
  case AMDGPU::TEX_SAMPLE_C_L:
  case AMDGPU::TEX_SAMPLE_LB:
  case AMDGPU::TEX_SAMPLE_C_LB:
  case AMDGPU::TEX_SAMPLE_G:
  case AMDGPU::TEX_SAMPLE_C_G:
  case AMDGPU::TXD:
  case AMDGPU::TXD_SHADOW:
    return IDFetch;
  default:
    DEBUG(
        dbgs() << "other inst: ";
        SU->dump(DAG);
    );
    return IDOther;
  }
}

class ConstPairs {
private:
  unsigned XYPair;
  unsigned ZWPair;
public:
  ConstPairs(unsigned ReadConst[3]) : XYPair(0), ZWPair(0) {
    for (unsigned i = 0; i < 3; i++) {
      unsigned ReadConstChan = ReadConst[i] & 3;
      unsigned ReadConstIndex = ReadConst[i] & (~3);
      if (ReadConstChan < 2) {
        if (!XYPair) {
          XYPair = ReadConstIndex;
        }
      } else {
        if (!ZWPair) {
          ZWPair = ReadConstIndex;
        }
      }
    }
  }

  bool isCompatibleWith(const ConstPairs& CP) const {
    return (!XYPair || !CP.XYPair || CP.XYPair == XYPair) &&
        (!ZWPair || !CP.ZWPair || CP.ZWPair == ZWPair);
  }
};

static
const ConstPairs getPairs(const R600InstrInfo *TII, const MachineInstr& MI) {
  unsigned ReadConsts[3] = {0, 0, 0};
  R600Operands::Ops OpTable[3][2] = {
    {R600Operands::SRC0, R600Operands::SRC0_SEL},
    {R600Operands::SRC1, R600Operands::SRC1_SEL},
    {R600Operands::SRC2, R600Operands::SRC2_SEL},
  };

  if (!TII->isALUInstr(MI.getOpcode()))
    return ConstPairs(ReadConsts);

  for (unsigned i = 0; i < 3; i++) {
    int SrcIdx = TII->getOperandIdx(MI.getOpcode(), OpTable[i][0]);
    if (SrcIdx < 0)
      break;
    if (MI.getOperand(SrcIdx).getReg() == AMDGPU::ALU_CONST)
      ReadConsts[i] =MI.getOperand(
          TII->getOperandIdx(MI.getOpcode(), OpTable[i][1])).getImm();
  }
  return ConstPairs(ReadConsts);
}

bool
R600SchedStrategy::isBundleable(const MachineInstr& MI) {
  const ConstPairs &MIPair = getPairs(TII, MI);
  for (unsigned i = 0; i < 4; i++) {
    if (!InstructionsGroupCandidate[i])
      continue;
    const ConstPairs &IGPair = getPairs(TII,
        *InstructionsGroupCandidate[i]->getInstr());
    if (!IGPair.isCompatibleWith(MIPair))
      return false;
  }
  return true;
}

SUnit *R600SchedStrategy::PopInst(std::multiset<SUnit *, CompareSUnit> &Q) {
  if (Q.empty())
    return NULL;
  for (std::set<SUnit *, CompareSUnit>::iterator It = Q.begin(), E = Q.end();
      It != E; ++It) {
    SUnit *SU = *It;
    if (isBundleable(*SU->getInstr())) {
      Q.erase(It);
      return SU;
    }
  }
  return NULL;
}

void R600SchedStrategy::LoadAlu() {
  ReadyQueue *QSrc = Pending[IDAlu];
  for (ReadyQueue::iterator I = QSrc->begin(),
        E = QSrc->end(); I != E; ++I) {
      (*I)->NodeQueueId &= ~QSrc->getID();
      AluKind AK = getAluKind(*I);
      AvailableAlus[AK].insert(*I);
    }
    QSrc->clear();
}

void R600SchedStrategy::PrepareNextSlot() {
  DEBUG(dbgs() << "New Slot\n");
  assert (OccupedSlotsMask && "Slot wasn't filled");
  OccupedSlotsMask = 0;
  memset(InstructionsGroupCandidate, 0, sizeof(InstructionsGroupCandidate));
  LoadAlu();
}

void R600SchedStrategy::AssignSlot(MachineInstr* MI, unsigned Slot) {
  unsigned DestReg = MI->getOperand(0).getReg();
  // PressureRegister crashes if an operand is def and used in the same inst
  // and we try to constraint its regclass
  for (MachineInstr::mop_iterator It = MI->operands_begin(),
      E = MI->operands_end(); It != E; ++It) {
    MachineOperand &MO = *It;
    if (MO.isReg() && !MO.isDef() &&
        MO.getReg() == MI->getOperand(0).getReg())
      return;
  }
  // Constrains the regclass of DestReg to assign it to Slot
  switch (Slot) {
  case 0:
    MRI->constrainRegClass(DestReg, &AMDGPU::R600_TReg32_XRegClass);
    break;
  case 1:
    MRI->constrainRegClass(DestReg, &AMDGPU::R600_TReg32_YRegClass);
    break;
  case 2:
    MRI->constrainRegClass(DestReg, &AMDGPU::R600_TReg32_ZRegClass);
    break;
  case 3:
    MRI->constrainRegClass(DestReg, &AMDGPU::R600_TReg32_WRegClass);
    break;
  }
}

SUnit *R600SchedStrategy::AttemptFillSlot(unsigned Slot) {
  static const AluKind IndexToID[] = {AluT_X, AluT_Y, AluT_Z, AluT_W};
  SUnit *SlotedSU = PopInst(AvailableAlus[IndexToID[Slot]]);
  SUnit *UnslotedSU = PopInst(AvailableAlus[AluAny]);
  if (!UnslotedSU) {
    return SlotedSU;
  } else if (!SlotedSU) {
    AssignSlot(UnslotedSU->getInstr(), Slot);
    return UnslotedSU;
  } else {
    //Determine which one to pick (the lesser one)
    if (CompareSUnit()(SlotedSU, UnslotedSU)) {
      AvailableAlus[AluAny].insert(UnslotedSU);
      return SlotedSU;
    } else {
      AvailableAlus[IndexToID[Slot]].insert(SlotedSU);
      AssignSlot(UnslotedSU->getInstr(), Slot);
      return UnslotedSU;
    }
  }
}

bool R600SchedStrategy::isAvailablesAluEmpty() const {
  return Pending[IDAlu]->empty() && AvailableAlus[AluAny].empty() &&
      AvailableAlus[AluT_XYZW].empty() && AvailableAlus[AluT_X].empty() &&
      AvailableAlus[AluT_Y].empty() && AvailableAlus[AluT_Z].empty() &&
      AvailableAlus[AluT_W].empty() && AvailableAlus[AluDiscarded].empty();
}

SUnit* R600SchedStrategy::pickAlu() {
  while (!isAvailablesAluEmpty()) {
    if (!OccupedSlotsMask) {
      // Flush physical reg copies (RA will discard them)
      if (!AvailableAlus[AluDiscarded].empty()) {
        OccupedSlotsMask = 15;
        return PopInst(AvailableAlus[AluDiscarded]);
      }
      // If there is a T_XYZW alu available, use it
      if (!AvailableAlus[AluT_XYZW].empty()) {
        OccupedSlotsMask = 15;
        return PopInst(AvailableAlus[AluT_XYZW]);
      }
    }
    for (unsigned Chan = 0; Chan < 4; ++Chan) {
      bool isOccupied = OccupedSlotsMask & (1 << Chan);
      if (!isOccupied) {
        SUnit *SU = AttemptFillSlot(Chan);
        if (SU) {
          OccupedSlotsMask |= (1 << Chan);
          InstructionsGroupCandidate[Chan] = SU;
          return SU;
        }
      }
    }
    PrepareNextSlot();
  }
  return NULL;
}

SUnit* R600SchedStrategy::pickOther(int QID) {
  SUnit *SU = 0;
  ReadyQueue *AQ = Available[QID];

  if (AQ->empty()) {
    MoveUnits(Pending[QID], AQ);
  }
  if (!AQ->empty()) {
    SU = *AQ->begin();
    AQ->remove(AQ->begin());
  }
  return SU;
}

