//===- LiveIntervalAnalysis.h - Live Interval Analysis ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file This file implements the LiveInterval analysis pass.  Given some
/// numbering of each the machine instructions (in this implemention depth-first
/// order) an interval [i, j) is said to be a live interval for register v if
/// there is no instruction with number j' > j such that v is live at j' and
/// there is no instruction with number i' < i such that v is live at i'. In
/// this implementation intervals can have holes, i.e. an interval might look
/// like [1,20), [50,65), [1000,1001).
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_LIVEINTERVALANALYSIS_H
#define LLVM_CODEGEN_LIVEINTERVALANALYSIS_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <cassert>
#include <cstdint>
#include <utility>

namespace llvm {

extern cl::opt<bool> UseSegmentSetForPhysRegs;

class BitVector;
class LiveRangeCalc;
class MachineBlockFrequencyInfo;
class MachineDominatorTree;
class MachineFunction;
class MachineInstr;
class MachineRegisterInfo;
class raw_ostream;
class TargetInstrInfo;
class VirtRegMap;

  class LiveIntervals : public MachineFunctionPass {
    MachineFunction* MF;
    MachineRegisterInfo* MRI;
    const TargetRegisterInfo* TRI;
    const TargetInstrInfo* TII;
    AliasAnalysis *AA;
    SlotIndexes* Indexes;
    MachineDominatorTree *DomTree = nullptr;
    LiveRangeCalc *LRCalc = nullptr;

    /// Special pool allocator for VNInfo's (LiveInterval val#).
    VNInfo::Allocator VNInfoAllocator;

    /// Live interval pointers for all the virtual registers.
    IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;

    /// Sorted list of instructions with register mask operands. Always use the
    /// 'r' slot, RegMasks are normal clobbers, not early clobbers.
    SmallVector<SlotIndex, 8> RegMaskSlots;

    /// This vector is parallel to RegMaskSlots, it holds a pointer to the
    /// corresponding register mask.  This pointer can be recomputed as:
    ///
    ///   MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]);
    ///   unsigned OpNum = findRegMaskOperand(MI);
    ///   RegMaskBits[N] = MI->getOperand(OpNum).getRegMask();
    ///
    /// This is kept in a separate vector partly because some standard
    /// libraries don't support lower_bound() with mixed objects, partly to
    /// improve locality when searching in RegMaskSlots.
    /// Also see the comment in LiveInterval::find().
    SmallVector<const uint32_t*, 8> RegMaskBits;

    /// For each basic block number, keep (begin, size) pairs indexing into the
    /// RegMaskSlots and RegMaskBits arrays.
    /// Note that basic block numbers may not be layout contiguous, that's why
    /// we can't just keep track of the first register mask in each basic
    /// block.
    SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;

    /// Keeps a live range set for each register unit to track fixed physreg
    /// interference.
    SmallVector<LiveRange*, 0> RegUnitRanges;

  public:
    static char ID;

    LiveIntervals();
    ~LiveIntervals() override;

    /// Calculate the spill weight to assign to a single instruction.
    static float getSpillWeight(bool isDef, bool isUse,
                                const MachineBlockFrequencyInfo *MBFI,
                                const MachineInstr &Instr);

    /// Calculate the spill weight to assign to a single instruction.
    static float getSpillWeight(bool isDef, bool isUse,
                                const MachineBlockFrequencyInfo *MBFI,
                                const MachineBasicBlock *MBB);

    LiveInterval &getInterval(unsigned Reg) {
      if (hasInterval(Reg))
        return *VirtRegIntervals[Reg];
      else
        return createAndComputeVirtRegInterval(Reg);
    }

    const LiveInterval &getInterval(unsigned Reg) const {
      return const_cast<LiveIntervals*>(this)->getInterval(Reg);
    }

    bool hasInterval(unsigned Reg) const {
      return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
    }

    /// Interval creation.
    LiveInterval &createEmptyInterval(unsigned Reg) {
      assert(!hasInterval(Reg) && "Interval already exists!");
      VirtRegIntervals.grow(Reg);
      VirtRegIntervals[Reg] = createInterval(Reg);
      return *VirtRegIntervals[Reg];
    }

