From 77d76b73a614820bf45024b053db376f35b06d10 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 1 Aug 2026 17:10:33 +0800 Subject: [MIR] Add compilation unit reference context --- backend/lib/CodeGen/CompilationUnit.cpp | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 backend/lib/CodeGen/CompilationUnit.cpp (limited to 'backend/lib/CodeGen/CompilationUnit.cpp') diff --git a/backend/lib/CodeGen/CompilationUnit.cpp b/backend/lib/CodeGen/CompilationUnit.cpp new file mode 100644 index 0000000..1de6487 --- /dev/null +++ b/backend/lib/CodeGen/CompilationUnit.cpp @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/CodeGen/CompilationUnit.h" + +#include "rcc/CodeGen/MachineFunction.h" + +#include +#include +#include +#include +#include +#include + +namespace rcc { + +CompilationUnit::CompilationUnit() = default; + +CompilationUnit::CompilationUnit(CompilationUnit &&) noexcept = default; + +CompilationUnit &CompilationUnit::operator=(CompilationUnit &&) noexcept = default; + +CompilationUnit::~CompilationUnit() = default; + +Expected CompilationUnit::createMachineFunction(std::string Name) { + if (Name.empty()) + return makeUnexpected(ErrorCode::InvalidArgument, "machine function name cannot be empty"); + if (FunctionNameToIndex.contains(Name)) { + return makeUnexpected(ErrorCode::InvalidArgument, + "machine function name is already present in the compilation unit"); + } + + auto StableID = FunctionIDGenerator.allocate(); + if (!StableID) + return std::unexpected(StableID.error()); + auto Function = MachineFunction::create(std::move(Name), *StableID); + if (!Function) + return std::unexpected(Function.error()); + + MachineFunction *Result = Function->get(); + const std::size_t Index = Functions.size(); + FunctionNameToIndex.emplace(std::string(Result->name()), Index); + Functions.push_back(std::move(*Function)); + return Result; +} + +MachineFunction *CompilationUnit::functionAt(std::size_t Index) noexcept { + if (Index >= Functions.size()) + return nullptr; + return Functions[Index].get(); +} + +const MachineFunction *CompilationUnit::functionAt(std::size_t Index) const noexcept { + if (Index >= Functions.size()) + return nullptr; + return Functions[Index].get(); +} + +MachineFunction *CompilationUnit::function(std::string_view Name) noexcept { + const auto Position = FunctionNameToIndex.find(Name); + if (Position == FunctionNameToIndex.end()) + return nullptr; + return Functions[Position->second].get(); +} + +const MachineFunction *CompilationUnit::function(std::string_view Name) const noexcept { + const auto Position = FunctionNameToIndex.find(Name); + if (Position == FunctionNameToIndex.end()) + return nullptr; + return Functions[Position->second].get(); +} + +MachineFunction *CompilationUnit::function(MachineFunctionStableID ID) noexcept { + for (const std::unique_ptr &Function : Functions) { + if (Function->stableID() == ID) + return Function.get(); + } + return nullptr; +} + +const MachineFunction *CompilationUnit::function(MachineFunctionStableID ID) const noexcept { + for (const std::unique_ptr &Function : Functions) { + if (Function->stableID() == ID) + return Function.get(); + } + return nullptr; +} + +Expected CompilationUnit::verify() const { + if (FunctionNameToIndex.size() != Functions.size()) { + return makeUnexpected(ErrorCode::VerificationError, + "compilation unit function name index has an inconsistent size"); + } + + std::unordered_set StableIDs; + for (std::size_t Index = 0; Index < Functions.size(); ++Index) { + const std::unique_ptr &Function = Functions[Index]; + if (Function == nullptr) { + return makeUnexpected(ErrorCode::VerificationError, + "compilation unit contains a null machine function"); + } + if (Function->name().empty() || !Function->stableID().isValid()) { + return makeUnexpected(ErrorCode::VerificationError, + "compilation unit contains an invalid machine function identity"); + } + if (!StableIDs.insert(Function->stableID()).second) { + return makeUnexpected(ErrorCode::VerificationError, + "compilation unit contains duplicate machine function StableIDs"); + } + + const auto Position = FunctionNameToIndex.find(Function->name()); + if (Position == FunctionNameToIndex.end() || Position->second != Index) { + return makeUnexpected(ErrorCode::VerificationError, + "compilation unit function name index is inconsistent"); + } + } + return {}; +} + +} // namespace rcc -- cgit v1.2.3