//===--------- HexagonCopyHoisting.cpp - Hexagon Copy Hoisting  ----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// The purpose of this pass is to move the copy instructions that are
// present in all the successor of a basic block (BB) to the end of BB.
//===----------------------------------------------------------------------===//

#include "HexagonTargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "CopyHoist"

using namespace llvm;

static cl::opt<std::string> CPHoistFn("cphoistfn", cl::Hidden, cl::desc(""),
                                      cl::init(""));

namespace llvm {
void initializeHexagonCopyHoistingPass(PassRegistry &Registry);
FunctionPass *createHexagonCopyHoisting();
} // namespace llvm

namespace {

class HexagonCopyHoisting : public MachineFunctionPass {

public:
  static char ID;
  HexagonCopyHoisting() : MachineFunctionPass(ID), MFN(nullptr), MRI(nullptr) {
    initializeHexagonCopyHoistingPass(*PassRegistry::getPassRegistry());
  }

  StringRef getPassName() const override { return "Hexagon Copy Hoisting"; }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<SlotIndexes>();
    AU.addRequired<LiveIntervals>();
    AU.addPreserved<SlotIndexes>();
    AU.addPreserved<LiveIntervals>();
    AU.addRequired<MachineDominatorTree>();
    AU.addPreserved<MachineDominatorTree>();
    MachineFunctionPass::getAnalysisUsage(AU);
  }

  bool runOnMachineFunction(MachineFunction &Fn) override;
  void collectCopyInst();
  void addMItoCopyList(MachineInstr *MI);
  bool analyzeCopy(MachineBasicBlock *BB);
  bool isSafetoMove(MachineInstr *CandMI);
  void moveCopyInstr(MachineBasicBlock *DestBB,
                     std::pair<Register, Register> Key, MachineInstr *MI);

  MachineFunction *MFN;
  MachineRegisterInfo *MRI;
  std::vector<DenseMap<std::pair<Register, Register>, MachineInstr *>>
      CopyMIList;
};

} // namespace

char HexagonCopyHoisting::ID = 0;

namespace llvm {
char &HexagonCopyHoistingID = HexagonCopyHoisting::ID;
} // namespace llvm

bool HexagonCopyHoisting::runOnMachineFunction(MachineFunction &Fn) {

  if ((CPHoistFn != "") && (CPHoistFn != Fn.getFunction().getName()))
    return false;

  MFN = &Fn;
  MRI = &Fn.getRegInfo();

  LLVM_DEBUG(dbgs() << "\nCopy Hoisting:" << "\'" << Fn.getName() << "\'\n");

  CopyMIList.clear();
  CopyMIList.resize(Fn.getNumBlockIDs());

  // Traverse through all basic blocks and collect copy instructions.
  collectCopyInst();

  // Traverse through the basic blocks again and move the COPY instructions
  // that are present in all the successors of BB to BB.
  bool Changed = false;
  for (MachineBasicBlock *BB : post_order(&Fn)) {
    if (!BB->empty()) {
      if (BB->pred_size() != 1)
        continue;
      auto &BBCopyInst = CopyMIList[BB->getNumber()];
      if (BBCopyInst.size() > 0)
        Changed |= analyzeCopy(*BB->pred_begin());
    }
  }
  // Re-compute liveness
  if (Changed) {
    LiveIntervals &LIS = getAnalysis<LiveIntervals>();
    SlotIndexes *SI = LIS.getSlotIndexes();
    SI->releaseMemory();
    SI->runOnMachineFunction(Fn);
    LIS.releaseMemory();
    LIS.runOnMachineFunction(Fn);
  }
  return Changed;
}

//===----------------------------------------------------------------------===//
// Save all COPY instructions for each basic block in CopyMIList vector.
//===----------------------------------------------------------------------===//
void HexagonCopyHoisting::collectCopyInst() {
  for (MachineBasicBlock &BB : *MFN) {
#ifndef NDEBUG
    auto &BBCopyInst = CopyMIList[BB.getNumber()];
    LLVM_DEBUG(dbgs() << "Visiting BB#" << BB.getNumber() << ":\n");
#endif

    for (MachineInstr &MI : BB) {
      if (MI.getOpcode() == TargetOpcode::COPY)
        addMItoCopyList(&MI);
    }
    LLVM_DEBUG(dbgs() << "\tNumber of copies: " << BBCopyInst.size() << "\n");
  }
}

void HexagonCopyHoisting::addMItoCopyList(MachineInstr *MI) {
  unsigned BBNum = MI->getParent()->getNumber();
  auto &BBCopyInst = CopyMIList[BBNum];
  Register DstReg = MI->getOperand(0).getReg();
  Register SrcReg = MI->getOperand(1).getReg();

  if (!Register::isVirtualRegister(DstReg) ||
      !Register::isVirtualRegister(SrcReg) ||
      MRI->getRegClass(DstReg) != &Hexagon::IntRegsRegClass ||
      MRI->getRegClass(SrcReg) != &Hexagon::IntRegsRegClass)
    return;

  BBCopyInst.insert(std::pair(std::pair(SrcReg, DstReg), MI));
#ifndef NDEBUG
  LLVM_DEBUG(dbgs() << "\tAdding Copy Instr to the list: " << MI << "\n");
  for (auto II : BBCopyInst) {
    MachineInstr *TempMI = II.getSecond();
    LLVM_DEBUG(dbgs() << "\tIn the list: " << TempMI << "\n");
  }
#endif
}

