//===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/PassRegistry.h"
#include <utility>
using namespace llvm;

namespace {
  class UnpackMachineBundles : public MachineFunctionPass {
  public:
    static char ID; // Pass identification
    UnpackMachineBundles(
        std::function<bool(const MachineFunction &)> Ftor = nullptr)
        : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
      initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
    }

    bool runOnMachineFunction(MachineFunction &MF) override;

  private:
    std::function<bool(const MachineFunction &)> PredicateFtor;
  };
} // end anonymous namespace

char UnpackMachineBundles::ID = 0;
char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",
                "Unpack machine instruction bundles", false, false)

bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
  if (PredicateFtor && !PredicateFtor(MF))
    return false;

  bool Changed = false;
  for (MachineBasicBlock &MBB : MF) {
    for (MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),
           MIE = MBB.instr_end(); MII != MIE; ) {
      MachineInstr *MI = &*MII;

      // Remove BUNDLE instruction and the InsideBundle flags from bundled
      // instructions.
      if (MI->isBundle()) {
        while (++MII != MIE && MII->isBundledWithPred()) {
          MII->unbundleFromPred();
          for (MachineOperand &MO  : MII->operands()) {
            if (MO.isReg() && MO.isInternalRead())
              MO.setIsInternalRead(false);
          }
        }
        MI->eraseFromParent();

        Changed = true;
        continue;
      }

      ++MII;
    }
  }

  return Changed;
}

FunctionPass *
llvm::createUnpackMachineBundles(
    std::function<bool(const MachineFunction &)> Ftor) {
  return new UnpackMachineBundles(std::move(Ftor));
}

/// Return the first found DebugLoc that has a DILocation, given a range of
/// instructions. The search range is from FirstMI to LastMI (exclusive). If no
/// DILocation is found, then an empty location is returned.
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,
                            MachineBasicBlock::instr_iterator LastMI) {
  for (auto MII = FirstMI; MII != LastMI; ++MII)
    if (MII->getDebugLoc())
      return MII->getDebugLoc();
  return DebugLoc();
}

/// Check if target reg is contained in given lists, which are:
/// LocalDefsV as given list for virtual regs
/// LocalDefsP as given list for physical regs, in BitVector[RegUnit] form
static bool containsReg(SmallSetVector<Register, 32> LocalDefsV,
                        const BitVector &LocalDefsP, Register Reg,
                        const TargetRegisterInfo *TRI) {
  if (Reg.isPhysical()) {
    for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
      if (!LocalDefsP[Unit])
        return false;

    return true;
  }
  return LocalDefsV.contains(Reg);
}

/// finalizeBundle - Finalize a machine instruction bundle which includes
/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
/// This routine adds a BUNDLE instruction to represent the bundle, it adds
/// IsInternalRead markers to MachineOperands which are defined inside the
/// bundle, and it copies externally visible defs and uses to the BUNDLE
/// instruction.
void llvm::finalizeBundle(MachineBasicBlock &MBB,
                          MachineBasicBlock::instr_iterator FirstMI,
                          MachineBasicBlock::instr_iterator LastMI) {
  assert(FirstMI != LastMI && "Empty bundle?");
  MIBundleBuilder Bundle(MBB, FirstMI, LastMI);

  MachineFunction &MF = *MBB.getParent();
  const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();

  MachineInstrBuilder MIB =
      BuildMI(MF, getDebugLoc(FirstMI, LastMI), TII->get(TargetOpcode::BUNDLE));
  Bundle.prepend(MIB);

  SmallSetVector<Register, 32> LocalDefs;
  BitVector LocalDefsP(TRI->getNumRegUnits());
  SmallSet<Register, 8> DeadDefSet;
  SmallSet<Register, 16> KilledDefSet;
  SmallSetVector<Register, 8> ExternUses;
  SmallSet<Register, 8> KilledUseSet;
  SmallSet<Register, 8> UndefUseSet;
  for (auto MII = FirstMI; MII != LastMI; ++MII) {
    // Debug instructions have no effects to track.
    if (MII->isDebugInstr())
      continue;

    for (MachineOperand &MO : MII->all_uses()) {
      Register Reg = MO.getReg();
      if (!Reg)
        continue;

      if (containsReg(LocalDefs, LocalDefsP, Reg, TRI)) {
        MO.setIsInternalRead();
        if (MO.isKill()) {
          // Internal def is now killed.
          KilledDefSet.insert(Reg);
        }
      } else {
        if (ExternUses.insert(Reg)) {
          if (MO.isUndef())
            UndefUseSet.insert(Reg);
        }
        if (MO.isKill()) {
          // External def is now killed.
          KilledUseSet.insert(Reg);
        }
      }
    }

    for (MachineOperand &MO : MII->all_defs()) {
      Register Reg = MO.getReg();
      if (!Reg)
        continue;

      if (LocalDefs.insert(Reg)) {
        if (MO.isDead())
          DeadDefSet.insert(Reg);
        else if (Reg.isPhysical())
          for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
            LocalDefsP.set(Unit);
      } else {
        // Re-defined inside the bundle, it's no longer killed.
        KilledDefSet.erase(Reg);
        if (!MO.isDead()) {
          // Previously defined but dead.
          DeadDefSet.erase(Reg);
        }
      }
    }

    // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions
    // got the property, then also set it on the bundle.
    if (MII->getFlag(MachineInstr::FrameSetup))
      MIB.setMIFlag(MachineInstr::FrameSetup);
    if (MII->getFlag(MachineInstr::FrameDestroy))
      MIB.setMIFlag(MachineInstr::FrameDestroy);
  }

  for (Register Reg : LocalDefs) {
    // If it's not live beyond end of the bundle, mark it dead.
    bool isDead = DeadDefSet.contains(Reg) || KilledDefSet.contains(Reg);
    MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) |
                        getImplRegState(true));
  }

  for (Register Reg : ExternUses) {
    bool isKill = KilledUseSet.contains(Reg);
    bool isUndef = UndefUseSet.contains(Reg);
    MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
               getImplRegState(true));
  }
}

