//=- llvm/CodeGen/AggressiveAntiDepBreaker.h - Anti-Dep Support -*- 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 AggressiveAntiDepBreaker class, which
// implements register anti-dependence breaking during post-RA
// scheduling. It attempts to break all anti-dependencies within a
// block.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H
#define LLVM_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H

#include "AntiDepBreaker.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/Target/TargetSubtarget.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallSet.h"
#include <map>

namespace llvm {
  /// Class AggressiveAntiDepState
  /// Contains all the state necessary for anti-dep breaking.
  class AggressiveAntiDepState {
  public:
    /// RegisterReference - Information about a register reference
    /// within a liverange
    typedef struct {
      /// Operand - The registers operand
      MachineOperand *Operand;
      /// RC - The register class
      const TargetRegisterClass *RC;
    } RegisterReference;

  private:
    /// NumTargetRegs - Number of non-virtual target registers
    /// (i.e. TRI->getNumRegs()).
    const unsigned NumTargetRegs;

    /// GroupNodes - Implements a disjoint-union data structure to
    /// form register groups. A node is represented by an index into
    /// the vector. A node can "point to" itself to indicate that it
    /// is the parent of a group, or point to another node to indicate
    /// that it is a member of the same group as that node.
    std::vector<unsigned> GroupNodes;

    /// GroupNodeIndices - For each register, the index of the GroupNode
    /// currently representing the group that the register belongs to.
    /// Register 0 is always represented by the 0 group, a group
    /// composed of registers that are not eligible for anti-aliasing.
    unsigned GroupNodeIndices[TargetRegisterInfo::FirstVirtualRegister];

    /// RegRefs - Map registers to all their references within a live range.
    std::multimap<unsigned, RegisterReference> RegRefs;

    /// KillIndices - The index of the most recent kill (proceding bottom-up),
    /// or ~0u if the register is not live.
    unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister];

    /// DefIndices - The index of the most recent complete def (proceding bottom
    /// up), or ~0u if the register is live.
    unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister];

  public:
    AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB);

    /// GetKillIndices - Return the kill indices.
    unsigned *GetKillIndices() { return KillIndices; }

    /// GetDefIndices - Return the define indices.
    unsigned *GetDefIndices() { return DefIndices; }

    /// GetRegRefs - Return the RegRefs map.
    std::multimap<unsigned, RegisterReference>& GetRegRefs() { return RegRefs; }

    // GetGroup - Get the group for a register. The returned value is
    // the index of the GroupNode representing the group.
    unsigned GetGroup(unsigned Reg);

    // GetGroupRegs - Return a vector of the registers belonging to a
    // group. If RegRefs is non-NULL then only included referenced registers.
    void GetGroupRegs(
       unsigned Group,
       std::vector<unsigned> &Regs,
       std::multimap<unsigned,
         AggressiveAntiDepState::RegisterReference> *RegRefs);

    // UnionGroups - Union Reg1's and Reg2's groups to form a new
    // group. Return the index of the GroupNode representing the
    // group.
    unsigned UnionGroups(unsigned Reg1, unsigned Reg2);

    // LeaveGroup - Remove a register from its current group and place
    // it alone in its own group. Return the index of the GroupNode
    // representing the registers new group.
    unsigned LeaveGroup(unsigned Reg);

    /// IsLive - Return true if Reg is live
    bool IsLive(unsigned Reg);
  };


  /// Class AggressiveAntiDepBreaker
  class AggressiveAntiDepBreaker : public AntiDepBreaker {
    MachineFunction& MF;
    MachineRegisterInfo &MRI;
    const TargetRegisterInfo *TRI;

    /// AllocatableSet - The set of allocatable registers.
    /// We'll be ignoring anti-dependencies on non-allocatable registers,
    /// because they may not be safe to break.
    const BitVector AllocatableSet;

    /// CriticalPathSet - The set of registers that should only be
    /// renamed if they are on the critical path.
    BitVector CriticalPathSet;

    /// State - The state used to identify and rename anti-dependence
    /// registers.
    AggressiveAntiDepState *State;

  public:
    AggressiveAntiDepBreaker(MachineFunction& MFi,
                             TargetSubtarget::RegClassVector& CriticalPathRCs);
    ~AggressiveAntiDepBreaker();

    /// Start - Initialize anti-dep breaking for a new basic block.
    void StartBlock(MachineBasicBlock *BB);

    /// BreakAntiDependencies - Identifiy anti-dependencies along the critical
    /// path
    /// of the ScheduleDAG and break them by renaming registers.
    ///
    unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,
                                   MachineBasicBlock::iterator& Begin,
                                   MachineBasicBlock::iterator& End,
                                   unsigned InsertPosIndex);

    /// Observe - Update liveness information to account for the current
    /// instruction, which will not be scheduled.
    ///
    void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex);

    /// Finish - Finish anti-dep breaking for a basic block.
    void FinishBlock();

  private:
    typedef std::map<const TargetRegisterClass *,
                     TargetRegisterClass::const_iterator> RenameOrderType;

    /// IsImplicitDefUse - Return true if MO represents a register
    /// that is both implicitly used and defined in MI
    bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO);

    /// GetPassthruRegs - If MI implicitly def/uses a register, then
    /// return that register and all subregisters.
    void GetPassthruRegs(MachineInstr *MI, std::set<unsigned>& PassthruRegs);

    void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag,
                       const char *header =NULL, const char *footer =NULL);

    void PrescanInstruction(MachineInstr *MI, unsigned Count,
                            std::set<unsigned>& PassthruRegs);
    void ScanInstruction(MachineInstr *MI, unsigned Count);
    BitVector GetRenameRegisters(unsigned Reg);
    bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex,
                                   RenameOrderType& RenameOrder,
                                   std::map<unsigned, unsigned> &RenameMap);
  };
}

#endif
