//===-- 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.
//
//===----------------------------------------------------------------------===//
//
// 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_LIVEINTERVAL_ANALYSIS_H
#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H

#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include <cmath>
#include <iterator>

namespace llvm {

  class AliasAnalysis;
  class LiveVariables;
  class MachineLoopInfo;
  class TargetRegisterInfo;
  class MachineRegisterInfo;
  class TargetInstrInfo;
  class TargetRegisterClass;
  class VirtRegMap;

  class LiveIntervals : public MachineFunctionPass {
    MachineFunction* mf_;
    MachineRegisterInfo* mri_;
    const TargetMachine* tm_;
    const TargetRegisterInfo* tri_;
    const TargetInstrInfo* tii_;
    AliasAnalysis *aa_;
    LiveVariables* lv_;
    SlotIndexes* indexes_;

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

    typedef DenseMap<unsigned, LiveInterval*> Reg2IntervalMap;
    Reg2IntervalMap r2iMap_;

    /// allocatableRegs_ - A bit vector of allocatable registers.
    BitVector allocatableRegs_;

    /// CloneMIs - A list of clones as result of re-materialization.
    std::vector<MachineInstr*> CloneMIs;

  public:
    static char ID; // Pass identification, replacement for typeid
    LiveIntervals() : MachineFunctionPass(ID) {
      initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
    }

    // Calculate the spill weight to assign to a single instruction.
    static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);

    typedef Reg2IntervalMap::iterator iterator;
    typedef Reg2IntervalMap::const_iterator const_iterator;
    const_iterator begin() const { return r2iMap_.begin(); }
    const_iterator end() const { return r2iMap_.end(); }
    iterator begin() { return r2iMap_.begin(); }
    iterator end() { return r2iMap_.end(); }
    unsigned getNumIntervals() const { return (unsigned)r2iMap_.size(); }

    LiveInterval &getInterval(unsigned reg) {
      Reg2IntervalMap::iterator I = r2iMap_.find(reg);
      assert(I != r2iMap_.end() && "Interval does not exist for register");
      return *I->second;
    }

    const LiveInterval &getInterval(unsigned reg) const {
      Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
      assert(I != r2iMap_.end() && "Interval does not exist for register");
      return *I->second;
    }

    bool hasInterval(unsigned reg) const {
      return r2iMap_.count(reg);
    }

    /// isAllocatable - is the physical register reg allocatable in the current
    /// function?
    bool isAllocatable(unsigned reg) const {
      return allocatableRegs_.test(reg);
    }

    /// getScaledIntervalSize - get the size of an interval in "units,"
    /// where every function is composed of one thousand units.  This
    /// measure scales properly with empty index slots in the function.
    double getScaledIntervalSize(LiveInterval& I) {
      return (1000.0 * I.getSize()) / indexes_->getIndexesLength();
    }

    /// getFuncInstructionCount - Return the number of instructions in the
    /// current function.
    unsigned getFuncInstructionCount() {
      return indexes_->getFunctionSize();
    }

    /// getApproximateInstructionCount - computes an estimate of the number
    /// of instructions in a given LiveInterval.
    unsigned getApproximateInstructionCount(LiveInterval& I) {
      double IntervalPercentage = getScaledIntervalSize(I) / 1000.0;
      return (unsigned)(IntervalPercentage * indexes_->getFunctionSize());
    }

    /// conflictsWithPhysReg - Returns true if the specified register is used or
    /// defined during the duration of the specified interval. Copies to and
    /// from li.reg are allowed. This method is only able to analyze simple
    /// ranges that stay within a single basic block. Anything else is
    /// considered a conflict.
    bool conflictsWithPhysReg(const LiveInterval &li, VirtRegMap &vrm,
                              unsigned reg);

    /// conflictsWithAliasRef - Similar to conflictsWithPhysRegRef except
    /// it checks for alias uses and defs.
    bool conflictsWithAliasRef(LiveInterval &li, unsigned Reg,
                                   SmallPtrSet<MachineInstr*,32> &JoinedCopies);

    // Interval creation
    LiveInterval &getOrCreateInterval(unsigned reg) {
      Reg2IntervalMap::iterator I = r2iMap_.find(reg);
      if (I == r2iMap_.end())
        I = r2iMap_.insert(std::make_pair(reg, createInterval(reg))).first;
      return *I->second;
    }

    /// dupInterval - Duplicate a live interval. The caller is responsible for
    /// managing the allocated memory.
    LiveInterval *dupInterval(LiveInterval *li);

    /// addLiveRangeToEndOfBlock - Given a register and an instruction,
    /// adds a live range from that instruction to the end of its MBB.
    LiveRange addLiveRangeToEndOfBlock(unsigned reg,
                                       MachineInstr* startInst);

    /// shrinkToUses - 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.
    /// Return true if the interval may have been separated into multiple
    /// connected components.
    bool shrinkToUses(LiveInterval *li,
                      SmallVectorImpl<MachineInstr*> *dead = 0);

    // Interval removal

