// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_VIRTREGMAP_H #define RCC_CODEGEN_VIRTREGMAP_H #include "rcc/CodeGen/MachineFrameInfo.h" #include "rcc/CodeGen/MachinePassManager.h" #include "rcc/CodeGen/TargetRegisterInfo.h" #include #include #include #include #include namespace rcc { class MachineFunction; class TargetDescription; enum class VirtRegAllocationState : std::uint8_t { Unassigned, Assigned, Spilled, Split, }; struct VirtRegSpillMetadata final { std::optional StackSlot; LaneMask Lanes = LaneMask::all(); std::uint64_t SpillCount = 0; std::uint64_t ReloadCount = 0; std::uint64_t RematerializationCount = 0; }; struct VirtRegMapEntry final { Register VirtualReg; VirtRegAllocationState State = VirtRegAllocationState::Unassigned; std::optional PhysicalReg; std::optional SplitParent; std::optional Origin; bool Spillable = true; VirtRegSpillMetadata Spill; }; class VirtRegMap final { public: explicit VirtRegMap(MachineFunction &Function) noexcept : Function(&Function) {} [[nodiscard]] MachineFunction &function() const noexcept { return *Function; } [[nodiscard]] Expected add(Register VirtualReg, bool Spillable = true, std::optional SplitParent = std::nullopt, std::optional Origin = std::nullopt); [[nodiscard]] Expected assign(Register VirtualReg, PhysicalRegister PhysicalReg); [[nodiscard]] Expected assignStackSlot(Register VirtualReg, FrameIndex StackSlot, LaneMask Lanes = LaneMask::all()); [[nodiscard]] Expected markSplit(Register VirtualReg, Register Parent, Register Origin); [[nodiscard]] Expected setSpillable(Register VirtualReg, bool Spillable); [[nodiscard]] VirtRegMapEntry *entry(Register VirtualReg) noexcept; [[nodiscard]] const VirtRegMapEntry *entry(Register VirtualReg) const noexcept; [[nodiscard]] std::optional physicalRegister(Register VirtualReg) const noexcept; [[nodiscard]] std::optional stackSlot(Register VirtualReg) const noexcept; [[nodiscard]] bool isSpillable(Register VirtualReg) const noexcept; [[nodiscard]] std::vector orderedEntries() const; [[nodiscard]] Expected verify() const; private: MachineFunction *Function; std::unordered_map Entries; }; [[nodiscard]] Expected rewriteVirtualRegisters(MachineFunction &Function, const TargetDescription &Target, const VirtRegMap &Mapping); class VirtRegMapAnalysis final { public: using Result = VirtRegMap; [[nodiscard]] static constexpr std::string_view name() noexcept { return "VirtRegMap"; } [[nodiscard]] static Expected run(MachineFunction &Function, const TargetDescription &Target, MachineFunctionAnalysisManager &Analyses); }; class VirtualRegisterRewritePass final : public MachineFunctionPass { public: [[nodiscard]] const MachinePassContract &contract() const noexcept override; [[nodiscard]] Expected run(MachineFunction &Function, const TargetDescription &Target, MachineFunctionAnalysisManager &Analyses) override; }; } // namespace rcc #endif // RCC_CODEGEN_VIRTREGMAP_H