aboutsummaryrefslogtreecommitdiff
path: root/backend/include
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-04 05:34:15 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-04 05:34:15 +0800
commit183e2354e9fdd107be420cbb185c1d239434aa48 (patch)
treece5c42cb6e9790072d5dcf00d1d55cb7f6573ddc /backend/include
parent67d6231fba98e776c0f442e5b6908e279c35e346 (diff)
downloadrcc-project-183e2354e9fdd107be420cbb185c1d239434aa48.tar.gz
rcc-project-183e2354e9fdd107be420cbb185c1d239434aa48.tar.xz
[MIR] Add machine instruction parser and printer
Parse MachineFunction bodies in two passes and serialize the same MachineIR model in complete or readable form. Extend instruction attachments and memory operands required by the fixed LLVM MIR grammar, and cover deterministic parse-print round trips.
Diffstat (limited to 'backend/include')
-rw-r--r--backend/include/rcc/CodeGen/MachineInstr.h59
-rw-r--r--backend/include/rcc/CodeGen/MachineMemOperand.h23
-rw-r--r--backend/include/rcc/MIR/MIParser.h95
-rw-r--r--backend/include/rcc/MIR/MIPrinter.h35
4 files changed, 212 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/MachineInstr.h b/backend/include/rcc/CodeGen/MachineInstr.h
index 69d7dd7..e7294b4 100644
--- a/backend/include/rcc/CodeGen/MachineInstr.h
+++ b/backend/include/rcc/CodeGen/MachineInstr.h
@@ -13,6 +13,8 @@
#include <functional>
#include <optional>
#include <span>
+#include <string>
+#include <string_view>
#include <utility>
#include <vector>
@@ -154,6 +156,56 @@ public:
DebugInstrNumber = 0;
}
+ [[nodiscard]] std::optional<std::string_view> preInstrSymbol() const noexcept;
+ [[nodiscard]] Expected<void> setPreInstrSymbol(std::string Symbol);
+ void clearPreInstrSymbol() noexcept {
+ PreInstrSymbol.reset();
+ }
+
+ [[nodiscard]] std::optional<std::string_view> postInstrSymbol() const noexcept;
+ [[nodiscard]] Expected<void> setPostInstrSymbol(std::string Symbol);
+ void clearPostInstrSymbol() noexcept {
+ PostInstrSymbol.reset();
+ }
+
+ [[nodiscard]] const std::optional<MachineMetadataReference> &heapAllocMarker() const noexcept {
+ return HeapAllocMarker;
+ }
+ [[nodiscard]] Expected<void> setHeapAllocMarker(MachineMetadataReference Marker);
+ void clearHeapAllocMarker() noexcept {
+ HeapAllocMarker.reset();
+ }
+
+ [[nodiscard]] const std::optional<MachineMetadataReference> &pcSections() const noexcept {
+ return PCSections;
+ }
+ [[nodiscard]] Expected<void> setPCSections(MachineMetadataReference Sections);
+ void clearPCSections() noexcept {
+ PCSections.reset();
+ }
+
+ [[nodiscard]] const std::optional<MachineMetadataReference> &mmra() const noexcept {
+ return MMRA;
+ }
+ [[nodiscard]] Expected<void> setMMRA(MachineMetadataReference Metadata);
+ void clearMMRA() noexcept {
+ MMRA.reset();
+ }
+
+ [[nodiscard]] std::optional<std::uint32_t> cfiType() const noexcept {
+ return CFIType;
+ }
+ [[nodiscard]] Expected<void> setCFIType(std::uint64_t Type);
+ void clearCFIType() noexcept {
+ CFIType.reset();
+ }
+
+ [[nodiscard]] std::optional<std::string_view> deactivationSymbol() const noexcept;
+ [[nodiscard]] Expected<void> setDeactivationSymbol(std::string Symbol);
+ void clearDeactivationSymbol() noexcept {
+ DeactivationSymbol.reset();
+ }
+
private:
MachineInstr(MachineFunction &OwnerFunction, Opcode InstructionOpcode,
MachineInstrStableID StableID);
@@ -177,6 +229,13 @@ private:
std::optional<MachineDebugLocation> DebugLocation;
std::optional<OriginID> Origin;
std::uint32_t DebugInstrNumber = 0;
+ std::optional<std::string> PreInstrSymbol;
+ std::optional<std::string> PostInstrSymbol;
+ std::optional<MachineMetadataReference> HeapAllocMarker;
+ std::optional<MachineMetadataReference> PCSections;
+ std::optional<MachineMetadataReference> MMRA;
+ std::optional<std::uint32_t> CFIType;
+ std::optional<std::string> DeactivationSymbol;
friend class MachineArena;
friend class MachineBasicBlock;
diff --git a/backend/include/rcc/CodeGen/MachineMemOperand.h b/backend/include/rcc/CodeGen/MachineMemOperand.h
index b6cb07f..a9e19a6 100644
--- a/backend/include/rcc/CodeGen/MachineMemOperand.h
+++ b/backend/include/rcc/CodeGen/MachineMemOperand.h
@@ -5,6 +5,7 @@
#include "rcc/CodeGen/LowLevelType.h"
#include "rcc/CodeGen/MachineIRTypes.h"
+#include "rcc/CodeGen/MachineMetadata.h"
#include <cstdint>
#include <initializer_list>
@@ -138,6 +139,14 @@ public:
JumpTable,
GlobalSymbol,
ExternalSymbol,
+ IRValue,
+ Stack,
+ GOT,
+ ConstantPoolPseudo,
+ JumpTablePseudo,
+ CallEntryGlobal,
+ CallEntryExternal,
+ Custom,
};
MemoryBase() = default;
@@ -147,6 +156,14 @@ public:
[[nodiscard]] static MemoryBase jumpTable(JumpTableIndex Index);
[[nodiscard]] static MemoryBase globalSymbol(std::string Name);
[[nodiscard]] static MemoryBase externalSymbol(std::string Name);
+ [[nodiscard]] static MemoryBase irValue(std::string Name);
+ [[nodiscard]] static MemoryBase stack();
+ [[nodiscard]] static MemoryBase got();
+ [[nodiscard]] static MemoryBase constantPoolPseudo();
+ [[nodiscard]] static MemoryBase jumpTablePseudo();
+ [[nodiscard]] static MemoryBase callEntryGlobal(std::string Name);
+ [[nodiscard]] static MemoryBase callEntryExternal(std::string Name);
+ [[nodiscard]] static MemoryBase custom(std::string Name);
[[nodiscard]] Kind kind() const noexcept {
return BaseKind;
@@ -177,11 +194,17 @@ struct MachineMemOperandDesc final {
SyncScopeID SyncScope;
MemorySize Size;
Alignment Align;
+ std::optional<Alignment> BaseAlign;
std::uint32_t AddressSpace = 0;
MemoryBase Base;
std::int64_t Offset = 0;
std::optional<MemoryOffsetRange> OffsetRange;
std::optional<MemoryAliasSourceID> AliasSource;
+ std::optional<MachineMetadataReference> TBAA;
+ std::optional<MachineMetadataReference> AliasScope;
+ std::optional<MachineMetadataReference> NoAlias;
+ std::optional<MachineMetadataReference> NoAliasAddressSpace;
+ std::optional<MachineMetadataReference> RangeMetadata;
std::uint16_t TargetFlags = 0;
friend bool operator==(const MachineMemOperandDesc &Left,
diff --git a/backend/include/rcc/MIR/MIParser.h b/backend/include/rcc/MIR/MIParser.h
new file mode 100644
index 0000000..978e928
--- /dev/null
+++ b/backend/include/rcc/MIR/MIParser.h
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_MIR_MIPARSER_H
+#define RCC_MIR_MIPARSER_H
+
+#include "rcc/CodeGen/MachineIRTypes.h"
+#include "rcc/CodeGen/MachineMetadata.h"
+#include "rcc/Support/Error.h"
+#include "rcc/Support/TextDiagnostic.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <span>
+#include <string>
+#include <vector>
+
+namespace rcc {
+
+class MachineFunction;
+class TargetDescription;
+
+namespace mir {
+
+struct MIFrameObjectSlot final {
+ std::uint32_t TextID = 0;
+ FrameIndex Index;
+ std::optional<std::string> Name;
+};
+
+struct MIConstantPoolSlot final {
+ std::uint32_t TextID = 0;
+ ConstantPoolIndex Index;
+};
+
+struct MIJumpTableSlot final {
+ std::uint32_t TextID = 0;
+ JumpTableIndex Index;
+};
+
+struct MIMetadataSlot final {
+ std::uint32_t TextID = 0;
+ MachineMetadataReference Reference;
+};
+
+struct MISyncScopeSlot final {
+ std::string Name;
+ SyncScopeID ID;
+};
+
+struct MIParserContext final {
+ std::vector<MIFrameObjectSlot> StackObjects;
+ std::vector<MIFrameObjectSlot> FixedStackObjects;
+ std::vector<MIConstantPoolSlot> ConstantPoolItems;
+ std::vector<MIJumpTableSlot> JumpTables;
+ std::vector<MIMetadataSlot> Metadata;
+ std::vector<MISyncScopeSlot> SyncScopes;
+ std::uint32_t DefaultPointerSizeInBits = 0;
+};
+
+struct MIParserOptions final {
+ std::size_t MaximumTokens = std::size_t{1} << 24U;
+ std::size_t MaximumTokenLength = std::size_t{1} << 24U;
+ std::size_t MaximumBlocks = std::size_t{1} << 20U;
+ std::size_t MaximumInstructions = std::size_t{1} << 24U;
+ std::size_t MaximumOperandsPerInstruction = std::size_t{1} << 20U;
+ std::size_t MaximumMemoryOperandsPerInstruction = std::size_t{1} << 20U;
+};
+
+class MIParser final {
+public:
+ MIParser(MachineFunction &Function, const TargetDescription &Target, std::string SourceName,
+ std::string SourceText, MIParserContext Context = {}, MIParserOptions Options = {});
+ MIParser(const MIParser &) = delete;
+ MIParser &operator=(const MIParser &) = delete;
+ MIParser(MIParser &&) noexcept;
+ MIParser &operator=(MIParser &&) noexcept;
+ ~MIParser();
+
+ [[nodiscard]] Expected<void> parse();
+
+ [[nodiscard]] const TextSource &source() const noexcept;
+ [[nodiscard]] std::span<const TextDiagnostic> diagnostics() const noexcept;
+ [[nodiscard]] bool failed() const noexcept;
+
+private:
+ class Impl;
+ std::unique_ptr<Impl> Implementation;
+};
+
+} // namespace mir
+} // namespace rcc
+
+#endif // RCC_MIR_MIPARSER_H
diff --git a/backend/include/rcc/MIR/MIPrinter.h b/backend/include/rcc/MIR/MIPrinter.h
new file mode 100644
index 0000000..663859e
--- /dev/null
+++ b/backend/include/rcc/MIR/MIPrinter.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_MIR_MIPRINTER_H
+#define RCC_MIR_MIPRINTER_H
+
+#include "rcc/MIR/MIParser.h"
+#include "rcc/Support/Error.h"
+
+#include <string>
+
+namespace rcc {
+
+class MachineFunction;
+class TargetDescription;
+
+namespace mir {
+
+enum class MIPrintMode : unsigned char {
+ Complete,
+ Readable,
+};
+
+struct MIPrinterOptions final {
+ MIPrintMode Mode = MIPrintMode::Complete;
+};
+
+[[nodiscard]] Expected<std::string> printMachineFunctionBody(const MachineFunction &Function,
+ const TargetDescription &Target,
+ const MIParserContext &Context = {},
+ MIPrinterOptions Options = {});
+
+} // namespace mir
+} // namespace rcc
+
+#endif // RCC_MIR_MIPRINTER_H