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/MIRDocumentReferenceValidation.cpp | 426 --------------------- 1 file changed, 426 deletions(-) delete mode 100644 backend/lib/MIR/MIRDocumentReferenceValidation.cpp (limited to 'backend/lib/MIR/MIRDocumentReferenceValidation.cpp') diff --git a/backend/lib/MIR/MIRDocumentReferenceValidation.cpp b/backend/lib/MIR/MIRDocumentReferenceValidation.cpp deleted file mode 100644 index 69b0dd1..0000000 --- a/backend/lib/MIR/MIRDocumentReferenceValidation.cpp +++ /dev/null @@ -1,426 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "MIRDocumentReferenceValidation.h" - -#include "rcc/CodeGen/MachineBasicBlock.h" -#include "rcc/CodeGen/MachineConstantPool.h" -#include "rcc/CodeGen/MachineFrameInfo.h" -#include "rcc/CodeGen/MachineFunction.h" -#include "rcc/CodeGen/MachineFunctionRecords.h" -#include "rcc/CodeGen/MachineInstr.h" -#include "rcc/CodeGen/MachineMetadata.h" -#include "rcc/MIR/MIRDocument.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace rcc::mir { - -Expected verifyMIRDocumentReferences(const MIRDocument &Document, - const MachineFunction &Function, bool UseEmbeddedIR) { - const EmbeddedIRReferenceIndex *Embedded = UseEmbeddedIR ? Document.embeddedIR() : nullptr; - const EmbeddedIRFunction *IRFunction = nullptr; - if (Embedded != nullptr) { - if (Function.name().empty()) { - std::size_t AnonymousOrdinal = 0; - bool FoundFunction = false; - for (std::size_t Index = 0; Index < Document.unit().functionCount(); ++Index) { - const MachineFunction *Candidate = Document.unit().functionAt(Index); - if (Candidate == &Function) { - FoundFunction = true; - break; - } - if (Candidate != nullptr && Candidate->name().empty()) - ++AnonymousOrdinal; - } - if (FoundFunction) - IRFunction = Embedded->unnamedFunction(AnonymousOrdinal); - } else { - IRFunction = Embedded->function(Function.name()); - } - if (IRFunction == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "machine function has no matching embedded LLVM IR function"); - } - } - - const auto ValidateGlobal = [Embedded](std::string_view Name, - std::string_view Description) -> Expected { - if (Embedded == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + - " requires embedded LLVM IR to resolve global '" + - std::string(Name) + "'"); - } - if (Embedded->hasGlobalValue(Name)) - return {}; - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + - " references an undefined embedded LLVM IR global '" + - std::string(Name) + "'"); - }; - const auto ValidateBlockAddress = [Embedded](std::string_view FunctionName, - std::string_view BlockName, - std::string_view Description) -> Expected { - if (Embedded == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + - " requires embedded LLVM IR to resolve a block address"); - } - const EmbeddedIRFunction *AddressFunction = Embedded->function(FunctionName); - if (AddressFunction == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + - " references an undefined embedded LLVM IR function '" + - std::string(FunctionName) + "'"); - } - if (AddressFunction->block(BlockName) == nullptr) { - return makeUnexpected( - ErrorCode::VerificationError, - std::string(Description) + " references an undefined embedded LLVM IR block '" + - std::string(BlockName) + "' in function '" + std::string(FunctionName) + "'"); - } - return {}; - }; - const auto ValidateIRValue = [IRFunction](std::string_view Name, - std::string_view Description) -> Expected { - if (IRFunction == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + - " requires embedded LLVM IR to resolve IR value '%" + - std::string(Name) + "'"); - } - if (IRFunction->value(Name) != nullptr) - return {}; - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + - " references an undefined embedded LLVM IR value '%" + - std::string(Name) + "'"); - }; - const auto ValidateMetadata = [Embedded](MachineMetadataReference Reference, - std::initializer_list ExpectedTypes, - std::string_view Description) -> Expected { - if (!Reference.isValid()) { - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + " has an invalid metadata reference"); - } - if (Reference.scope() != MachineMetadataScope::EmbeddedIR) - return {}; - if (Embedded == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + " requires embedded LLVM IR metadata !" + - std::to_string(Reference.slot())); - } - const EmbeddedIRMetadataDefinition *Definition = - Embedded->metadata(std::to_string(Reference.slot())); - if (Definition == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + - " references undefined embedded LLVM IR metadata !" + - std::to_string(Reference.slot())); - } - if (ExpectedTypes.size() == 0 || - std::ranges::find(ExpectedTypes, Definition->DynamicType) != ExpectedTypes.end()) { - return {}; - } - std::string Expected; - for (const std::string_view Type : ExpectedTypes) { - if (!Expected.empty()) - Expected.append(" or "); - Expected.append(Type); - } - return makeUnexpected(ErrorCode::VerificationError, - std::string(Description) + " requires " + Expected + " metadata, but !" + - std::to_string(Reference.slot()) + " is " + - (Definition->DynamicType.empty() - ? std::string("an unclassified metadata node") - : Definition->DynamicType)); - }; - const auto ValidateMetadataValue = - [&ValidateMetadata](const MachineMetadataValue &Value, - std::string_view Description) -> Expected { - const MachineMetadataReference *Reference = Value.reference(); - return Reference == nullptr ? Expected{} : ValidateMetadata(*Reference, {}, Description); - }; - const auto ValidateLocation = - [&ValidateMetadata](const MachineDebugLocation &Location, - std::string_view Description) -> Expected { - if (const MachineMetadataReference *Reference = Location.reference()) - return ValidateMetadata(*Reference, {"DILocation"}, Description); - const MachineDILocation *Inline = Location.inlineLocation(); - if (Inline == nullptr) - return {}; - for (const MachineDILocationFrame &Frame : Inline->inlineChain()) { - auto Verification = - ValidateMetadata(Frame.Scope, {"DISubprogram", "DILexicalBlock", "DILexicalBlockFile"}, - "inline DILocation scope"); - if (!Verification) - return Verification; - } - if (Inline->terminalInlinedAt()) { - return ValidateMetadata(*Inline->terminalInlinedAt(), {"DILocation"}, - "inline DILocation inlinedAt"); - } - return {}; - }; - const auto ValidateVariableDebugInfo = - [&ValidateMetadata, &ValidateMetadataValue, - &ValidateLocation](const MachineVariableDebugInfo &DebugInfo) -> Expected { - if (DebugInfo.Variable) { - auto Verification = - ValidateMetadata(*DebugInfo.Variable, {"DILocalVariable"}, "debug variable"); - if (!Verification) - return Verification; - } - if (DebugInfo.Expression) { - if (const MachineMetadataReference *Reference = DebugInfo.Expression->reference(); - Reference != nullptr) { - auto Verification = ValidateMetadata(*Reference, {"DIExpression"}, "debug expression"); - if (!Verification) - return Verification; - } - auto Verification = ValidateMetadataValue(*DebugInfo.Expression, "debug expression"); - if (!Verification) - return Verification; - } - if (DebugInfo.Location) - return ValidateLocation(*DebugInfo.Location, "debug location"); - return {}; - }; - const auto ValidateGenericType = [Embedded](const auto &Self, - const GenericConstantType &Type) -> Expected { - if (Type.Kind == GenericConstantTypeKind::Named) { - if (Embedded == nullptr) { - return makeUnexpected( - ErrorCode::VerificationError, - "generic constant type requires embedded LLVM IR to resolve named type '%" + Type.Name + - "'"); - } - if (Embedded->typeDefinition(Type.Name) == nullptr) { - return makeUnexpected( - ErrorCode::VerificationError, - "generic constant type references an undefined embedded LLVM IR named type '%" + - Type.Name + "'"); - } - } - for (const GenericConstantType &Element : Type.Elements) { - auto Verification = Self(Self, Element); - if (!Verification) - return Verification; - } - return {}; - }; - const auto ValidateGenericConstant = - [&ValidateBlockAddress, &ValidateGenericType, - &ValidateGlobal](const auto &Self, const GenericConstantData &Constant) -> Expected { - auto TypeVerification = ValidateGenericType(ValidateGenericType, Constant.Type); - if (!TypeVerification) - return TypeVerification; - if (Constant.SourceElementType) { - TypeVerification = ValidateGenericType(ValidateGenericType, *Constant.SourceElementType); - if (!TypeVerification) - return TypeVerification; - } - switch (Constant.Kind) { - case GenericConstantKind::GlobalAddress: - case GenericConstantKind::DSOLocalEquivalent: - case GenericConstantKind::NoCFI: - if (auto Verification = ValidateGlobal(Constant.Symbol, "generic constant"); !Verification) - return Verification; - break; - case GenericConstantKind::BlockAddress: - if (auto Verification = ValidateBlockAddress(Constant.Symbol, Constant.Block, - "generic constant blockaddress"); - !Verification) { - return Verification; - } - break; - default: - break; - } - for (const GenericConstantData &Element : Constant.Elements) { - auto Verification = Self(Self, Element); - if (!Verification) - return Verification; - } - return {}; - }; - - for (const MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; - Block = Block->next()) { - if (const auto Name = Block->attributes().irBlockName(); Name) { - if (IRFunction == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "machine basic block requires embedded LLVM IR to resolve block '" + - std::string(*Name) + "'"); - } - if (IRFunction->block(*Name) == nullptr) { - return makeUnexpected( - ErrorCode::VerificationError, - "machine basic block references an undefined embedded LLVM IR block '" + - std::string(*Name) + "'"); - } - } - } - for (const StackObject &Object : Function.frameInfo().objects()) { - const StackObjectDesc *Description = Object.description(); - if (Description == nullptr || !Description->AllocaName) - continue; - if (IRFunction == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "stack object requires embedded LLVM IR to resolve alloca '" + - *Description->AllocaName + "'"); - } - if (IRFunction->alloca(*Description->AllocaName) == nullptr) { - return makeUnexpected(ErrorCode::VerificationError, - "stack object references an undefined embedded LLVM IR alloca '" + - *Description->AllocaName + "'"); - } - } - - for (const MachineConstantPoolEntry &Entry : Function.constantPool().entries()) { - const MachineConstantPoolEntryDesc *Description = Entry.description(); - if (Description == nullptr) - continue; - if (const auto *Generic = std::get_if(&Description->Value)) { - auto Verification = ValidateGenericConstant(ValidateGenericConstant, *Generic); - if (!Verification) - return Verification; - } else if (const auto *Address = std::get_if(&Description->Value)) { - auto Verification = ValidateBlockAddress(Address->FunctionName, Address->BlockName, - "constant-pool block address"); - if (!Verification) - return Verification; - } - } - - for (const MachineMetadataNode &Node : Function.metadata().nodes()) { - for (const MachineMetadataElement &Element : Node.Elements) { - const MachineMetadataReference *Reference = Element.reference(); - if (Reference == nullptr) - continue; - auto Verification = ValidateMetadata(*Reference, {}, "machine metadata node"); - if (!Verification) - return Verification; - } - } - - for (const StackObject &Object : Function.frameInfo().objects()) { - const StackObjectDesc *Description = Object.description(); - if (Description == nullptr || !Description->DebugInfo) - continue; - auto Verification = ValidateVariableDebugInfo(*Description->DebugInfo); - if (!Verification) - return Verification; - } - for (const MachineEntryValueInfo &Entry : Function.records().entryValues()) { - auto Verification = ValidateVariableDebugInfo(Entry.DebugInfo); - if (!Verification) - return Verification; - } - for (const MachineCalledGlobal &Called : Function.records().calledGlobals()) { - auto Verification = ValidateGlobal(Called.Callee, "called-global record"); - if (!Verification) - return Verification; - } - - for (const MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; - Block = Block->next()) { - for (const MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr; - Instruction = Instruction->next()) { - if (Instruction->debugLocation()) { - auto Verification = - ValidateLocation(*Instruction->debugLocation(), "instruction debug location"); - if (!Verification) - return Verification; - } - const std::array InstructionMetadata{ - Instruction->heapAllocMarker(), - Instruction->pcSections(), - Instruction->mmra(), - }; - for (const auto &Reference : InstructionMetadata) { - if (!Reference) - continue; - auto Verification = ValidateMetadata(*Reference, {}, "instruction metadata attachment"); - if (!Verification) - return Verification; - } - - for (const MachineOperand &Operand : Instruction->operands()) { - if (const auto *Global = Operand.getIf(); Global != nullptr) { - auto Verification = ValidateGlobal(Global->Name, "global-symbol operand"); - if (!Verification) - return Verification; - } - if (const auto *Address = Operand.getIf(); Address != nullptr) { - auto Verification = ValidateBlockAddress(Address->FunctionName, Address->BlockName, - "block-address operand"); - if (!Verification) - return Verification; - } - if (const auto *Metadata = Operand.getIf(); Metadata != nullptr) { - auto Verification = ValidateMetadataValue(Metadata->Value, "metadata operand"); - if (!Verification) - return Verification; - } - } - - for (const MachineMemOperand *Memory : Instruction->memOperands()) { - const MachineMemOperandDesc &Description = Memory->description(); - const std::optional BaseName = Description.Base.symbolName(); - switch (Description.Base.kind()) { - case MemoryBase::Kind::GlobalSymbol: - case MemoryBase::Kind::CallEntryGlobal: - if (BaseName) { - auto Verification = ValidateGlobal(*BaseName, "machine memory base"); - if (!Verification) - return Verification; - } - break; - case MemoryBase::Kind::IRValue: - if (BaseName) { - auto Verification = ValidateIRValue(*BaseName, "machine memory base"); - if (!Verification) - return Verification; - } - break; - default: - break; - } - const std::array MetadataReferences{ - Description.TBAA, Description.AliasScope, - Description.NoAlias, Description.NoAliasAddressSpace, - Description.RangeMetadata, - }; - for (const auto &Reference : MetadataReferences) { - if (!Reference) - continue; - auto Verification = ValidateMetadata(*Reference, {}, "machine memory operand metadata"); - if (!Verification) - return Verification; - } - if (Description.SyncScope.value() == 0) - continue; - const auto Scope = - std::ranges::find_if(Document.syncScopes(), [&Description](const auto &Slot) { - return Slot.ID == Description.SyncScope; - }); - if (Scope == Document.syncScopes().end()) { - return makeUnexpected( - ErrorCode::VerificationError, - "machine memory operand synchronization scope has no document name"); - } - } - } - } - return {}; -} - -} // namespace rcc::mir -- cgit v1.2.3