//===- 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 = Register::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 Register copyHint(const MachineInstr *mi, unsigned reg,
                         const TargetRegisterInfo &tri,
                         const MachineRegisterInfo &mri) {
  unsigned sub, hsub;
  Register hreg;
  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 (Register::isVirtualRegister(hreg))
    return sub == hsub ? hreg : Register();

  const TargetRegisterClass *rc = mri.getRegClass(reg);
  Register 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 (!Register::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_nodbg_iterator
           I = mri.reg_instr_nodbg_begin(li.reg),
           E = mri.reg_instr_nodbg_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())
      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;
    Register 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 (Register::isVirtualRegister(hint) || mri.isAllocatable(hint))
      CopyHints.insert(
          CopyHint(hint, hweight, Register::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);
}
