aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include/rcc/CodeGen')
-rw-r--r--backend/include/rcc/CodeGen/MIRParser/MIParser.h107
-rw-r--r--backend/include/rcc/CodeGen/MIRParser/MIRParser.h130
-rw-r--r--backend/include/rcc/CodeGen/MIRPrinter.h45
-rw-r--r--backend/include/rcc/CodeGen/MIRYamlMapping.h144
4 files changed, 426 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/MIRParser/MIParser.h b/backend/include/rcc/CodeGen/MIRParser/MIParser.h
new file mode 100644
index 0000000..0b888e5
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MIRParser/MIParser.h
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MIRPARSER_MIPARSER_H
+#define RCC_CODEGEN_MIRPARSER_MIPARSER_H
+
+#include "rcc/CodeGen/MachineIRTypes.h"
+#include "rcc/CodeGen/MachineMetadata.h"
+#include "rcc/CodeGen/Register.h"
+#include "rcc/Support/Error.h"
+#include "rcc/Support/TextDiagnostic.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <optional>
+#include <span>
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace rcc {
+
+class MachineFunction;
+class TargetDescription;
+
+namespace mir {
+
+struct MIVirtualRegisterSlot final {
+ std::uint32_t TextID = 0;
+ Register Reg;
+};
+
+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<MIVirtualRegisterSlot> VirtualRegisters;
+ 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::function<bool(std::string_view)> HasIRBlock;
+ std::function<Expected<SyncScopeID>(std::string_view)> InternSyncScope;
+ std::function<Expected<std::uint32_t>(std::uint32_t)> PointerSizeInBits;
+};
+
+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;
+ bool VerifyAfterParse = true;
+};
+
+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_CODEGEN_MIRPARSER_MIPARSER_H
diff --git a/backend/include/rcc/CodeGen/MIRParser/MIRParser.h b/backend/include/rcc/CodeGen/MIRParser/MIRParser.h
new file mode 100644
index 0000000..798a747
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MIRParser/MIRParser.h
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MIRPARSER_MIRPARSER_H
+#define RCC_CODEGEN_MIRPARSER_MIRPARSER_H
+
+#include "rcc/CodeGen/CompilationUnit.h"
+#include "rcc/CodeGen/MIRParser/MIParser.h"
+#include "rcc/CodeGen/StableID.h"
+#include "rcc/MIR/EmbeddedIR.h"
+#include "rcc/Support/TextDiagnostic.h"
+#include "rcc/Support/YAML.h"
+
+#include <cstdint>
+#include <optional>
+#include <span>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace rcc {
+
+class TargetDescription;
+
+namespace mir {
+
+struct MIRFunctionDocumentInfo final {
+ MachineFunctionStableID Function;
+ std::optional<bool> NoPHIs;
+ std::optional<bool> IsSSA;
+ std::optional<bool> NoVRegs;
+ std::optional<bool> HasFakeUses;
+
+ friend bool operator==(const MIRFunctionDocumentInfo &Left,
+ const MIRFunctionDocumentInfo &Right) = default;
+};
+
+class MIRDocument final {
+public:
+ MIRDocument();
+ explicit MIRDocument(CompilationUnit Unit);
+ MIRDocument(const MIRDocument &) = delete;
+ MIRDocument &operator=(const MIRDocument &) = delete;
+ MIRDocument(MIRDocument &&) noexcept;
+ MIRDocument &operator=(MIRDocument &&) noexcept;
+ ~MIRDocument();
+
+ [[nodiscard]] CompilationUnit &unit() noexcept {
+ return Unit;
+ }
+
+ [[nodiscard]] const CompilationUnit &unit() const noexcept {
+ return Unit;
+ }
+
+ [[nodiscard]] const EmbeddedIRReferenceIndex *embeddedIR() const noexcept {
+ return EmbeddedIR ? &*EmbeddedIR : nullptr;
+ }
+
+ [[nodiscard]] std::span<const MIRFunctionDocumentInfo> functionDocumentInfo() const noexcept {
+ return FunctionInfo;
+ }
+
+ [[nodiscard]] std::span<const MISyncScopeSlot> syncScopes() const noexcept {
+ return SyncScopes;
+ }
+
+private:
+ CompilationUnit Unit;
+ std::optional<EmbeddedIRReferenceIndex> EmbeddedIR;
+ std::vector<MIRFunctionDocumentInfo> FunctionInfo;
+ std::vector<MISyncScopeSlot> SyncScopes;
+
+ friend class MIRDocumentParser;
+};
+
+struct MIRDocumentParserOptions final {
+ yaml::ParseOptions YAML;
+ MIParserOptions MachineInstructions;
+ std::string DataLayout;
+ bool VerifyMachineFunctions = true;
+};
+
+class MIRDocumentParseResult final {
+public:
+ MIRDocumentParseResult(const MIRDocumentParseResult &) = delete;
+ MIRDocumentParseResult &operator=(const MIRDocumentParseResult &) = delete;
+ MIRDocumentParseResult(MIRDocumentParseResult &&) noexcept;
+ MIRDocumentParseResult &operator=(MIRDocumentParseResult &&) noexcept;
+ ~MIRDocumentParseResult();
+
+ [[nodiscard]] bool succeeded() const noexcept {
+ return Document.has_value() && Diagnostics.empty();
+ }
+
+ [[nodiscard]] MIRDocument *document() noexcept {
+ return Document ? &*Document : nullptr;
+ }
+
+ [[nodiscard]] const MIRDocument *document() const noexcept {
+ return Document ? &*Document : nullptr;
+ }
+
+ [[nodiscard]] const TextSource &source() const noexcept {
+ return Source;
+ }
+
+ [[nodiscard]] std::span<const TextDiagnostic> diagnostics() const noexcept {
+ return Diagnostics;
+ }
+
+private:
+ MIRDocumentParseResult(std::string SourceName, std::string SourceText)
+ : Source(std::move(SourceName), std::move(SourceText)) {}
+
+ TextSource Source;
+ std::optional<MIRDocument> Document;
+ std::vector<TextDiagnostic> Diagnostics;
+
+ friend class MIRDocumentParser;
+};
+
+[[nodiscard]] MIRDocumentParseResult parseMIRDocument(const TargetDescription &Target,
+ std::string SourceName,
+ std::string SourceText,
+ MIRDocumentParserOptions Options = {});
+
+} // namespace mir
+} // namespace rcc
+
+#endif // RCC_CODEGEN_MIRPARSER_MIRPARSER_H
diff --git a/backend/include/rcc/CodeGen/MIRPrinter.h b/backend/include/rcc/CodeGen/MIRPrinter.h
new file mode 100644
index 0000000..bb87509
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MIRPrinter.h
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MIRPRINTER_H
+#define RCC_CODEGEN_MIRPRINTER_H
+
+#include "rcc/CodeGen/MIRParser/MIRParser.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 = {});
+
+struct MIRDocumentPrinterOptions final {
+ MIPrintMode Mode = MIPrintMode::Complete;
+ bool EmitEmbeddedIR = true;
+ std::string DataLayout;
+};
+
+[[nodiscard]] Expected<std::string> printMIRDocument(const MIRDocument &Document,
+ const TargetDescription &Target,
+ MIRDocumentPrinterOptions Options = {});
+
+} // namespace mir
+} // namespace rcc
+
+#endif // RCC_CODEGEN_MIRPRINTER_H
diff --git a/backend/include/rcc/CodeGen/MIRYamlMapping.h b/backend/include/rcc/CodeGen/MIRYamlMapping.h
new file mode 100644
index 0000000..82880ca
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MIRYamlMapping.h
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MIRYAMLMAPPING_H
+#define RCC_CODEGEN_MIRYAMLMAPPING_H
+
+#include "rcc/CodeGen/MIRParser/MIRParser.h"
+#include "rcc/CodeGen/MachineDebugInfo.h"
+#include "rcc/CodeGen/MachineFrameInfo.h"
+#include "rcc/CodeGen/MachineJumpTableInfo.h"
+#include "rcc/CodeGen/MachineMetadata.h"
+#include "rcc/CodeGen/TargetMIRTextInfo.h"
+#include "rcc/MIR/LLVMConstantSyntax.h"
+#include "rcc/Support/Error.h"
+
+#include <cstdint>
+#include <optional>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+namespace rcc {
+
+class MachineBasicBlock;
+class MachineFunction;
+class MachineInstr;
+
+namespace mir {
+
+struct PendingJumpTable final {
+ JumpTableIndex Index;
+ std::uint32_t TextID = 0;
+ JumpTableEntryEncoding Encoding = JumpTableEntryEncoding::BlockAddress;
+ std::uint8_t EntrySize = 8;
+ std::vector<std::string> Blocks;
+};
+
+class MIRDocumentParser final {
+public:
+ MIRDocumentParser(const TargetDescription &Target, std::string SourceName, std::string SourceText,
+ MIRDocumentParserOptions Options)
+ : Target(Target), Options(std::move(Options)),
+ Result(std::move(SourceName), std::move(SourceText)) {}
+
+ [[nodiscard]] MIRDocumentParseResult run();
+
+private:
+ [[nodiscard]] bool fail(const TextRange &Range, std::string Message,
+ std::string Category = "mir-yaml");
+ [[nodiscard]] bool importError(const TextRange &Range, const Error &Failure,
+ std::string Category = "mir-yaml");
+ [[nodiscard]] const yaml::Node *node(yaml::NodeID ID) const noexcept {
+ return Stream->node(ID);
+ }
+ [[nodiscard]] const yaml::Node *mappingValue(const yaml::Node &Mapping,
+ std::string_view Key) const noexcept;
+ [[nodiscard]] bool requireKind(const yaml::Node &Node, yaml::NodeKind Kind,
+ std::string_view Description);
+ [[nodiscard]] bool validateKeys(const yaml::Node &Mapping, std::span<const std::string_view> Keys,
+ std::string_view Description);
+ [[nodiscard]] bool scalar(const yaml::Node &Node, std::string_view &Value,
+ std::string_view Description);
+ [[nodiscard]] bool boolean(const yaml::Node &Node, bool &Value);
+ [[nodiscard]] bool unsignedValue(const yaml::Node &Node, std::uint64_t &Value,
+ std::string_view Description);
+ [[nodiscard]] bool signedValue(const yaml::Node &Node, std::int64_t &Value,
+ std::string_view Description);
+ [[nodiscard]] bool alignment(const yaml::Node &Node, Alignment &Value, bool AllowZero);
+ [[nodiscard]] bool physicalRegister(const yaml::Node &Node, PhysicalRegister &Reg);
+ [[nodiscard]] bool physicalRegister(std::string_view Text, const TextRange &Range,
+ PhysicalRegister &Reg);
+ [[nodiscard]] bool virtualRegister(std::string_view Text, const TextRange &Range,
+ MachineFunction &Function, MIParserContext &Context,
+ Register &Reg);
+ [[nodiscard]] Expected<MachineMetadataReference>
+ resolveMetadataReference(const MachineFunction &Function, std::uint32_t Slot) const;
+ [[nodiscard]] bool parseVariableDebugInfo(const yaml::Node &Entry, MachineFunction &Function,
+ MachineVariableDebugInfo &DebugInfo);
+ [[nodiscard]] bool parseFunction(const yaml::Node &Root, MIRDocument &Document);
+ [[nodiscard]] bool parseFunctionScalars(const yaml::Node &Root, MachineFunction &Function,
+ MIRFunctionDocumentInfo &DocumentInfo);
+ [[nodiscard]] bool recomputeProperties(const yaml::Node &Root, MachineFunction &Function,
+ const MIRFunctionDocumentInfo &DocumentInfo);
+ [[nodiscard]] bool parseRegisters(const yaml::Node &Root, MachineFunction &Function,
+ MIParserContext &Context);
+ [[nodiscard]] bool parseMetadata(const yaml::Node &Root, MachineFunction &Function,
+ MIParserContext &Context);
+ [[nodiscard]] bool parseStackObjects(const yaml::Node &Root, MachineFunction &Function,
+ MIParserContext &Context);
+ [[nodiscard]] bool parseConstants(const yaml::Node &Root, MachineFunction &Function,
+ MIParserContext &Context);
+ [[nodiscard]] bool parseFrameState(const yaml::Node &Root, MachineFunction &Function,
+ const MIParserContext &Context);
+ [[nodiscard]] bool reserveJumpTables(const yaml::Node &Root, MachineFunction &Function,
+ MIParserContext &Context,
+ std::vector<PendingJumpTable> &Pending);
+ [[nodiscard]] bool defineJumpTables(MachineFunction &Function,
+ std::span<const PendingJumpTable> Pending);
+ [[nodiscard]] bool parseBody(const yaml::Node &Root, MachineFunction &Function,
+ MIParserContext &Context);
+ [[nodiscard]] TextRange scalarDiagnosticRange(const yaml::Node &Scalar,
+ const TextRange &ScalarRange) const noexcept;
+ [[nodiscard]] bool parseFunctionRecords(const yaml::Node &Root, MachineFunction &Function);
+ [[nodiscard]] bool parseTargetState(const yaml::Node &Root, MachineFunction &Function);
+ [[nodiscard]] bool convertTargetNode(const yaml::Node &Source, MIRTargetNode &Destination);
+ [[nodiscard]] bool validateDocumentReferences(const MachineFunction &Function);
+ [[nodiscard]] std::string_view effectiveDataLayout() const noexcept;
+ [[nodiscard]] LLVMConstantSyntaxOptions pointerLayoutOptions() const noexcept;
+
+ [[nodiscard]] MachineBasicBlock *blockAt(MachineFunction &Function,
+ std::uint32_t Number) const noexcept;
+ [[nodiscard]] MachineInstr *instructionAt(MachineFunction &Function, std::uint32_t Block,
+ std::uint32_t Offset) const noexcept;
+ [[nodiscard]] bool parseBlockReference(std::string_view Text, const TextRange &Range,
+ MachineFunction &Function, MachineBasicBlock *&Block);
+ [[nodiscard]] bool parseFrameReference(const yaml::Node &Node, const MIParserContext &Context,
+ FrameIndex &Index);
+ [[nodiscard]] bool parseSaveRestorePoints(const yaml::Node &Node, MachineFunction &Function,
+ std::vector<MachineFrameSaveRestorePoint> &Points);
+
+ const TargetDescription &Target;
+ MIRDocumentParserOptions Options;
+ MIRDocumentParseResult Result;
+ const yaml::Stream *Stream = nullptr;
+ MIRDocument *ActiveDocument = nullptr;
+ MachineFunction *ActiveFunction = nullptr;
+};
+
+[[nodiscard]] Expected<void> verifyMIRDocumentReferences(const MIRDocument &Document,
+ const MachineFunction &Function,
+ bool UseEmbeddedIR);
+
+[[nodiscard]] std::optional<std::uint64_t>
+parseDIExpressionOpcodeName(std::string_view Name) noexcept;
+[[nodiscard]] std::optional<std::uint64_t>
+parseDIExpressionAttributeEncodingName(std::string_view Name) noexcept;
+[[nodiscard]] std::string invalidDIExpressionElementMessage(std::string_view Name);
+[[nodiscard]] std::string formatDIExpression(std::span<const std::uint64_t> Elements);
+
+} // namespace mir
+} // namespace rcc
+
+#endif // RCC_CODEGEN_MIRYAMLMAPPING_H