aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen/StableID.h
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include/rcc/CodeGen/StableID.h')
-rw-r--r--backend/include/rcc/CodeGen/StableID.h92
1 files changed, 92 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/StableID.h b/backend/include/rcc/CodeGen/StableID.h
new file mode 100644
index 0000000..89a4266
--- /dev/null
+++ b/backend/include/rcc/CodeGen/StableID.h
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_STABLEID_H
+#define RCC_CODEGEN_STABLEID_H
+
+#include "rcc/Support/Error.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <type_traits>
+
+namespace rcc {
+
+template <typename TagT> 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<detail::MachineFunctionStableIDTag>;
+using MachineBlockStableID = StableID<detail::MachineBlockStableIDTag>;
+using MachineInstrStableID = StableID<detail::MachineInstrStableIDTag>;
+
+template <typename StableIDT> 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<StableIDT> allocate() {
+ if (NextValue == 0) {
+ return makeUnexpected(ErrorCode::InternalError, "stable ID space is exhausted");
+ }
+
+ const StableIDT Result = StableIDT::fromValue(NextValue);
+ if (NextValue == std::numeric_limits<std::uint64_t>::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<MachineFunctionStableID>);
+static_assert(std::is_trivially_copyable_v<MachineBlockStableID>);
+static_assert(std::is_trivially_copyable_v<MachineInstrStableID>);
+
+} // namespace rcc
+
+template <typename TagT> struct std::hash<rcc::StableID<TagT>> {
+ [[nodiscard]] std::size_t operator()(rcc::StableID<TagT> ID) const noexcept {
+ return std::hash<std::uint64_t>{}(ID.value());
+ }
+};
+
+#endif // RCC_CODEGEN_STABLEID_H