aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/TargetMIRTextInfo.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-07 01:27:41 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-07 01:27:41 +0800
commit76d89700953ddd81cf31ab8f260eddf67e93aa85 (patch)
treec96a453164154b2d1559cea36910df52103f0f19 /backend/lib/CodeGen/TargetMIRTextInfo.cpp
parent183e2354e9fdd107be420cbb185c1d239434aa48 (diff)
downloadrcc-project-76d89700953ddd81cf31ab8f260eddf67e93aa85.tar.gz
rcc-project-76d89700953ddd81cf31ab8f260eddf67e93aa85.tar.xz
[MIR] Complete document parsing and printing
Implement the single LLVM-compatible MIR document path with structured\nembedded-IR references, YAML mappings, constants, and deterministic printing.\n\nKeep pointer LLT widths DataLayout-derived, reject layout-dependent output\nwhen embedded IR is omitted, and record the fixed-baseline compatibility\ncontract and regression coverage.
Diffstat (limited to 'backend/lib/CodeGen/TargetMIRTextInfo.cpp')
-rw-r--r--backend/lib/CodeGen/TargetMIRTextInfo.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/backend/lib/CodeGen/TargetMIRTextInfo.cpp b/backend/lib/CodeGen/TargetMIRTextInfo.cpp
index a349432..65e3c65 100644
--- a/backend/lib/CodeGen/TargetMIRTextInfo.cpp
+++ b/backend/lib/CodeGen/TargetMIRTextInfo.cpp
@@ -8,6 +8,7 @@
#include <cstddef>
#include <cstdint>
#include <string>
+#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -51,6 +52,89 @@ namespace {
} // namespace
+MIRTargetNode::MIRTargetNode() = default;
+MIRTargetNode::MIRTargetNode(const MIRTargetNode &) = default;
+MIRTargetNode &MIRTargetNode::operator=(const MIRTargetNode &) = default;
+MIRTargetNode::MIRTargetNode(MIRTargetNode &&) noexcept = default;
+MIRTargetNode &MIRTargetNode::operator=(MIRTargetNode &&) noexcept = default;
+MIRTargetNode::~MIRTargetNode() = default;
+
+MIRTargetNode MIRTargetNode::null() {
+ return {};
+}
+
+MIRTargetNode MIRTargetNode::scalar(std::string Value) {
+ MIRTargetNode Result;
+ Result.Kind = MIRTargetNodeKind::Scalar;
+ Result.Scalar = std::move(Value);
+ return Result;
+}
+
+MIRTargetNode MIRTargetNode::sequence(std::vector<MIRTargetNode> Values) {
+ MIRTargetNode Result;
+ Result.Kind = MIRTargetNodeKind::Sequence;
+ Result.Sequence = std::move(Values);
+ return Result;
+}
+
+MIRTargetNode MIRTargetNode::mapping(std::vector<MIRTargetMappingEntry> Entries) {
+ MIRTargetNode Result;
+ Result.Kind = MIRTargetNodeKind::Mapping;
+ Result.Mapping = std::move(Entries);
+ return Result;
+}
+
+bool operator==(const MIRTargetNode &Left, const MIRTargetNode &Right) {
+ return Left.Kind == Right.Kind && Left.Scalar == Right.Scalar &&
+ Left.Sequence == Right.Sequence && Left.Mapping == Right.Mapping;
+}
+
+const MIRTargetNode *MIRTargetNode::mappingValue(std::string_view Key) const noexcept {
+ if (Kind != MIRTargetNodeKind::Mapping)
+ return nullptr;
+ for (const MIRTargetMappingEntry &Entry : Mapping) {
+ if (Entry.Key == Key)
+ return &Entry.Value;
+ }
+ return nullptr;
+}
+
+Expected<void> MIRTargetNode::verify() const {
+ if (Kind >= MIRTargetNodeKind::Count)
+ return makeUnexpected(ErrorCode::InvalidArgument, "target MIR node kind is invalid");
+
+ const bool HasScalar = !Scalar.empty();
+ const bool HasSequence = !Sequence.empty();
+ const bool HasMapping = !Mapping.empty();
+ if ((Kind != MIRTargetNodeKind::Scalar && HasScalar) ||
+ (Kind != MIRTargetNodeKind::Sequence && HasSequence) ||
+ (Kind != MIRTargetNodeKind::Mapping && HasMapping)) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "target MIR node contains storage for a different node kind");
+ }
+
+ if (Kind == MIRTargetNodeKind::Sequence) {
+ for (const MIRTargetNode &Element : Sequence) {
+ auto ElementResult = Element.verify();
+ if (!ElementResult)
+ return ElementResult;
+ }
+ }
+ if (Kind == MIRTargetNodeKind::Mapping) {
+ std::unordered_set<std::string_view> Keys;
+ for (const MIRTargetMappingEntry &Entry : Mapping) {
+ if (Entry.Key.empty() || !Keys.insert(Entry.Key).second) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "target MIR mapping keys must be nonempty and unique");
+ }
+ auto ValueResult = Entry.Value.verify();
+ if (!ValueResult)
+ return ValueResult;
+ }
+ }
+ return {};
+}
+
Expected<TargetMIRTextInfo> TargetMIRTextInfo::create(TargetMIRTextInfoDesc Description,
const TargetRegisterInfo &Registers) {
TargetMIRTextInfo Result(std::move(Description));
@@ -192,6 +276,18 @@ Expected<TargetMIRTextInfo> TargetMIRTextInfo::create(TargetMIRTextInfoDesc Desc
if (Result.Description.FunctionStateType && Result.Description.FunctionStateType->value() == 0) {
return invalidDescription("target function state TypeID must be nonzero");
}
+ const bool HasStateType = Result.Description.FunctionStateType.has_value();
+ const bool HasParser = Result.Description.ParseFunctionState != nullptr;
+ const bool HasPrinter = Result.Description.PrintFunctionState != nullptr;
+ if (HasStateType != HasParser || HasStateType != HasPrinter) {
+ return invalidDescription(
+ "target function state TypeID, parser, and printer must be provided together");
+ }
+ const bool HasConstantParser = Result.Description.ParseTargetConstant != nullptr;
+ const bool HasConstantPrinter = Result.Description.PrintTargetConstant != nullptr;
+ if (HasConstantParser != HasConstantPrinter) {
+ return invalidDescription("target constant parser and printer must be provided together");
+ }
return Result;
}
@@ -365,4 +461,86 @@ TargetMIRTextInfo::physicalRegister(std::uint32_t DwarfRegister) const noexcept
return Position->second;
}
+Expected<TargetFunctionState>
+TargetMIRTextInfo::parseFunctionState(const MIRTargetNode &Node) const {
+ if (Description.ParseFunctionState == nullptr || !Description.FunctionStateType) {
+ return makeUnexpected(ErrorCode::Unsupported,
+ "target does not define a machineFunctionInfo MIR schema");
+ }
+ auto NodeResult = Node.verify();
+ if (!NodeResult)
+ return std::unexpected(NodeResult.error());
+ auto State = Description.ParseFunctionState(Node);
+ if (!State)
+ return std::unexpected(State.error());
+ auto StateResult = State->verify();
+ if (!StateResult)
+ return std::unexpected(StateResult.error());
+ if (State->typeID() != Description.FunctionStateType) {
+ return makeUnexpected(ErrorCode::ParseError,
+ "parsed target function state has the wrong schema TypeID");
+ }
+ return State;
+}
+
+Expected<MIRTargetNode>
+TargetMIRTextInfo::printFunctionState(const TargetFunctionState &State) const {
+ if (Description.PrintFunctionState == nullptr || !Description.FunctionStateType) {
+ return makeUnexpected(ErrorCode::Unsupported,
+ "target does not define a machineFunctionInfo MIR schema");
+ }
+ auto StateResult = State.verify();
+ if (!StateResult)
+ return std::unexpected(StateResult.error());
+ if (State.typeID() != Description.FunctionStateType) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "target function state has the wrong MIR schema TypeID");
+ }
+ auto Node = Description.PrintFunctionState(State);
+ if (!Node)
+ return std::unexpected(Node.error());
+ auto NodeResult = Node->verify();
+ if (!NodeResult)
+ return std::unexpected(NodeResult.error());
+ if (Node->Kind != MIRTargetNodeKind::Mapping) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machineFunctionInfo printer must produce a mapping");
+ }
+ return Node;
+}
+
+Expected<TargetConstant>
+TargetMIRTextInfo::parseTargetConstant(std::string_view Text) const {
+ if (Description.ParseTargetConstant == nullptr) {
+ return makeUnexpected(ErrorCode::Unsupported,
+ "target does not define a target constant MIR schema");
+ }
+ auto Constant = Description.ParseTargetConstant(Text);
+ if (!Constant)
+ return std::unexpected(Constant.error());
+ auto Verification = Constant->verify();
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ return Constant;
+}
+
+Expected<std::string>
+TargetMIRTextInfo::printTargetConstant(const TargetConstant &Constant) const {
+ if (Description.PrintTargetConstant == nullptr) {
+ return makeUnexpected(ErrorCode::Unsupported,
+ "target does not define a target constant MIR schema");
+ }
+ auto Verification = Constant.verify();
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ auto Text = Description.PrintTargetConstant(Constant);
+ if (!Text)
+ return std::unexpected(Text.error());
+ if (Text->empty()) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "target constant printer produced an empty MIR value");
+ }
+ return Text;
+}
+
} // namespace rcc