From a2f8d7c5e22b510965327383410bd576f7cf28e7 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Thu, 13 Aug 2026 04:17:52 +0800 Subject: [CodeGen] Split machine liveness components --- backend/include/rcc/CodeGen/SlotIndexes.h | 130 ++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 backend/include/rcc/CodeGen/SlotIndexes.h (limited to 'backend/include/rcc/CodeGen/SlotIndexes.h') diff --git a/backend/include/rcc/CodeGen/SlotIndexes.h b/backend/include/rcc/CodeGen/SlotIndexes.h new file mode 100644 index 0000000..1767596 --- /dev/null +++ b/backend/include/rcc/CodeGen/SlotIndexes.h @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_SLOTINDEXES_H +#define RCC_CODEGEN_SLOTINDEXES_H + +#include "rcc/CodeGen/MachineIRTypes.h" +#include "rcc/CodeGen/MachinePass.h" +#include "rcc/CodeGen/StableID.h" +#include "rcc/Support/Error.h" + +#include +#include +#include +#include +#include +#include + +namespace rcc { + +class MachineBasicBlock; +class MachineFunction; +class MachineInstr; +class TargetDescription; + +enum class SlotIndexKind : std::uint8_t { + Block, + EarlyClobber, + Register, + Dead, +}; + +class SlotIndex final { +public: + constexpr SlotIndex() noexcept = default; + + [[nodiscard]] static constexpr SlotIndex fromValue(std::uint64_t Value) noexcept { + return SlotIndex(Value); + } + + [[nodiscard]] constexpr bool isValid() const noexcept { + return Value != 0; + } + + [[nodiscard]] constexpr std::uint64_t value() const noexcept { + return Value; + } + + [[nodiscard]] constexpr SlotIndexKind kind() const noexcept { + return static_cast(Value & KindMask); + } + + [[nodiscard]] constexpr SlotIndex baseIndex() const noexcept { + return SlotIndex(Value & ~KindMask); + } + + [[nodiscard]] constexpr SlotIndex withKind(SlotIndexKind Kind) const noexcept { + return isValid() ? SlotIndex((Value & ~KindMask) | static_cast(Kind)) + : SlotIndex{}; + } + + [[nodiscard]] constexpr SlotIndex earlyClobberSlot() const noexcept { + return withKind(SlotIndexKind::EarlyClobber); + } + + [[nodiscard]] constexpr SlotIndex registerSlot() const noexcept { + return withKind(SlotIndexKind::Register); + } + + [[nodiscard]] constexpr SlotIndex deadSlot() const noexcept { + return withKind(SlotIndexKind::Dead); + } + + friend constexpr bool operator==(SlotIndex, SlotIndex) noexcept = default; + friend constexpr auto operator<=>(SlotIndex, SlotIndex) noexcept = default; + +private: + static constexpr std::uint64_t KindMask = 3; + + explicit constexpr SlotIndex(std::uint64_t Value) noexcept : Value(Value) {} + + std::uint64_t Value = 0; +}; + +class SlotIndexesAnalysis final { +public: + class Result final { + public: + [[nodiscard]] SlotIndex instructionIndex(const MachineInstr &Instruction) const noexcept; + [[nodiscard]] SlotIndex slot(const MachineInstr &Instruction) const noexcept { + return instructionIndex(Instruction); + } + [[nodiscard]] SlotIndex blockStart(const MachineBasicBlock &Block) const noexcept; + [[nodiscard]] SlotIndex blockEnd(const MachineBasicBlock &Block) const noexcept; + [[nodiscard]] const MachineInstr *instructionFromIndex(SlotIndex Index) const noexcept; + [[nodiscard]] const MachineBasicBlock *blockFromIndex(SlotIndex Index) const noexcept; + + [[nodiscard]] Expected insertInstruction(const MachineInstr &Instruction); + [[nodiscard]] Expected eraseInstruction(const MachineInstr &Instruction); + [[nodiscard]] Expected renumber(MachineFunction &Function); + + [[nodiscard]] bool invalidate(const MachineFunction &, + const PreservedAnalyses &Preserved) const noexcept; + + private: + std::unordered_map InstructionSlots; + std::unordered_map SlotToInstruction; + std::unordered_map BlockStarts; + std::unordered_map BlockEnds; + std::vector BlocksByStart; + + friend class SlotIndexesAnalysis; + }; + + [[nodiscard]] static constexpr std::string_view name() noexcept { + return "SlotIndexes"; + } + + [[nodiscard]] static Expected + run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses); +}; + +} // namespace rcc + +template <> struct std::hash { + [[nodiscard]] std::size_t operator()(rcc::SlotIndex Index) const noexcept { + return std::hash{}(Index.value()); + } +}; + +#endif // RCC_CODEGEN_SLOTINDEXES_H -- cgit v1.2.3