diff options
Diffstat (limited to 'llvm/lib/CodeGen/AggressiveAntiDepBreaker.h')
| -rw-r--r-- | llvm/lib/CodeGen/AggressiveAntiDepBreaker.h | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h new file mode 100644 index 000000000000..0cf2e6d78f7f --- /dev/null +++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h @@ -0,0 +1,183 @@ +//==- 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 "AntiDepBreaker.h" +#include "llvm/ADT/BitVector.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<unsigned, 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<unsigned, RegisterReference>& GetRegRefs() { return RegRefs; } + + // Get the group for a register. The returned value is + // the index of the GroupNode representing the group. + unsigned GetGroup(unsigned 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<unsigned> &Regs, + std::multimap<unsigned, + 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(unsigned Reg1, unsigned 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(unsigned Reg); + + /// Return true if Reg is live. + bool IsLive(unsigned 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() 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<unsigned> &PassthruRegs); + + void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag, + const char *header = nullptr, + const char *footer = nullptr); + + 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); + }; + +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H |
