aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/MIR/MIRDocumentParser.h
blob: 4d1d1eab39388d35a848f8d6007cf02b8a0e595d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-License-Identifier: GPL-3.0-or-later

// NOLINTNEXTLINE(llvm-header-guard)
#ifndef RCC_LIB_MIR_MIRDOCUMENTPARSER_H
#define RCC_LIB_MIR_MIRDOCUMENTPARSER_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/MIR/MIRDocument.h"

#include <cstdint>
#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;
};

} // namespace mir
} // namespace rcc

#endif // RCC_LIB_MIR_MIRDOCUMENTPARSER_H