Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h
35233 views
//==- llvm/CodeGen/AggressiveAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the AggressiveAntiDepBreaker class, which9// implements register anti-dependence breaking during post-RA10// scheduling. It attempts to break all anti-dependencies within a11// block.12//13//===----------------------------------------------------------------------===//1415#ifndef LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H16#define LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H1718#include "llvm/ADT/BitVector.h"19#include "llvm/CodeGen/AntiDepBreaker.h"20#include "llvm/CodeGen/TargetSubtargetInfo.h"21#include "llvm/Support/Compiler.h"22#include <map>23#include <set>24#include <vector>2526namespace llvm {2728class MachineBasicBlock;29class MachineFunction;30class MachineInstr;31class MachineOperand;32class MachineRegisterInfo;33class RegisterClassInfo;34class TargetInstrInfo;35class TargetRegisterClass;36class TargetRegisterInfo;3738/// Contains all the state necessary for anti-dep breaking.39class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepState {40public:41/// Information about a register reference within a liverange42struct RegisterReference {43/// The registers operand44MachineOperand *Operand;4546/// The register class47const TargetRegisterClass *RC;48};4950private:51/// Number of non-virtual target registers (i.e. TRI->getNumRegs()).52const unsigned NumTargetRegs;5354/// Implements a disjoint-union data structure to55/// form register groups. A node is represented by an index into56/// the vector. A node can "point to" itself to indicate that it57/// is the parent of a group, or point to another node to indicate58/// that it is a member of the same group as that node.59std::vector<unsigned> GroupNodes;6061/// For each register, the index of the GroupNode62/// currently representing the group that the register belongs to.63/// Register 0 is always represented by the 0 group, a group64/// composed of registers that are not eligible for anti-aliasing.65std::vector<unsigned> GroupNodeIndices;6667/// Map registers to all their references within a live range.68std::multimap<unsigned, RegisterReference> RegRefs;6970/// The index of the most recent kill (proceeding bottom-up),71/// or ~0u if the register is not live.72std::vector<unsigned> KillIndices;7374/// The index of the most recent complete def (proceeding bottom75/// up), or ~0u if the register is live.76std::vector<unsigned> DefIndices;7778public:79AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB);8081/// Return the kill indices.82std::vector<unsigned> &GetKillIndices() { return KillIndices; }8384/// Return the define indices.85std::vector<unsigned> &GetDefIndices() { return DefIndices; }8687/// Return the RegRefs map.88std::multimap<unsigned, RegisterReference>& GetRegRefs() { return RegRefs; }8990// Get the group for a register. The returned value is91// the index of the GroupNode representing the group.92unsigned GetGroup(unsigned Reg);9394// Return a vector of the registers belonging to a group.95// If RegRefs is non-NULL then only included referenced registers.96void GetGroupRegs(97unsigned Group,98std::vector<unsigned> &Regs,99std::multimap<unsigned,100AggressiveAntiDepState::RegisterReference> *RegRefs);101102// Union Reg1's and Reg2's groups to form a new group.103// Return the index of the GroupNode representing the group.104unsigned UnionGroups(unsigned Reg1, unsigned Reg2);105106// Remove a register from its current group and place107// it alone in its own group. Return the index of the GroupNode108// representing the registers new group.109unsigned LeaveGroup(unsigned Reg);110111/// Return true if Reg is live.112bool IsLive(unsigned Reg);113};114115class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepBreaker116: public AntiDepBreaker {117MachineFunction &MF;118MachineRegisterInfo &MRI;119const TargetInstrInfo *TII;120const TargetRegisterInfo *TRI;121const RegisterClassInfo &RegClassInfo;122123/// The set of registers that should only be124/// renamed if they are on the critical path.125BitVector CriticalPathSet;126127/// The state used to identify and rename anti-dependence registers.128AggressiveAntiDepState *State = nullptr;129130public:131AggressiveAntiDepBreaker(MachineFunction &MFi,132const RegisterClassInfo &RCI,133TargetSubtargetInfo::RegClassVector& CriticalPathRCs);134AggressiveAntiDepBreaker &135operator=(const AggressiveAntiDepBreaker &other) = delete;136AggressiveAntiDepBreaker(const AggressiveAntiDepBreaker &other) = delete;137~AggressiveAntiDepBreaker() override;138139/// Initialize anti-dep breaking for a new basic block.140void StartBlock(MachineBasicBlock *BB) override;141142/// Identifiy anti-dependencies along the critical path143/// of the ScheduleDAG and break them by renaming registers.144unsigned BreakAntiDependencies(const std::vector<SUnit> &SUnits,145MachineBasicBlock::iterator Begin,146MachineBasicBlock::iterator End,147unsigned InsertPosIndex,148DbgValueVector &DbgValues) override;149150/// Update liveness information to account for the current151/// instruction, which will not be scheduled.152void Observe(MachineInstr &MI, unsigned Count,153unsigned InsertPosIndex) override;154155/// Finish anti-dep breaking for a basic block.156void FinishBlock() override;157158private:159/// Keep track of a position in the allocation order for each regclass.160using RenameOrderType = std::map<const TargetRegisterClass *, unsigned>;161162/// Return true if MO represents a register163/// that is both implicitly used and defined in MI164bool IsImplicitDefUse(MachineInstr &MI, MachineOperand &MO);165166/// If MI implicitly def/uses a register, then167/// return that register and all subregisters.168void GetPassthruRegs(MachineInstr &MI, std::set<unsigned> &PassthruRegs);169170void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag,171const char *header = nullptr,172const char *footer = nullptr);173174void PrescanInstruction(MachineInstr &MI, unsigned Count,175std::set<unsigned> &PassthruRegs);176void ScanInstruction(MachineInstr &MI, unsigned Count);177BitVector GetRenameRegisters(unsigned Reg);178bool FindSuitableFreeRegisters(unsigned SuperReg,179unsigned AntiDepGroupIndex,180RenameOrderType &RenameOrder,181std::map<unsigned, unsigned> &RenameMap);182};183184} // end namespace llvm185186#endif // LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H187188189