// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_STABLEID_H #define RCC_CODEGEN_STABLEID_H #include "rcc/Support/Error.h" #include #include #include #include #include namespace rcc { template class StableID final { public: constexpr StableID() noexcept = default; [[nodiscard]] static constexpr StableID fromValue(std::uint64_t Value) noexcept { return StableID(Value); } [[nodiscard]] constexpr bool isValid() const noexcept { return Value != 0; } [[nodiscard]] constexpr std::uint64_t value() const noexcept { return Value; } friend constexpr bool operator==(StableID Left, StableID Right) noexcept = default; private: explicit constexpr StableID(std::uint64_t Value) noexcept : Value(Value) {} std::uint64_t Value = 0; }; namespace detail { struct MachineFunctionStableIDTag; struct MachineBlockStableIDTag; struct MachineInstrStableIDTag; } // namespace detail using MachineFunctionStableID = StableID; using MachineBlockStableID = StableID; using MachineInstrStableID = StableID; template class StableIDGenerator final { public: StableIDGenerator() = default; StableIDGenerator(const StableIDGenerator &) = delete; StableIDGenerator &operator=(const StableIDGenerator &) = delete; StableIDGenerator(StableIDGenerator &&) noexcept = default; StableIDGenerator &operator=(StableIDGenerator &&) noexcept = default; [[nodiscard]] Expected allocate() { if (NextValue == 0) { return makeUnexpected(ErrorCode::InternalError, "stable ID space is exhausted"); } const StableIDT Result = StableIDT::fromValue(NextValue); if (NextValue == std::numeric_limits::max()) NextValue = 0; else ++NextValue; return Result; } private: std::uint64_t NextValue = 1; }; static_assert(sizeof(MachineFunctionStableID) == sizeof(std::uint64_t)); static_assert(sizeof(MachineBlockStableID) == sizeof(std::uint64_t)); static_assert(sizeof(MachineInstrStableID) == sizeof(std::uint64_t)); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); static_assert(std::is_trivially_copyable_v); } // namespace rcc template struct std::hash> { [[nodiscard]] std::size_t operator()(rcc::StableID ID) const noexcept { return std::hash{}(ID.value()); } }; #endif // RCC_CODEGEN_STABLEID_H