//===----- HexagonMCShuffler.cpp - MC bundle shuffling --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This implements the shuffling of insns inside a bundle according to the
// packet formation rules of the Hexagon ISA.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "hexagon-shuffle"

#include "MCTargetDesc/HexagonMCShuffler.h"
#include "Hexagon.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonShuffler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>

using namespace llvm;

static cl::opt<bool>
    DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),
                   cl::desc("Disable Hexagon instruction shuffling"));

void HexagonMCShuffler::init(MCInst &MCB) {
  if (HexagonMCInstrInfo::isBundle(MCB)) {
    MCInst const *Extender = nullptr;
    // Copy the bundle for the shuffling.
    for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
      MCInst &MI = *const_cast<MCInst *>(I.getInst());
      DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode()) << '\n');
      assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo());

      if (!HexagonMCInstrInfo::isImmext(MI)) {
        append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
        Extender = nullptr;
      } else
        Extender = &MI;
    }
  }

  Loc = MCB.getLoc();
  BundleFlags = MCB.getOperand(0).getImm();
}

void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI,
                             bool bInsertAtFront) {
  if (HexagonMCInstrInfo::isBundle(MCB)) {
    if (bInsertAtFront)
      append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
    MCInst const *Extender = nullptr;
    // Copy the bundle for the shuffling.
    for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
      assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo());
      MCInst &MI = *const_cast<MCInst *>(I.getInst());
      if (!HexagonMCInstrInfo::isImmext(MI)) {
        append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
        Extender = nullptr;
      } else
        Extender = &MI;
    }
    if (!bInsertAtFront)
      append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
  }

  Loc = MCB.getLoc();
  BundleFlags = MCB.getOperand(0).getImm();
}

void HexagonMCShuffler::copyTo(MCInst &MCB) {
  MCB.clear();
  MCB.addOperand(MCOperand::createImm(BundleFlags));
  MCB.setLoc(Loc);
  // Copy the results into the bundle.
  for (HexagonShuffler::iterator I = begin(); I != end(); ++I) {

    MCInst const &MI = I->getDesc();
    MCInst const *Extender = I->getExtender();
    if (Extender)
      MCB.addOperand(MCOperand::createInst(Extender));
    MCB.addOperand(MCOperand::createInst(&MI));
  }
}

bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) {
  if (shuffle()) {
    // Copy the results into the bundle.
    copyTo(MCB);
    return true;
  }
  DEBUG(MCB.dump());
  return false;
}

bool llvm::HexagonMCShuffle(MCContext &Context, bool Fatal,
                            MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
                            MCInst &MCB) {
  HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB);

  if (DisableShuffle)
    // Ignore if user chose so.
    return false;

  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
    // There once was a bundle:
    //    BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ...
    //      * %D2<def> = IMPLICIT_DEF; flags:
    //      * %D7<def> = IMPLICIT_DEF; flags:
    // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
    // became empty.
    DEBUG(dbgs() << "Skipping empty bundle");
    return false;
  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
    DEBUG(dbgs() << "Skipping stand-alone insn");
    return false;
  }

  return MCS.reshuffleTo(MCB);
}

bool
llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
                       MCSubtargetInfo const &STI, MCInst &MCB,
                       SmallVector<DuplexCandidate, 8> possibleDuplexes) {
  if (DisableShuffle)
    return false;

  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
    // There once was a bundle:
    //    BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ...
    //      * %D2<def> = IMPLICIT_DEF; flags:
    //      * %D7<def> = IMPLICIT_DEF; flags:
    // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
    // became empty.
    DEBUG(dbgs() << "Skipping empty bundle");
    return false;
  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
    DEBUG(dbgs() << "Skipping stand-alone insn");
    return false;
  }

  bool doneShuffling = false;
  while (possibleDuplexes.size() > 0 && (!doneShuffling)) {
    // case of Duplex Found
    DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
    MCInst Attempt(MCB);
    HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
    HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler
    if (MCS.size() == 1) {                     // case of one duplex
      // copy the created duplex in the shuffler to the bundle
      MCS.copyTo(MCB);
      return false;
    }
    // try shuffle with this duplex
    doneShuffling = MCS.reshuffleTo(MCB);

    if (doneShuffling)
      break;
  }

  if (!doneShuffling) {
    HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
    doneShuffling = MCS.reshuffleTo(MCB); // shuffle
  }
  if (!doneShuffling)
    return true;

  return false;
}

bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
                            MCSubtargetInfo const &STI, MCInst &MCB,
                            MCInst const &AddMI, int fixupCount) {
  if (!HexagonMCInstrInfo::isBundle(MCB))
    return false;

  // if fixups present, make sure we don't insert too many nops that would
  // later prevent an extender from being inserted.
  unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
  if (bundleSize >= HEXAGON_PACKET_SIZE)
    return false;
  bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB);
  if (fixupCount >= 2) {
    if (bhasDuplex) {
      if (bundleSize >= HEXAGON_PACKET_SIZE - 1) {
        return false;
      }
    } else {
      return false;
    }
  } else {
    if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
      return false;
  }

  if (DisableShuffle)
    return false;

  // mgl: temporary code (shuffler doesn't take into account the fact that
  // a duplex takes up two slots.  for example, 3 nops can be put into a packet
  // containing a duplex oversubscribing slots by 1).
  unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB))
                               ? HEXAGON_PACKET_SIZE
                               : HEXAGON_PACKET_SIZE - 1;
  if (bhasDuplex && bundleSize >= maxBundleSize)
    return false;

  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);
  return MCS.reshuffleTo(MCB);
}
