aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/CodeGen')
-rw-r--r--backend/lib/CodeGen/CMakeLists.txt4
-rw-r--r--backend/lib/CodeGen/CompilationUnit.cpp119
2 files changed, 123 insertions, 0 deletions
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt
index 3a45cec..2c4f6f8 100644
--- a/backend/lib/CodeGen/CMakeLists.txt
+++ b/backend/lib/CodeGen/CMakeLists.txt
@@ -2,6 +2,7 @@
set(
RCCBackendCodeGenSources
+ CompilationUnit.cpp
InstructionDescriptor.cpp
LowLevelType.cpp
MachineCompilationStatus.cpp
@@ -29,6 +30,7 @@ set(
)
set(
RCCBackendCodeGenHeaders
+ "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/CompilationUnit.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/InstructionDescriptor.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/LowLevelType.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineCompilationStatus.h"
@@ -85,6 +87,7 @@ install(
)
rcc_backend_register_format_files(
+ "${CMAKE_CURRENT_SOURCE_DIR}/CompilationUnit.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/InstructionDescriptor.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LowLevelType.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineCompilationStatus.cpp"
@@ -112,6 +115,7 @@ rcc_backend_register_format_files(
${RCCBackendCodeGenHeaders}
)
rcc_backend_register_tidy_files(
+ "${CMAKE_CURRENT_SOURCE_DIR}/CompilationUnit.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/InstructionDescriptor.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LowLevelType.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineCompilationStatus.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 <cstddef>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <unordered_set>
+#include <utility>
+
+namespace rcc {
+
+CompilationUnit::CompilationUnit() = default;
+
+CompilationUnit::CompilationUnit(CompilationUnit &&) noexcept = default;
+
+CompilationUnit &CompilationUnit::operator=(CompilationUnit &&) noexcept = default;
+
+CompilationUnit::~CompilationUnit() = default;
+
+Expected<MachineFunction *> 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<MachineFunction> &Function : Functions) {
+ if (Function->stableID() == ID)
+ return Function.get();
+ }
+ return nullptr;
+}
+
+const MachineFunction *CompilationUnit::function(MachineFunctionStableID ID) const noexcept {
+ for (const std::unique_ptr<MachineFunction> &Function : Functions) {
+ if (Function->stableID() == ID)
+ return Function.get();
+ }
+ return nullptr;
+}
+
+Expected<void> CompilationUnit::verify() const {
+ if (FunctionNameToIndex.size() != Functions.size()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "compilation unit function name index has an inconsistent size");
+ }
+
+ std::unordered_set<MachineFunctionStableID> StableIDs;
+ for (std::size_t Index = 0; Index < Functions.size(); ++Index) {
+ const std::unique_ptr<MachineFunction> &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