//===- CalcSpillWeights.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/CalcSpillWeights.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <tuple>

using namespace llvm;

#define DEBUG_TYPE "calcspillweights"

void llvm::calculateSpillWeightsAndHints(LiveIntervals &LIS,
                           MachineFunction &MF,
                           VirtRegMap *VRM,
                           const MachineLoopInfo &MLI,
                           const MachineBlockFrequencyInfo &MBFI,
                           VirtRegAuxInfo::NormalizingFn norm) {
  LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
                    << "********** Function: " << MF.getName() << '\n');

  MachineRegisterInfo &MRI = MF.getRegInfo();
  VirtRegAuxInfo VRAI(MF, LIS, VRM, MLI, MBFI, norm);
  for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
    unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
    if (MRI.reg_nodbg_empty(Reg))
      continue;
    VRAI.calculateSpillWeightAndHint(LIS.getInterval(Reg));
  }
}

// Return the preferred allocation register for reg, given a COPY instruction.
static unsigned copyHint(const MachineInstr *mi, unsigned reg,
                         const TargetRegisterInfo &tri,
                         const MachineRegisterInfo &mri) {
  unsigned sub, hreg, hsub;
  if (mi->getOperand(0).getReg() == reg) {
    sub = mi->getOperand(0).getSubReg();
    hreg = mi->getOperand(1).getReg();
    hsub = mi->getOperand(1).getSubReg();
  } else {
    sub = mi->getOperand(1).getSubReg();
    hreg = mi->getOperand(0).getReg();
    hsub = mi->getOperand(0).getSubReg();
  }

  if (!hreg)
    return 0;

  if (TargetRegisterInfo::isVirtualRegister(hreg))
    return sub == hsub ? hreg : 0;

  const TargetRegisterClass *rc = mri.getRegClass(reg);
  unsigned CopiedPReg = (hsub ? tri.getSubReg(hreg, hsub) : hreg);
  if (rc->contains(CopiedPReg))
    return CopiedPReg;

  // Check if reg:sub matches so that a super register could be hinted.
  if (sub)
    return tri.getMatchingSuperReg(CopiedPReg, sub, rc);

  return 0;
}

// Check if all values in LI are rematerializable
static bool isRematerializable(const LiveInterval &LI,
                               const LiveIntervals &LIS,
                               VirtRegMap *VRM,
                               const TargetInstrInfo &TII) {
  unsigned Reg = LI.reg;
  unsigned Original = VRM ? VRM->getOriginal(Reg) : 0;
  for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
       I != E; ++I) {
    const VNInfo *VNI = *I;
    if (VNI->isUnused())
      continue;
    if (VNI->isPHIDef())
      return false;

    MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
    assert(MI && "Dead valno in interval");

    // Trace copies introduced by live range splitting.  The inline
    // spiller can rematerialize through these copies, so the spill
    // weight must reflect this.
    if (VRM) {
      while (MI->isFullCopy()) {
        // The copy destination must match the interval register.
        if (MI->getOperand(0).getReg() != Reg)
          return false;

        // Get the source register.
        Reg = MI->getOperand(1).getReg();

        // If the original (pre-splitting) registers match this
        // copy came from a split.
        if (!TargetRegisterInfo::isVirtualRegister(Reg) ||
            VRM->getOriginal(Reg) != Original)
          return false;

        // Follow the copy live-in value.
        const LiveInterval &SrcLI = LIS.getInterval(Reg);
        LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
        VNI = SrcQ.valueIn();
        assert(VNI && "Copy from non-existing value");
        if (VNI->isPHIDef())
          return false;
        MI = LIS.getInstructionFromIndex(VNI->def);
        assert(MI && "Dead valno in interval");
      }
    }

    if (!TII.isTriviallyReMaterializable(*MI, LIS.getAliasAnalysis()))
      return false;
  }
  return true;
}

void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &li) {
  float weight = weightCalcHelper(li);
  // Check if unspillable.
  if (weight < 0)
    return;
  li.weight = weight;
}

float VirtRegAuxInfo::futureWeight(LiveInterval &li, SlotIndex start,
                                   SlotIndex end) {
  return weightCalcHelper(li, &start, &end);
}

