//==- llvm/CodeGen/AggressiveAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-==//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// 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_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H
#define LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H

#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/AntiDepBreaker.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Support/Compiler.h"
#include <map>
#include <set>
#include <vector>

namespace llvm {

class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
class MachineOperand;
class MachineRegisterInfo;
class RegisterClassInfo;
class TargetInstrInfo;
class TargetRegisterClass;
class TargetRegisterInfo;

  /// Contains all the state necessary for anti-dep breaking.
class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepState {
  public:
    /// Information about a register reference within a liverange
    struct RegisterReference {
      /// The registers operand
      MachineOperand *Operand;

      /// The register class
      const TargetRegisterClass *RC;
    };

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

    /// 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;

    /// 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.
    std::vector<unsigned> GroupNodeIndices;

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

    /// The index of the most recent kill (proceeding bottom-up),
    /// or ~0u if the register is not live.
    std::vector<unsigned> KillIndices;

    /// The index of the most recent complete def (proceeding bottom
    /// up), or ~0u if the register is live.
    std::vector<unsigned> DefIndices;

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

    /// Return the kill indices.
    std::vector<unsigned> &GetKillIndices() { return KillIndices; }

    /// Return the define indices.
    std::vector<unsigned> &GetDefIndices() { return DefIndices; }

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

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

    // 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<MCRegister> &Regs,
        std::multimap<MCRegister, AggressiveAntiDepState::RegisterReference>
            *RegRefs);

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

    // 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(MCRegister Reg);

    /// Return true if Reg is live.
    bool IsLive(MCRegister Reg);
  };

  class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepBreaker
      : public AntiDepBreaker {
    MachineFunction &MF;
    MachineRegisterInfo &MRI;
    const TargetInstrInfo *TII;
    const TargetRegisterInfo *TRI;
    const RegisterClassInfo &RegClassInfo;

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

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

  public:
    AggressiveAntiDepBreaker(MachineFunction &MFi,
                          const RegisterClassInfo &RCI,
                          TargetSubtargetInfo::RegClassVector& CriticalPathRCs);
    AggressiveAntiDepBreaker &
    operator=(const AggressiveAntiDepBreaker &other) = delete;
    AggressiveAntiDepBreaker(const AggressiveAntiDepBreaker &other) = delete;
    ~AggressiveAntiDepBreaker() override;

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

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

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

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

  private:
    /// Keep track of a position in the allocation order for each regclass.
    using RenameOrderType = std::map<const TargetRegisterClass *, unsigned>;

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

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

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

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

} // end namespace llvm

#endif // LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H