/// finalizeBundle - Same functionality as the previous finalizeBundle except
/// the last instruction in the bundle is not provided as an input. This is
/// used in cases where bundles are pre-determined by marking instructions
/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
/// points to the end of the bundle.
MachineBasicBlock::instr_iterator
llvm::finalizeBundle(MachineBasicBlock &MBB,
                     MachineBasicBlock::instr_iterator FirstMI) {
  MachineBasicBlock::instr_iterator E = MBB.instr_end();
  MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
  while (LastMI != E && LastMI->isInsideBundle())
    ++LastMI;
  finalizeBundle(MBB, FirstMI, LastMI);
  return LastMI;
}

/// finalizeBundles - Finalize instruction bundles in the specified
/// MachineFunction. Return true if any bundles are finalized.
bool llvm::finalizeBundles(MachineFunction &MF) {
  bool Changed = false;
  for (MachineBasicBlock &MBB : MF) {
    MachineBasicBlock::instr_iterator MII = MBB.instr_begin();
    MachineBasicBlock::instr_iterator MIE = MBB.instr_end();
    if (MII == MIE)
      continue;
    assert(!MII->isInsideBundle() &&
           "First instr cannot be inside bundle before finalization!");

    for (++MII; MII != MIE; ) {
      if (!MII->isInsideBundle())
        ++MII;
      else {
        MII = finalizeBundle(MBB, std::prev(MII));
        Changed = true;
      }
    }
  }

  return Changed;
}

VirtRegInfo llvm::AnalyzeVirtRegInBundle(
    MachineInstr &MI, Register Reg,
    SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops) {
  VirtRegInfo RI = {false, false, false};
  for (MIBundleOperands O(MI); O.isValid(); ++O) {
    MachineOperand &MO = *O;
    if (!MO.isReg() || MO.getReg() != Reg)
      continue;

    // Remember each (MI, OpNo) that refers to Reg.
    if (Ops)
      Ops->push_back(std::make_pair(MO.getParent(), O.getOperandNo()));

    // Both defs and uses can read virtual registers.
    if (MO.readsReg()) {
      RI.Reads = true;
      if (MO.isDef())
        RI.Tied = true;
    }

    // Only defs can write.
    if (MO.isDef())
      RI.Writes = true;
    else if (!RI.Tied &&
             MO.getParent()->isRegTiedToDefOperand(O.getOperandNo()))
      RI.Tied = true;
  }
  return RI;
}

std::pair<LaneBitmask, LaneBitmask>
llvm::AnalyzeVirtRegLanesInBundle(const MachineInstr &MI, Register Reg,
                                  const MachineRegisterInfo &MRI,
                                  const TargetRegisterInfo &TRI) {

  LaneBitmask UseMask, DefMask;

  for (const MachineOperand &MO : const_mi_bundle_ops(MI)) {
    if (!MO.isReg() || MO.getReg() != Reg)
      continue;

    unsigned SubReg = MO.getSubReg();
    if (SubReg == 0 && MO.isUse() && !MO.isUndef())
      UseMask |= MRI.getMaxLaneMaskForVReg(Reg);

    LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(SubReg);
    if (MO.isDef()) {
      if (!MO.isUndef())
        UseMask |= ~SubRegMask;
      DefMask |= SubRegMask;
    } else if (!MO.isUndef())
      UseMask |= SubRegMask;
  }

  return {UseMask, DefMask};
}

PhysRegInfo llvm::AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,
                                         const TargetRegisterInfo *TRI) {
  bool AllDefsDead = true;
  PhysRegInfo PRI = {false, false, false, false, false, false, false, false};

  assert(Reg.isPhysical() && "analyzePhysReg not given a physical register!");
  for (const MachineOperand &MO : const_mi_bundle_ops(MI)) {
    if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) {
      PRI.Clobbered = true;
      continue;
    }

    if (!MO.isReg())
      continue;

    Register MOReg = MO.getReg();
    if (!MOReg || !MOReg.isPhysical())
      continue;

    if (!TRI->regsOverlap(MOReg, Reg))
      continue;

    bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);
    if (MO.readsReg()) {
      PRI.Read = true;
      if (Covered) {
        PRI.FullyRead = true;
        if (MO.isKill())
          PRI.Killed = true;
      }
    } else if (MO.isDef()) {
      PRI.Defined = true;
      if (Covered)
        PRI.FullyDefined = true;
      if (!MO.isDead())
        AllDefsDead = false;
    }
  }

  if (AllDefsDead) {
    if (PRI.FullyDefined || PRI.Clobbered)
      PRI.DeadDef = true;
    else if (PRI.Defined)
      PRI.PartialDeadDef = true;
  }

  return PRI;
}

PreservedAnalyses
llvm::FinalizeBundleTestPass::run(MachineFunction &MF,
                                  MachineFunctionAnalysisManager &) {
  // For testing purposes, bundle the entire contents of each basic block
  // except for terminators.
  for (MachineBasicBlock &MBB : MF)
    finalizeBundle(MBB, MBB.instr_begin(), MBB.getFirstInstrTerminator());
  return PreservedAnalyses::none();
}