float VirtRegAuxInfo::weightCalcHelper(LiveInterval &li, SlotIndex *start,
                                       SlotIndex *end) {
  MachineRegisterInfo &mri = MF.getRegInfo();
  const TargetRegisterInfo &tri = *MF.getSubtarget().getRegisterInfo();
  MachineBasicBlock *mbb = nullptr;
  MachineLoop *loop = nullptr;
  bool isExiting = false;
  float totalWeight = 0;
  unsigned numInstr = 0; // Number of instructions using li
  SmallPtrSet<MachineInstr*, 8> visited;

  std::pair<unsigned, unsigned> TargetHint = mri.getRegAllocationHint(li.reg);

  // Don't recompute spill weight for an unspillable register.
  bool Spillable = li.isSpillable();

  bool localSplitArtifact = start && end;

  // Do not update future local split artifacts.
  bool updateLI = !localSplitArtifact;

  if (localSplitArtifact) {
    MachineBasicBlock *localMBB = LIS.getMBBFromIndex(*end);
    assert(localMBB == LIS.getMBBFromIndex(*start) &&
           "start and end are expected to be in the same basic block");

    // Local split artifact will have 2 additional copy instructions and they
    // will be in the same BB.
    // localLI = COPY other
    // ...
    // other   = COPY localLI
    totalWeight += LiveIntervals::getSpillWeight(true, false, &MBFI, localMBB);
    totalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB);

    numInstr += 2;
  }

  // CopyHint is a sortable hint derived from a COPY instruction.
  struct CopyHint {
    unsigned Reg;
    float Weight;
    bool IsPhys;
    CopyHint(unsigned R, float W, bool P) :
      Reg(R), Weight(W), IsPhys(P) {}
    bool operator<(const CopyHint &rhs) const {
      // Always prefer any physreg hint.
      if (IsPhys != rhs.IsPhys)
        return (IsPhys && !rhs.IsPhys);
      if (Weight != rhs.Weight)
        return (Weight > rhs.Weight);
      return Reg < rhs.Reg; // Tie-breaker.
    }
  };
  std::set<CopyHint> CopyHints;

  for (MachineRegisterInfo::reg_instr_iterator
       I = mri.reg_instr_begin(li.reg), E = mri.reg_instr_end();
       I != E; ) {
    MachineInstr *mi = &*(I++);

    // For local split artifacts, we are interested only in instructions between
    // the expected start and end of the range.
    SlotIndex si = LIS.getInstructionIndex(*mi);
    if (localSplitArtifact && ((si < *start) || (si > *end)))
      continue;

    numInstr++;
    if (mi->isIdentityCopy() || mi->isImplicitDef() || mi->isDebugInstr())
      continue;
    if (!visited.insert(mi).second)
      continue;

    float weight = 1.0f;
    if (Spillable) {
      // Get loop info for mi.
      if (mi->getParent() != mbb) {
        mbb = mi->getParent();
        loop = Loops.getLoopFor(mbb);
        isExiting = loop ? loop->isLoopExiting(mbb) : false;
      }

      // Calculate instr weight.
      bool reads, writes;
      std::tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg);
      weight = LiveIntervals::getSpillWeight(writes, reads, &MBFI, *mi);

      // Give extra weight to what looks like a loop induction variable update.
      if (writes && isExiting && LIS.isLiveOutOfMBB(li, mbb))
        weight *= 3;

      totalWeight += weight;
    }

    // Get allocation hints from copies.
    if (!mi->isCopy())
      continue;
    unsigned hint = copyHint(mi, li.reg, tri, mri);
    if (!hint)
      continue;
    // Force hweight onto the stack so that x86 doesn't add hidden precision,
    // making the comparison incorrectly pass (i.e., 1 > 1 == true??).
    //
    // FIXME: we probably shouldn't use floats at all.
    volatile float hweight = Hint[hint] += weight;
    if (TargetRegisterInfo::isVirtualRegister(hint) || mri.isAllocatable(hint))
      CopyHints.insert(CopyHint(hint, hweight, tri.isPhysicalRegister(hint)));
  }

  Hint.clear();

  // Pass all the sorted copy hints to mri.
  if (updateLI && CopyHints.size()) {
    // Remove a generic hint if previously added by target.
    if (TargetHint.first == 0 && TargetHint.second)
      mri.clearSimpleHint(li.reg);

    std::set<unsigned> HintedRegs;
    for (auto &Hint : CopyHints) {
      if (!HintedRegs.insert(Hint.Reg).second ||
          (TargetHint.first != 0 && Hint.Reg == TargetHint.second))
        // Don't add the same reg twice or the target-type hint again.
        continue;
      mri.addRegAllocationHint(li.reg, Hint.Reg);
    }

    // Weakly boost the spill weight of hinted registers.
    totalWeight *= 1.01F;
  }

  // If the live interval was already unspillable, leave it that way.
  if (!Spillable)
    return -1.0;

  // Mark li as unspillable if all live ranges are tiny and the interval
  // is not live at any reg mask.  If the interval is live at a reg mask
  // spilling may be required.
  if (updateLI && li.isZeroLength(LIS.getSlotIndexes()) &&
      !li.isLiveAtIndexes(LIS.getRegMaskSlots())) {
    li.markNotSpillable();
    return -1.0;
  }

  // If all of the definitions of the interval are re-materializable,
  // it is a preferred candidate for spilling.
  // FIXME: this gets much more complicated once we support non-trivial
  // re-materialization.
  if (isRematerializable(li, LIS, VRM, *MF.getSubtarget().getInstrInfo()))
    totalWeight *= 0.5F;

  if (localSplitArtifact)
    return normalize(totalWeight, start->distance(*end), numInstr);
  return normalize(totalWeight, li.getSize(), numInstr);
}
