From d62f022c92fcc3ebe2269273628943a0089683fd Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Thu, 13 Aug 2026 06:19:30 +0800 Subject: [CodeGen] Align MIR parser and printer ownership --- backend/lib/MIR/MIRFunctionRecordsParser.cpp | 341 --------------------------- 1 file changed, 341 deletions(-) delete mode 100644 backend/lib/MIR/MIRFunctionRecordsParser.cpp (limited to 'backend/lib/MIR/MIRFunctionRecordsParser.cpp') diff --git a/backend/lib/MIR/MIRFunctionRecordsParser.cpp b/backend/lib/MIR/MIRFunctionRecordsParser.cpp deleted file mode 100644 index 04857bb..0000000 --- a/backend/lib/MIR/MIRFunctionRecordsParser.cpp +++ /dev/null @@ -1,341 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "MIRDocumentParser.h" -#include "MIRDocumentReferenceValidation.h" -#include "MIRMetadataTextParser.h" -#include "MIRParserUtilities.h" -#include "rcc/CodeGen/MachineBasicBlock.h" -#include "rcc/CodeGen/MachineConstantPool.h" -#include "rcc/CodeGen/MachineFrameInfo.h" -#include "rcc/CodeGen/MachineFunction.h" -#include "rcc/CodeGen/MachineFunctionAttributes.h" -#include "rcc/CodeGen/MachineFunctionProperties.h" -#include "rcc/CodeGen/MachineFunctionRecords.h" -#include "rcc/CodeGen/MachineInstr.h" -#include "rcc/CodeGen/MachineJumpTableInfo.h" -#include "rcc/CodeGen/MachineMetadata.h" -#include "rcc/CodeGen/MachineRegisterInfo.h" -#include "rcc/CodeGen/MachineVerifier.h" -#include "rcc/CodeGen/TargetDescription.h" -#include "rcc/CodeGen/TargetMIRTextInfo.h" -#include "rcc/CodeGen/TargetRegisterInfo.h" -#include "rcc/MIR/LLVMConstantSyntax.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace rcc::mir { - -using parser_detail::parseBool; -using parser_detail::parsePrefixedID; -using parser_detail::parseSigned; -using parser_detail::parseUnsigned; -using parser_detail::parseUnsigned32; -using parser_detail::trim; - -bool MIRDocumentParser::parseFunctionRecords(const yaml::Node &Root, MachineFunction &Function) { - auto ParseLocation = [this, &Function](const yaml::Node &Entry, - MachineInstr *&Instruction) -> bool { - const yaml::Node *BlockNode = mappingValue(Entry, "bb"); - const yaml::Node *OffsetNode = mappingValue(Entry, "offset"); - if (BlockNode == nullptr || OffsetNode == nullptr) - return fail(Entry.range(), "instruction location requires 'bb' and 'offset'"); - std::uint64_t Block = 0; - std::uint64_t Offset = 0; - if (unsignedValue(*BlockNode, Block, "a 32-bit basic block number") || - unsignedValue(*OffsetNode, Offset, "a 32-bit instruction offset") || - Block > std::numeric_limits::max() || - Offset > std::numeric_limits::max()) { - return true; - } - Instruction = instructionAt(Function, static_cast(Block), - static_cast(Offset)); - if (Instruction == nullptr) - return fail(Entry.range(), "instruction location is outside the machine function body"); - return false; - }; - - if (const yaml::Node *CallSites = mappingValue(Root, "callSites")) { - if (requireKind(*CallSites, yaml::NodeKind::Sequence, "call-site records")) - return true; - constexpr std::array CallSiteKeys{ - std::string_view{"bb"}, - std::string_view{"offset"}, - std::string_view{"fwdArgRegs"}, - std::string_view{"calleeTypeIds"}, - }; - constexpr std::array ArgumentKeys{ - std::string_view{"arg"}, - std::string_view{"reg"}, - }; - for (const yaml::NodeID CallSiteID : CallSites->sequence()) { - const yaml::Node *CallSiteNode = node(CallSiteID); - if (CallSiteNode == nullptr || - requireKind(*CallSiteNode, yaml::NodeKind::Mapping, "call-site record") || - validateKeys(*CallSiteNode, CallSiteKeys, "call-site record")) { - return true; - } - MachineInstr *Call = nullptr; - if (ParseLocation(*CallSiteNode, Call)) - return true; - if (Call == nullptr) - return fail(CallSiteNode->range(), - "instruction location is outside the machine function body"); - MachineCallSiteInfo Info{ - .CallInstruction = Call->stableID(), - .ForwardedArguments = {}, - .CalleeTypeIDs = {}, - }; - if (const yaml::Node *Arguments = mappingValue(*CallSiteNode, "fwdArgRegs")) { - if (requireKind(*Arguments, yaml::NodeKind::Sequence, "forwarded call arguments")) { - return true; - } - for (const yaml::NodeID ArgumentID : Arguments->sequence()) { - const yaml::Node *Argument = node(ArgumentID); - if (Argument == nullptr || - requireKind(*Argument, yaml::NodeKind::Mapping, "forwarded call argument") || - validateKeys(*Argument, ArgumentKeys, "forwarded call argument")) { - return true; - } - const yaml::Node *NumberNode = mappingValue(*Argument, "arg"); - const yaml::Node *RegNode = mappingValue(*Argument, "reg"); - if (NumberNode == nullptr || RegNode == nullptr) - return fail(Argument->range(), "forwarded call argument requires 'arg' and 'reg'"); - std::uint16_t Number = 0; - std::uint64_t WideNumber = 0; - PhysicalRegister Reg; - if (unsignedValue(*NumberNode, WideNumber, "a 16-bit argument number") || - WideNumber > std::numeric_limits::max() || - physicalRegister(*RegNode, Reg)) { - return true; - } - Number = static_cast(WideNumber); - Info.ForwardedArguments.push_back({Reg, Number}); - } - } - if (const yaml::Node *TypeIDs = mappingValue(*CallSiteNode, "calleeTypeIds")) { - if (requireKind(*TypeIDs, yaml::NodeKind::Sequence, "callee type IDs")) - return true; - for (const yaml::NodeID TypeID : TypeIDs->sequence()) { - const yaml::Node *TypeNode = node(TypeID); - std::uint64_t Value = 0; - if (TypeNode == nullptr || - unsignedValue(*TypeNode, Value, "an unsigned callee type ID")) { - return true; - } - Info.CalleeTypeIDs.push_back(Value); - } - } - auto AddResult = Function.records().addCallSite(std::move(Info)); - if (!AddResult) - return importError(CallSiteNode->range(), AddResult.error()); - } - } - - if (const yaml::Node *CalledGlobals = mappingValue(Root, "calledGlobals")) { - if (requireKind(*CalledGlobals, yaml::NodeKind::Sequence, "called-global records")) - return true; - constexpr std::array Keys{ - std::string_view{"bb"}, - std::string_view{"offset"}, - std::string_view{"callee"}, - std::string_view{"flags"}, - }; - for (const yaml::NodeID CalledID : CalledGlobals->sequence()) { - const yaml::Node *CalledNode = node(CalledID); - if (CalledNode == nullptr || - requireKind(*CalledNode, yaml::NodeKind::Mapping, "called-global record") || - validateKeys(*CalledNode, Keys, "called-global record")) { - return true; - } - MachineInstr *Call = nullptr; - if (ParseLocation(*CalledNode, Call)) - return true; - if (Call == nullptr) - return fail(CalledNode->range(), - "instruction location is outside the machine function body"); - const yaml::Node *CalleeNode = mappingValue(*CalledNode, "callee"); - const yaml::Node *FlagsNode = mappingValue(*CalledNode, "flags"); - if (CalleeNode == nullptr || FlagsNode == nullptr) - return fail(CalledNode->range(), "called-global record requires 'callee' and 'flags'"); - std::string_view Callee; - std::uint64_t WideFlags = 0; - if (scalar(*CalleeNode, Callee, "callee name") || - unsignedValue(*FlagsNode, WideFlags, "32-bit called-global flags") || - WideFlags > std::numeric_limits::max()) { - return true; - } - if (ActiveDocument->EmbeddedIR && !ActiveDocument->EmbeddedIR->hasGlobalValue(Callee)) { - return fail(CalleeNode->range(), "called global references an undefined embedded global"); - } - auto AddResult = - Function.records().addCalledGlobal({.CallInstruction = Call->stableID(), - .Callee = std::string(Callee), - .Flags = static_cast(WideFlags)}); - if (!AddResult) - return importError(CalledNode->range(), AddResult.error()); - } - } - - if (const yaml::Node *Substitutions = mappingValue(Root, "debugValueSubstitutions")) { - if (requireKind(*Substitutions, yaml::NodeKind::Sequence, "debug value substitutions")) { - return true; - } - constexpr std::array Keys{ - std::string_view{"srcinst"}, std::string_view{"srcop"}, std::string_view{"dstinst"}, - std::string_view{"dstop"}, std::string_view{"subreg"}, - }; - for (const yaml::NodeID SubstitutionID : Substitutions->sequence()) { - const yaml::Node *Substitution = node(SubstitutionID); - if (Substitution == nullptr || - requireKind(*Substitution, yaml::NodeKind::Mapping, "debug value substitution") || - validateKeys(*Substitution, Keys, "debug value substitution")) { - return true; - } - std::array Values{}; - for (std::size_t Index = 0; Index < Keys.size(); ++Index) { - const yaml::Node *ValueNode = mappingValue(*Substitution, Keys[Index]); - if (ValueNode == nullptr) - return fail(Substitution->range(), "debug value substitution requires every fixed field"); - std::uint64_t Wide = 0; - if (unsignedValue(*ValueNode, Wide, "a 32-bit debug substitution value") || - Wide > std::numeric_limits::max()) { - return true; - } - Values[Index] = static_cast(Wide); - } - auto AddResult = Function.records().addDebugValueSubstitution( - {.Source = {Values[0], Values[1]}, - .Destination = {Values[2], Values[3]}, - .Subregister = SubRegIndex::fromValue(Values[4])}); - if (!AddResult) - return importError(Substitution->range(), AddResult.error()); - } - } - - if (const yaml::Node *PrefetchTargets = mappingValue(Root, "prefetch-targets")) { - if (requireKind(*PrefetchTargets, yaml::NodeKind::Sequence, "prefetch targets")) - return true; - for (const yaml::NodeID TargetID : PrefetchTargets->sequence()) { - const yaml::Node *TargetNode = node(TargetID); - std::string_view Text; - if (TargetNode == nullptr || scalar(*TargetNode, Text, "prefetch target")) - return true; - - std::size_t ContentOffset = TargetNode->range().Begin.Offset; - if (TargetNode->scalarStyle() == yaml::ScalarStyle::SingleQuoted || - TargetNode->scalarStyle() == yaml::ScalarStyle::DoubleQuoted) { - ++ContentOffset; - } - const auto ErrorRange = [this, ContentOffset](std::size_t Begin, std::size_t End = 1U) { - return Result.Source.range(ContentOffset + Begin, ContentOffset + Begin + End); - }; - const auto SkipSpace = [&Text](std::size_t &Cursor) { - while (Cursor < Text.size() && (Text[Cursor] == ' ' || Text[Cursor] == '\t')) - ++Cursor; - }; - const auto ParseNumber = [&Text, &SkipSpace](std::size_t &Cursor, std::uint32_t &Value) { - SkipSpace(Cursor); - const std::size_t Begin = Cursor; - while (Cursor < Text.size() && Text[Cursor] >= '0' && Text[Cursor] <= '9') - ++Cursor; - return Begin != Cursor && parseUnsigned32(Text.substr(Begin, Cursor - Begin), Value); - }; - - std::size_t Cursor = 0; - SkipSpace(Cursor); - if (!Text.substr(Cursor).starts_with("bb_id") || - (Cursor + std::string_view("bb_id").size() < Text.size() && - Text[Cursor + std::string_view("bb_id").size()] != ' ' && - Text[Cursor + std::string_view("bb_id").size()] != '\t')) { - return fail(ErrorRange(Cursor), "expected 'bb_id'"); - } - Cursor += std::string_view("bb_id").size(); - - std::array Values{}; - if (!ParseNumber(Cursor, Values[0])) - return fail(ErrorRange(0), "expected unsigned integer"); - - SkipSpace(Cursor); - if (Cursor < Text.size() && (Text[Cursor] == ',' || Text[Cursor] == '.')) { - ++Cursor; - if (!ParseNumber(Cursor, Values[1])) - return fail(ErrorRange(0), "expected unsigned integer"); - } else if (Cursor < Text.size() && Text[Cursor] >= '0' && Text[Cursor] <= '9') { - if (!ParseNumber(Cursor, Values[1])) - return fail(ErrorRange(0), "expected unsigned integer"); - } - - SkipSpace(Cursor); - if (Cursor >= Text.size() || Text[Cursor] != ',') - return fail(ErrorRange(Cursor), "expected ','"); - ++Cursor; - if (!ParseNumber(Cursor, Values[2])) - return fail(ErrorRange(0), "expected unsigned integer"); - SkipSpace(Cursor); - if (Cursor != Text.size()) - return fail(ErrorRange(0), "unexpected content after prefetch target"); - - auto AddResult = Function.records().addPrefetchTarget( - {.Block = {Values[0], Values[1]}, .CallsiteIndex = Values[2]}); - if (!AddResult) - return importError(TargetNode->range(), AddResult.error()); - } - } - - if (const yaml::Node *EntryValues = mappingValue(Root, "entry_values")) { - if (requireKind(*EntryValues, yaml::NodeKind::Sequence, "entry values")) - return true; - constexpr std::array Keys{ - std::string_view{"entry-value-register"}, - std::string_view{"debug-info-variable"}, - std::string_view{"debug-info-expression"}, - std::string_view{"debug-info-location"}, - }; - for (const yaml::NodeID EntryID : EntryValues->sequence()) { - const yaml::Node *Entry = node(EntryID); - if (Entry == nullptr || requireKind(*Entry, yaml::NodeKind::Mapping, "entry value") || - validateKeys(*Entry, Keys, "entry value")) { - return true; - } - const yaml::Node *RegNode = mappingValue(*Entry, "entry-value-register"); - const yaml::Node *VariableNode = mappingValue(*Entry, "debug-info-variable"); - const yaml::Node *ExpressionNode = mappingValue(*Entry, "debug-info-expression"); - const yaml::Node *LocationNode = mappingValue(*Entry, "debug-info-location"); - if (RegNode == nullptr || VariableNode == nullptr || ExpressionNode == nullptr || - LocationNode == nullptr) { - return fail(Entry->range(), "entry value requires all four fixed fields"); - } - PhysicalRegister Reg; - if (physicalRegister(*RegNode, Reg)) - return true; - MachineVariableDebugInfo DebugInfo; - if (parseVariableDebugInfo(*Entry, Function, DebugInfo)) - return true; - if (!DebugInfo.Variable || !DebugInfo.Expression || !DebugInfo.Location) { - return fail(Entry->range(), "entry value debug metadata cannot be empty", - "mir-debug-metadata"); - } - auto AddResult = - Function.records().addEntryValue({.Reg = Reg, .DebugInfo = std::move(DebugInfo)}); - if (!AddResult) - return importError(Entry->range(), AddResult.error()); - } - } - return false; -} - -} // namespace rcc::mir -- cgit v1.2.3