diff options
Diffstat (limited to 'backend/include/rcc/MIR')
| -rw-r--r-- | backend/include/rcc/MIR/EmbeddedIR.h | 39 | ||||
| -rw-r--r-- | backend/include/rcc/MIR/LLVMConstantSyntax.h | 52 | ||||
| -rw-r--r-- | backend/include/rcc/MIR/MIDebugSyntax.h | 17 | ||||
| -rw-r--r-- | backend/include/rcc/MIR/MIParser.h | 12 | ||||
| -rw-r--r-- | backend/include/rcc/MIR/MIRDocument.h | 143 |
5 files changed, 260 insertions, 3 deletions
diff --git a/backend/include/rcc/MIR/EmbeddedIR.h b/backend/include/rcc/MIR/EmbeddedIR.h index 8e9e0f6..50567de 100644 --- a/backend/include/rcc/MIR/EmbeddedIR.h +++ b/backend/include/rcc/MIR/EmbeddedIR.h @@ -24,6 +24,20 @@ struct EmbeddedIRReference final { TextRange Range; }; +struct EmbeddedIRMetadataDefinition final { + std::string Name; + TextRange Range; + std::string DynamicType; +}; + +struct EmbeddedIRTypeDefinition final { + std::string Name; + TextRange Range; + std::string Definition; + TextRange DefinitionRange; + bool NumericName = false; +}; + class EmbeddedIRFunction final { public: [[nodiscard]] std::string_view name() const noexcept { @@ -46,8 +60,13 @@ public: return Allocas; } + [[nodiscard]] std::span<const EmbeddedIRReference> values() const noexcept { + return Values; + } + [[nodiscard]] const EmbeddedIRReference *block(std::string_view QueryName) const noexcept; [[nodiscard]] const EmbeddedIRReference *alloca(std::string_view QueryName) const noexcept; + [[nodiscard]] const EmbeddedIRReference *value(std::string_view QueryName) const noexcept; private: struct StringHash final { @@ -63,8 +82,10 @@ private: bool IsDefinition = false; std::vector<EmbeddedIRReference> Blocks; std::vector<EmbeddedIRReference> Allocas; + std::vector<EmbeddedIRReference> Values; std::unordered_map<std::string, std::size_t, StringHash, std::equal_to<>> BlockNameToIndex; std::unordered_map<std::string, std::size_t, StringHash, std::equal_to<>> AllocaNameToIndex; + std::unordered_map<std::string, std::size_t, StringHash, std::equal_to<>> ValueNameToIndex; friend class EmbeddedIRIndexer; }; @@ -101,13 +122,19 @@ public: return GlobalObjects; } - [[nodiscard]] std::span<const EmbeddedIRReference> metadataDefinitions() const noexcept { + [[nodiscard]] std::span<const EmbeddedIRMetadataDefinition> + metadataDefinitions() const noexcept { return MetadataDefinitions; } + [[nodiscard]] std::span<const EmbeddedIRTypeDefinition> typeDefinitions() const noexcept { + return TypeDefinitions; + } + [[nodiscard]] const EmbeddedIRFunction *function(std::string_view Name) const noexcept; [[nodiscard]] const EmbeddedIRReference *globalObject(std::string_view Name) const noexcept; - [[nodiscard]] const EmbeddedIRReference *metadata(std::string_view Name) const noexcept; + [[nodiscard]] const EmbeddedIRMetadataDefinition *metadata(std::string_view Name) const noexcept; + [[nodiscard]] const EmbeddedIRTypeDefinition *typeDefinition(std::string_view Name) const noexcept; [[nodiscard]] bool hasGlobalValue(std::string_view Name) const noexcept { return function(Name) != nullptr || globalObject(Name) != nullptr; } @@ -131,10 +158,12 @@ private: std::optional<TextRange> DataLayoutRange; std::vector<EmbeddedIRFunction> Functions; std::vector<EmbeddedIRReference> GlobalObjects; - std::vector<EmbeddedIRReference> MetadataDefinitions; + std::vector<EmbeddedIRMetadataDefinition> MetadataDefinitions; + std::vector<EmbeddedIRTypeDefinition> TypeDefinitions; std::unordered_map<std::string, std::size_t, StringHash, std::equal_to<>> FunctionNameToIndex; std::unordered_map<std::string, std::size_t, StringHash, std::equal_to<>> GlobalNameToIndex; std::unordered_map<std::string, std::size_t, StringHash, std::equal_to<>> MetadataNameToIndex; + std::unordered_map<std::string, std::size_t, StringHash, std::equal_to<>> TypeNameToIndex; friend class EmbeddedIRIndexer; }; @@ -159,6 +188,10 @@ public: return Diagnostics; } + [[nodiscard]] std::optional<EmbeddedIRReferenceIndex> takeIndex() && { + return std::move(Index); + } + private: EmbeddedIRIndexResult() = default; diff --git a/backend/include/rcc/MIR/LLVMConstantSyntax.h b/backend/include/rcc/MIR/LLVMConstantSyntax.h new file mode 100644 index 0000000..9d7a7d4 --- /dev/null +++ b/backend/include/rcc/MIR/LLVMConstantSyntax.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_MIR_LLVMCONSTANTSYNTAX_H +#define RCC_MIR_LLVMCONSTANTSYNTAX_H + +#include "rcc/CodeGen/GenericConstant.h" +#include "rcc/Support/Error.h" + +#include <cstddef> +#include <cstdint> +#include <span> +#include <string> +#include <string_view> + +namespace rcc::mir { + +struct LLVMNamedTypeDefinition final { + std::string_view Name; + std::string_view Definition; + bool NumericName = false; +}; + +struct LLVMConstantSyntaxOptions final { + std::uint32_t DefaultPointerSizeInBits = 0; + std::string_view DataLayout; + std::span<const LLVMNamedTypeDefinition> NamedTypes; + std::size_t MaximumDepth = 1024; + std::size_t MaximumNodes = std::size_t{1} << 24U; + std::size_t MaximumTokenLength = std::size_t{1} << 24U; +}; + +[[nodiscard]] Expected<GenericConstantData> +parseLLVMConstant(std::string_view Text, LLVMConstantSyntaxOptions Options = {}); + +[[nodiscard]] Expected<GenericConstantType> parseLLVMType(std::string_view Text, + LLVMConstantSyntaxOptions Options = {}); + +[[nodiscard]] Expected<std::string> printLLVMConstant(const GenericConstantData &Constant); + +[[nodiscard]] Expected<std::uint64_t> +llvmConstantStorageSize(const GenericConstantType &Type, LLVMConstantSyntaxOptions Options = {}); + +[[nodiscard]] Expected<Alignment> +llvmConstantPreferredAlignment(const GenericConstantType &Type, + LLVMConstantSyntaxOptions Options = {}); + +[[nodiscard]] Expected<std::uint32_t> llvmPointerSizeInBits(std::uint32_t AddressSpace, + LLVMConstantSyntaxOptions Options = {}); + +} // namespace rcc::mir + +#endif // RCC_MIR_LLVMCONSTANTSYNTAX_H diff --git a/backend/include/rcc/MIR/MIDebugSyntax.h b/backend/include/rcc/MIR/MIDebugSyntax.h new file mode 100644 index 0000000..a8427dc --- /dev/null +++ b/backend/include/rcc/MIR/MIDebugSyntax.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_MIR_MIDEBUGSYNTAX_H +#define RCC_MIR_MIDEBUGSYNTAX_H + +#include <cstdint> +#include <optional> +#include <string_view> + +namespace rcc::mir { + +[[nodiscard]] std::optional<std::uint64_t> +parseDIExpressionOpcodeName(std::string_view Name) noexcept; + +} // namespace rcc::mir + +#endif // RCC_MIR_MIDEBUGSYNTAX_H diff --git a/backend/include/rcc/MIR/MIParser.h b/backend/include/rcc/MIR/MIParser.h index 978e928..116a97f 100644 --- a/backend/include/rcc/MIR/MIParser.h +++ b/backend/include/rcc/MIR/MIParser.h @@ -5,15 +5,18 @@ #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 { @@ -23,6 +26,11 @@ class TargetDescription; namespace mir { +struct MIVirtualRegisterSlot final { + std::uint32_t TextID = 0; + Register Reg; +}; + struct MIFrameObjectSlot final { std::uint32_t TextID = 0; FrameIndex Index; @@ -50,12 +58,15 @@ struct MISyncScopeSlot final { }; 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<Expected<SyncScopeID>(std::string_view)> InternSyncScope; + std::function<Expected<std::uint32_t>(std::uint32_t)> PointerSizeInBits; std::uint32_t DefaultPointerSizeInBits = 0; }; @@ -66,6 +77,7 @@ struct MIParserOptions final { 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 { diff --git a/backend/include/rcc/MIR/MIRDocument.h b/backend/include/rcc/MIR/MIRDocument.h new file mode 100644 index 0000000..7980ca1 --- /dev/null +++ b/backend/include/rcc/MIR/MIRDocument.h @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_MIR_MIRDOCUMENT_H +#define RCC_MIR_MIRDOCUMENT_H + +#include "rcc/CodeGen/CompilationUnit.h" +#include "rcc/CodeGen/StableID.h" +#include "rcc/MIR/EmbeddedIR.h" +#include "rcc/MIR/MIParser.h" +#include "rcc/MIR/MIPrinter.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; + std::uint32_t DefaultPointerSizeInBits = 0; + 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 = {}); + +struct MIRDocumentPrinterOptions final { + MIPrintMode Mode = MIPrintMode::Complete; + bool EmitEmbeddedIR = true; + std::string DataLayout; + std::uint32_t DefaultPointerSizeInBits = 0; +}; + +[[nodiscard]] Expected<std::string> printMIRDocument(const MIRDocument &Document, + const TargetDescription &Target, + MIRDocumentPrinterOptions Options = {}); + +} // namespace mir +} // namespace rcc + +#endif // RCC_MIR_MIRDOCUMENT_H |
