// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_LIVEREGMATRIX_H #define RCC_CODEGEN_LIVEREGMATRIX_H #include "rcc/CodeGen/LiveIntervals.h" #include "rcc/CodeGen/TargetRegisterInfo.h" #include #include #include #include #include #include namespace rcc { class MachineFunction; class TargetDescription; enum class RegisterInterferenceKind : std::uint8_t { Free, VirtualRegister, FixedRegister, RegisterMask, RegisterUnit, }; struct RegisterInterference final { RegisterInterferenceKind Kind = RegisterInterferenceKind::Free; std::optional VirtualReg; std::optional FixedReg; std::optional Unit; std::optional Instruction; }; class LiveRegMatrix final { public: LiveRegMatrix(const MachineFunction &Function, const TargetDescription &Target, const LiveIntervalsAnalysis::Result &Intervals) noexcept : Function(&Function), Target(&Target), Intervals(&Intervals) {} [[nodiscard]] Expected assign(Register VirtualReg, PhysicalRegister PhysicalReg); [[nodiscard]] Expected unassign(Register VirtualReg); [[nodiscard]] std::optional assignment(Register VirtualReg) const noexcept; [[nodiscard]] RegisterInterference checkInterference(Register VirtualReg, PhysicalRegister PhysicalReg) const noexcept; [[nodiscard]] std::vector collectInterferences(Register VirtualReg, PhysicalRegister PhysicalReg) const; [[nodiscard]] std::span> assignments() const noexcept { return OrderedAssignments; } private: [[nodiscard]] bool intervalsOverlapOnCandidates(const LiveInterval &Left, PhysicalRegister LeftReg, const LiveInterval &Right, PhysicalRegister RightReg) const noexcept; [[nodiscard]] bool intervalOverlapsUnit(const LiveInterval &Interval, RegisterUnitLane Unit, const LiveRange &UnitRange) const noexcept; const MachineFunction *Function; const TargetDescription *Target; const LiveIntervalsAnalysis::Result *Intervals; std::unordered_map Assignments; std::vector> OrderedAssignments; }; } // namespace rcc #endif // RCC_CODEGEN_LIVEREGMATRIX_H