    LiveInterval &createAndComputeVirtRegInterval(unsigned Reg) {
      LiveInterval &LI = createEmptyInterval(Reg);
      computeVirtRegInterval(LI);
      return LI;
    }

    /// Interval removal.
    void removeInterval(unsigned Reg) {
      delete VirtRegIntervals[Reg];
      VirtRegIntervals[Reg] = nullptr;
    }

    /// Given a register and an instruction, adds a live segment from that
    /// instruction to the end of its MBB.
    LiveInterval::Segment addSegmentToEndOfBlock(unsigned reg,
                                                 MachineInstr &startInst);

    /// After removing some uses of a register, shrink its live range to just
    /// the remaining uses. This method does not compute reaching defs for new
    /// uses, and it doesn't remove dead defs.
    /// Dead PHIDef values are marked as unused. New dead machine instructions
    /// are added to the dead vector. Returns true if the interval may have been
    /// separated into multiple connected components.
    bool shrinkToUses(LiveInterval *li,
                      SmallVectorImpl<MachineInstr*> *dead = nullptr);

    /// Specialized version of
    /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead)
    /// that works on a subregister live range and only looks at uses matching
    /// the lane mask of the subregister range.
    /// This may leave the subrange empty which needs to be cleaned up with
    /// LiveInterval::removeEmptySubranges() afterwards.
    void shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg);

    /// Extend the live range \p LR to reach all points in \p Indices. The
    /// points in the \p Indices array must be jointly dominated by the union
    /// of the existing defs in \p LR and points in \p Undefs.
    ///
    /// PHI-defs are added as needed to maintain SSA form.
    ///
    /// If a SlotIndex in \p Indices is the end index of a basic block, \p LR
    /// will be extended to be live out of the basic block.
    /// If a SlotIndex in \p Indices is jointy dominated only by points in
    /// \p Undefs, the live range will not be extended to that point.
    ///
    /// See also LiveRangeCalc::extend().
    void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices,
                         ArrayRef<SlotIndex> Undefs);

    void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices) {
      extendToIndices(LR, Indices, /*Undefs=*/{});
    }

    /// If \p LR has a live value at \p Kill, prune its live range by removing
    /// any liveness reachable from Kill. Add live range end points to
    /// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
    /// value's live range.
    ///
    /// Calling pruneValue() and extendToIndices() can be used to reconstruct
    /// SSA form after adding defs to a virtual register.
    void pruneValue(LiveRange &LR, SlotIndex Kill,
                    SmallVectorImpl<SlotIndex> *EndPoints);

    /// This function should not be used. Its intend is to tell you that
    /// you are doing something wrong if you call pruveValue directly on a
    /// LiveInterval. Indeed, you are supposed to call pruneValue on the main
    /// LiveRange and all the LiveRange of the subranges if any.
    LLVM_ATTRIBUTE_UNUSED void pruneValue(LiveInterval &, SlotIndex,
                                          SmallVectorImpl<SlotIndex> *) {
      llvm_unreachable(
          "Use pruneValue on the main LiveRange and on each subrange");
    }

    SlotIndexes *getSlotIndexes() const {
      return Indexes;
    }

    AliasAnalysis *getAliasAnalysis() const {
      return AA;
    }

    /// Returns true if the specified machine instr has been removed or was
    /// never entered in the map.
    bool isNotInMIMap(const MachineInstr &Instr) const {
      return !Indexes->hasIndex(Instr);
    }

    /// Returns the base index of the given instruction.
    SlotIndex getInstructionIndex(const MachineInstr &Instr) const {
      return Indexes->getInstructionIndex(Instr);
    }

    /// Returns the instruction associated with the given index.
    MachineInstr* getInstructionFromIndex(SlotIndex index) const {
      return Indexes->getInstructionFromIndex(index);
    }

    /// Return the first index in the given basic block.
    SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
      return Indexes->getMBBStartIdx(mbb);
    }

    /// Return the last index in the given basic block.
    SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
      return Indexes->getMBBEndIdx(mbb);
    }

    bool isLiveInToMBB(const LiveRange &LR,
                       const MachineBasicBlock *mbb) const {
      return LR.liveAt(getMBBStartIdx(mbb));
    }

    bool isLiveOutOfMBB(const LiveRange &LR,
                        const MachineBasicBlock *mbb) const {
      return LR.liveAt(getMBBEndIdx(mbb).getPrevSlot());
    }

    MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
      return Indexes->getMBBFromIndex(index);
    }

    void insertMBBInMaps(MachineBasicBlock *MBB) {
      Indexes->insertMBBInMaps(MBB);
      assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
             "Blocks must be added in order.");
      RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
    }

    SlotIndex InsertMachineInstrInMaps(MachineInstr &MI) {
      return Indexes->insertMachineInstrInMaps(MI);
    }

    void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B,
                                       MachineBasicBlock::iterator E) {
      for (MachineBasicBlock::iterator I = B; I != E; ++I)
        Indexes->insertMachineInstrInMaps(*I);
    }

    void RemoveMachineInstrFromMaps(MachineInstr &MI) {
      Indexes->removeMachineInstrFromMaps(MI);
    }

    SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI) {
      return Indexes->replaceMachineInstrInMaps(MI, NewMI);
    }

    VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }

    void getAnalysisUsage(AnalysisUsage &AU) const override;
    void releaseMemory() override;

    /// Pass entry point; Calculates LiveIntervals.
    bool runOnMachineFunction(MachineFunction&) override;

    /// Implement the dump method.
    void print(raw_ostream &O, const Module* = nullptr) const override;

    /// If LI is confined to a single basic block, return a pointer to that
    /// block.  If LI is live in to or out of any block, return NULL.
    MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;

    /// Returns true if VNI is killed by any PHI-def values in LI.
    /// This may conservatively return true to avoid expensive computations.
    bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;

    /// Add kill flags to any instruction that kills a virtual register.
    void addKillFlags(const VirtRegMap*);

    /// Call this method to notify LiveIntervals that instruction \p MI has been
    /// moved within a basic block. This will update the live intervals for all
    /// operands of \p MI. Moves between basic blocks are not supported.
    ///
    /// \param UpdateFlags Update live intervals for nonallocatable physregs.
    void handleMove(MachineInstr &MI, bool UpdateFlags = false);

    /// Update intervals for operands of \p MI so that they begin/end on the
    /// SlotIndex for \p BundleStart.
    ///
    /// \param UpdateFlags Update live intervals for nonallocatable physregs.
    ///
    /// Requires MI and BundleStart to have SlotIndexes, and assumes
    /// existing liveness is accurate. BundleStart should be the first
    /// instruction in the Bundle.
    void handleMoveIntoBundle(MachineInstr &MI, MachineInstr &BundleStart,
                              bool UpdateFlags = false);

    /// Update live intervals for instructions in a range of iterators. It is
    /// intended for use after target hooks that may insert or remove
    /// instructions, and is only efficient for a small number of instructions.
    ///
    /// OrigRegs is a vector of registers that were originally used by the
    /// instructions in the range between the two iterators.
    ///
    /// Currently, the only only changes that are supported are simple removal
    /// and addition of uses.
    void repairIntervalsInRange(MachineBasicBlock *MBB,
                                MachineBasicBlock::iterator Begin,
                                MachineBasicBlock::iterator End,
                                ArrayRef<unsigned> OrigRegs);

    // Register mask functions.
    //
    // Machine instructions may use a register mask operand to indicate that a
    // large number of registers are clobbered by the instruction.  This is
    // typically used for calls.
    //
    // For compile time performance reasons, these clobbers are not recorded in
    // the live intervals for individual physical registers.  Instead,
    // LiveIntervalAnalysis maintains a sorted list of instructions with
    // register mask operands.

    /// Returns a sorted array of slot indices of all instructions with
    /// register mask operands.
    ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }

    /// Returns a sorted array of slot indices of all instructions with register
    /// mask operands in the basic block numbered \p MBBNum.
    ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
      std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
      return getRegMaskSlots().slice(P.first, P.second);
    }

    /// Returns an array of register mask pointers corresponding to
    /// getRegMaskSlots().
    ArrayRef<const uint32_t*> getRegMaskBits() const { return RegMaskBits; }

    /// Returns an array of mask pointers corresponding to
    /// getRegMaskSlotsInBlock(MBBNum).
    ArrayRef<const uint32_t*> getRegMaskBitsInBlock(unsigned MBBNum) const {
      std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
      return getRegMaskBits().slice(P.first, P.second);
    }

    /// Test if \p LI is live across any register mask instructions, and
    /// compute a bit mask of physical registers that are not clobbered by any
    /// of them.
    ///
    /// Returns false if \p LI doesn't cross any register mask instructions. In
    /// that case, the bit vector is not filled in.
    bool checkRegMaskInterference(LiveInterval &LI,
                                  BitVector &UsableRegs);

    // Register unit functions.
    //
    // Fixed interference occurs when MachineInstrs use physregs directly
    // instead of virtual registers. This typically happens when passing
    // arguments to a function call, or when instructions require operands in
    // fixed registers.
    //
    // Each physreg has one or more register units, see MCRegisterInfo. We
    // track liveness per register unit to handle aliasing registers more
    // efficiently.

    /// Return the live range for register unit \p Unit. It will be computed if
    /// it doesn't exist.
    LiveRange &getRegUnit(unsigned Unit) {
      LiveRange *LR = RegUnitRanges[Unit];
      if (!LR) {
        // Compute missing ranges on demand.
        // Use segment set to speed-up initial computation of the live range.
        RegUnitRanges[Unit] = LR = new LiveRange(UseSegmentSetForPhysRegs);
        computeRegUnitRange(*LR, Unit);
      }
      return *LR;
    }

    /// Return the live range for register unit \p Unit if it has already been
    /// computed, or nullptr if it hasn't been computed yet.
    LiveRange *getCachedRegUnit(unsigned Unit) {
      return RegUnitRanges[Unit];
    }

    const LiveRange *getCachedRegUnit(unsigned Unit) const {
      return RegUnitRanges[Unit];
    }

    /// Remove computed live range for register unit \p Unit. Subsequent uses
    /// should rely on on-demand recomputation.
    void removeRegUnit(unsigned Unit) {
      delete RegUnitRanges[Unit];
      RegUnitRanges[Unit] = nullptr;
    }

    /// Remove value numbers and related live segments starting at position
    /// \p Pos that are part of any liverange of physical register \p Reg or one
    /// of its subregisters.
    void removePhysRegDefAt(unsigned Reg, SlotIndex Pos);

    /// Remove value number and related live segments of \p LI and its subranges
    /// that start at position \p Pos.
    void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos);

    /// Split separate components in LiveInterval \p LI into separate intervals.
    void splitSeparateComponents(LiveInterval &LI,
                                 SmallVectorImpl<LiveInterval*> &SplitLIs);

    /// For live interval \p LI with correct SubRanges construct matching
    /// information for the main live range. Expects the main live range to not
    /// have any segments or value numbers.
    void constructMainRangeFromSubranges(LiveInterval &LI);

  private:
    /// Compute live intervals for all virtual registers.
    void computeVirtRegs();

    /// Compute RegMaskSlots and RegMaskBits.
    void computeRegMasks();

    /// Walk the values in \p LI and check for dead values:
    /// - Dead PHIDef values are marked as unused.
    /// - Dead operands are marked as such.
    /// - Completely dead machine instructions are added to the \p dead vector
    ///   if it is not nullptr.
    /// Returns true if any PHI value numbers have been removed which may
    /// have separated the interval into multiple connected components.
    bool computeDeadValues(LiveInterval &LI,
                           SmallVectorImpl<MachineInstr*> *dead);

    static LiveInterval* createInterval(unsigned Reg);

    void printInstrs(raw_ostream &O) const;
    void dumpInstrs() const;

    void computeLiveInRegUnits();
    void computeRegUnitRange(LiveRange&, unsigned Unit);
    void computeVirtRegInterval(LiveInterval&);


    /// Helper function for repairIntervalsInRange(), walks backwards and
    /// creates/modifies live segments in \p LR to match the operands found.
    /// Only full operands or operands with subregisters matching \p LaneMask
    /// are considered.
    void repairOldRegInRange(MachineBasicBlock::iterator Begin,
                             MachineBasicBlock::iterator End,
                             const SlotIndex endIdx, LiveRange &LR,
                             unsigned Reg,
                             LaneBitmask LaneMask = LaneBitmask::getAll());

    class HMEditor;
  };

} // end namespace llvm

#endif // LLVM_CODEGEN_LIVEINTERVALANALYSIS_H