//===----------------------------------------------------------------------===//
// Look at the COPY instructions of all the successors of BB. If the same
// instruction is present in every successor and can be safely moved,
// pull it into BB.
//===----------------------------------------------------------------------===//
bool HexagonCopyHoisting::analyzeCopy(MachineBasicBlock *BB) {

  bool Changed = false;
  if (BB->succ_size() < 2)
    return false;

  for (MachineBasicBlock *SB : BB->successors()) {
    if (SB->pred_size() != 1 || SB->isEHPad() || SB->hasAddressTaken())
      return false;
  }

  MachineBasicBlock *SBB1 = *BB->succ_begin();
  auto &BBCopyInst1 = CopyMIList[SBB1->getNumber()];

  for (auto II : BBCopyInst1) {
    std::pair<Register, Register> Key = II.getFirst();
    MachineInstr *MI = II.getSecond();
    bool IsSafetoMove = true;
    for (MachineBasicBlock *SuccBB : BB->successors()) {
      auto &SuccBBCopyInst = CopyMIList[SuccBB->getNumber()];
      if (!SuccBBCopyInst.count(Key)) {
        // Same copy not present in this successor
        IsSafetoMove = false;
        break;
      }
      // If present, make sure that it's safe to pull this copy instruction
      // into the predecessor.
      MachineInstr *SuccMI = SuccBBCopyInst[Key];
      if (!isSafetoMove(SuccMI)) {
        IsSafetoMove = false;
        break;
      }
    }
    // If we have come this far, this copy instruction can be safely
    // moved to the predecessor basic block.
    if (IsSafetoMove) {
      LLVM_DEBUG(dbgs() << "\t\t Moving instr to BB#" << BB->getNumber() << ": "
                        << MI << "\n");
      moveCopyInstr(BB, Key, MI);
      // Add my into BB copyMI list.
      Changed = true;
    }
  }

#ifndef NDEBUG
  auto &BBCopyInst = CopyMIList[BB->getNumber()];
  for (auto II : BBCopyInst) {
    MachineInstr *TempMI = II.getSecond();
    LLVM_DEBUG(dbgs() << "\tIn the list: " << TempMI << "\n");
  }
#endif
  return Changed;
}

bool HexagonCopyHoisting::isSafetoMove(MachineInstr *CandMI) {
  // Make sure that it's safe to move this 'copy' instruction to the predecessor
  // basic block.
  assert(CandMI->getOperand(0).isReg() && CandMI->getOperand(1).isReg());
  Register DefR = CandMI->getOperand(0).getReg();
  Register UseR = CandMI->getOperand(1).getReg();

  MachineBasicBlock *BB = CandMI->getParent();
  // There should not be a def/use of DefR between the start of BB and CandMI.
  MachineBasicBlock::iterator MII, MIE;
  for (MII = BB->begin(), MIE = CandMI; MII != MIE; ++MII) {
    MachineInstr *OtherMI = &*MII;
    for (const MachineOperand &Mo : OtherMI->operands())
      if (Mo.isReg() && Mo.getReg() == DefR)
        return false;
  }
  // There should not be a def of UseR between the start of BB and CandMI.
  for (MII = BB->begin(), MIE = CandMI; MII != MIE; ++MII) {
    MachineInstr *OtherMI = &*MII;
    for (const MachineOperand &Mo : OtherMI->operands())
      if (Mo.isReg() && Mo.isDef() && Mo.getReg() == UseR)
        return false;
  }
  return true;
}

void HexagonCopyHoisting::moveCopyInstr(MachineBasicBlock *DestBB,
                                        std::pair<Register, Register> Key,
                                        MachineInstr *MI) {
  MachineBasicBlock::iterator FirstTI = DestBB->getFirstTerminator();
  assert(FirstTI != DestBB->end());

  DestBB->splice(FirstTI, MI->getParent(), MI);

  addMItoCopyList(MI);
  for (auto I = ++(DestBB->succ_begin()), E = DestBB->succ_end(); I != E; ++I) {
    MachineBasicBlock *SuccBB = *I;
    auto &BBCopyInst = CopyMIList[SuccBB->getNumber()];
    MachineInstr *SuccMI = BBCopyInst[Key];
    SuccMI->eraseFromParent();
    BBCopyInst.erase(Key);
  }
}

//===----------------------------------------------------------------------===//
//                         Public Constructor Functions
//===----------------------------------------------------------------------===//

INITIALIZE_PASS(HexagonCopyHoisting, "hexagon-move-phicopy",
                "Hexagon move phi copy", false, false)

FunctionPass *llvm::createHexagonCopyHoisting() {
  return new HexagonCopyHoisting();
}