    void removeInterval(unsigned Reg) {
      DenseMap<unsigned, LiveInterval*>::iterator I = r2iMap_.find(Reg);
      delete I->second;
      r2iMap_.erase(I);
    }

    SlotIndexes *getSlotIndexes() const {
      return indexes_;
    }

    SlotIndex getZeroIndex() const {
      return indexes_->getZeroIndex();
    }

    SlotIndex getInvalidIndex() const {
      return indexes_->getInvalidIndex();
    }

    /// isNotInMIMap - 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 LiveInterval &li,
                       const MachineBasicBlock *mbb) const {
      return li.liveAt(getMBBStartIdx(mbb));
    }

    LiveRange* findEnteringRange(LiveInterval &li,
                                 const MachineBasicBlock *mbb) {
      return li.getLiveRangeContaining(getMBBStartIdx(mbb));
    }

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

    LiveRange* findExitingRange(LiveInterval &li,
                                const MachineBasicBlock *mbb) {
      return li.getLiveRangeContaining(getMBBEndIdx(mbb).getPrevSlot());
    }

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

    SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
      return indexes_->insertMachineInstrInMaps(MI);
    }

    void RemoveMachineInstrFromMaps(MachineInstr *MI) {
      indexes_->removeMachineInstrFromMaps(MI);
    }

    void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) {
      indexes_->replaceMachineInstrInMaps(MI, NewMI);
    }

    void InsertMBBInMaps(MachineBasicBlock *MBB) {
      indexes_->insertMBBInMaps(MBB);
    }

    bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
                        SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
      return indexes_->findLiveInMBBs(Start, End, MBBs);
    }

    void renumber() {
      indexes_->renumberIndexes();
    }

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

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

    /// runOnMachineFunction - pass entry point
    virtual bool runOnMachineFunction(MachineFunction&);

    /// print - Implement the dump method.
    virtual void print(raw_ostream &O, const Module* = 0) const;

    /// addIntervalsForSpills - Create new intervals for spilled defs / uses of
    /// the given interval. FIXME: It also returns the weight of the spill slot
    /// (if any is created) by reference. This is temporary.
    std::vector<LiveInterval*>
    addIntervalsForSpills(const LiveInterval& i,
                          const SmallVectorImpl<LiveInterval*> *SpillIs,
                          const MachineLoopInfo *loopInfo, VirtRegMap& vrm);

    /// spillPhysRegAroundRegDefsUses - Spill the specified physical register
    /// around all defs and uses of the specified interval. Return true if it
    /// was able to cut its interval.
    bool spillPhysRegAroundRegDefsUses(const LiveInterval &li,
                                       unsigned PhysReg, VirtRegMap &vrm);

    /// isReMaterializable - Returns true if every definition of MI of every
    /// val# of the specified interval is re-materializable. Also returns true
    /// by reference if all of the defs are load instructions.
    bool isReMaterializable(const LiveInterval &li,
                            const SmallVectorImpl<LiveInterval*> *SpillIs,
                            bool &isLoad);

    /// isReMaterializable - Returns true if the definition MI of the specified
    /// val# of the specified interval is re-materializable.
    bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
                            MachineInstr *MI);

    /// getRepresentativeReg - Find the largest super register of the specified
    /// physical register.
    unsigned getRepresentativeReg(unsigned Reg) const;

    /// getNumConflictsWithPhysReg - Return the number of uses and defs of the
    /// specified interval that conflicts with the specified physical register.
    unsigned getNumConflictsWithPhysReg(const LiveInterval &li,
                                        unsigned PhysReg) const;

    /// intervalIsInOneMBB - Returns true if the specified interval is entirely
    /// within a single basic block.
    bool intervalIsInOneMBB(const LiveInterval &li) const;

    /// getLastSplitPoint - Return the last possible insertion point in mbb for
    /// spilling and splitting code. This is the first terminator, or the call
    /// instruction if li is live into a landing pad successor.
    MachineBasicBlock::iterator getLastSplitPoint(const LiveInterval &li,
                                                  MachineBasicBlock *mbb) const;

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

  private:
    /// computeIntervals - Compute live intervals.
    void computeIntervals();

    /// handleRegisterDef - update intervals for a register def
    /// (calls handlePhysicalRegisterDef and
    /// handleVirtualRegisterDef)
    void handleRegisterDef(MachineBasicBlock *MBB,
                           MachineBasicBlock::iterator MI,
                           SlotIndex MIIdx,
                           MachineOperand& MO, unsigned MOIdx);

    /// isPartialRedef - Return true if the specified def at the specific index
    /// is partially re-defining the specified live interval. A common case of
    /// this is a definition of the sub-register.
    bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
                        LiveInterval &interval);

    /// handleVirtualRegisterDef - update intervals for a virtual
    /// register def
    void handleVirtualRegisterDef(MachineBasicBlock *MBB,
                                  MachineBasicBlock::iterator MI,
                                  SlotIndex MIIdx, MachineOperand& MO,
                                  unsigned MOIdx,
                                  LiveInterval& interval);

    /// handlePhysicalRegisterDef - update intervals for a physical register
    /// def.
    void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
                                   MachineBasicBlock::iterator mi,
                                   SlotIndex MIIdx, MachineOperand& MO,
                                   LiveInterval &interval,
                                   MachineInstr *CopyMI);

    /// handleLiveInRegister - Create interval for a livein register.
    void handleLiveInRegister(MachineBasicBlock* mbb,
                              SlotIndex MIIdx,
                              LiveInterval &interval, bool isAlias = false);

    /// getReMatImplicitUse - If the remat definition MI has one (for now, we
    /// only allow one) virtual register operand, then its uses are implicitly
    /// using the register. Returns the virtual register.
    unsigned getReMatImplicitUse(const LiveInterval &li,
                                 MachineInstr *MI) const;

    /// isValNoAvailableAt - Return true if the val# of the specified interval
    /// which reaches the given instruction also reaches the specified use
    /// index.
    bool isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
                            SlotIndex UseIdx) const;

    /// isReMaterializable - Returns true if the definition MI of the specified
    /// val# of the specified interval is re-materializable. Also returns true
    /// by reference if the def is a load.
    bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
                            MachineInstr *MI,
                            const SmallVectorImpl<LiveInterval*> *SpillIs,
                            bool &isLoad);

    /// tryFoldMemoryOperand - Attempts to fold either a spill / restore from
    /// slot / to reg or any rematerialized load into ith operand of specified
    /// MI. If it is successul, MI is updated with the newly created MI and
    /// returns true.
    bool tryFoldMemoryOperand(MachineInstr* &MI, VirtRegMap &vrm,
                              MachineInstr *DefMI, SlotIndex InstrIdx,
                              SmallVector<unsigned, 2> &Ops,
                              bool isSS, int FrameIndex, unsigned Reg);

    /// canFoldMemoryOperand - Return true if the specified load / store
    /// folding is possible.
    bool canFoldMemoryOperand(MachineInstr *MI,
                              SmallVector<unsigned, 2> &Ops,
                              bool ReMatLoadSS) const;

    /// anyKillInMBBAfterIdx - Returns true if there is a kill of the specified
    /// VNInfo that's after the specified index but is within the basic block.
    bool anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI,
                              MachineBasicBlock *MBB,
                              SlotIndex Idx) const;

    /// hasAllocatableSuperReg - Return true if the specified physical register
    /// has any super register that's allocatable.
    bool hasAllocatableSuperReg(unsigned Reg) const;

    /// SRInfo - Spill / restore info.
    struct SRInfo {
      SlotIndex index;
      unsigned vreg;
      bool canFold;
      SRInfo(SlotIndex i, unsigned vr, bool f)
        : index(i), vreg(vr), canFold(f) {}
    };

    bool alsoFoldARestore(int Id, SlotIndex index, unsigned vr,
                          BitVector &RestoreMBBs,
                          DenseMap<unsigned,std::vector<SRInfo> >&RestoreIdxes);
    void eraseRestoreInfo(int Id, SlotIndex index, unsigned vr,
                          BitVector &RestoreMBBs,
                          DenseMap<unsigned,std::vector<SRInfo> >&RestoreIdxes);

    /// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
    /// spilled and create empty intervals for their uses.
    void handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
                              const TargetRegisterClass* rc,
                              std::vector<LiveInterval*> &NewLIs);

    /// rewriteImplicitOps - Rewrite implicit use operands of MI (i.e. uses of
    /// interval on to-be re-materialized operands of MI) with new register.
    void rewriteImplicitOps(const LiveInterval &li,
                           MachineInstr *MI, unsigned NewVReg, VirtRegMap &vrm);

    /// rewriteInstructionForSpills, rewriteInstructionsForSpills - Helper
    /// functions for addIntervalsForSpills to rewrite uses / defs for the given
    /// live range.
    bool rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
        bool TrySplit, SlotIndex index, SlotIndex end,
        MachineInstr *MI, MachineInstr *OrigDefMI, MachineInstr *DefMI,
        unsigned Slot, int LdSlot,
        bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete,
        VirtRegMap &vrm, const TargetRegisterClass* rc,
        SmallVector<int, 4> &ReMatIds, const MachineLoopInfo *loopInfo,
        unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse,
        DenseMap<unsigned,unsigned> &MBBVRegsMap,
        std::vector<LiveInterval*> &NewLIs);
    void rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
        LiveInterval::Ranges::const_iterator &I,
        MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot,
        bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete,
        VirtRegMap &vrm, const TargetRegisterClass* rc,
        SmallVector<int, 4> &ReMatIds, const MachineLoopInfo *loopInfo,
        BitVector &SpillMBBs,
        DenseMap<unsigned,std::vector<SRInfo> > &SpillIdxes,
        BitVector &RestoreMBBs,
        DenseMap<unsigned,std::vector<SRInfo> > &RestoreIdxes,
        DenseMap<unsigned,unsigned> &MBBVRegsMap,
        std::vector<LiveInterval*> &NewLIs);

    static LiveInterval* createInterval(unsigned Reg);

    void printInstrs(raw_ostream &O) const;
    void dumpInstrs() const;
  };
} // End llvm namespace

#endif
