diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h --- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h +++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h @@ -304,6 +304,30 @@ static const bool flow = true; }; +/// Serializable representation of the MCRegister variant of +/// MachineFunction::VariableDbgInfo. +struct EntryValueObject { + StringValue EntryValueRegister; + StringValue DebugVar; + StringValue DebugExpr; + StringValue DebugLoc; + bool operator==(const EntryValueObject &Other) const { + return EntryValueRegister == Other.EntryValueRegister && + DebugVar == Other.DebugVar && DebugExpr == Other.DebugExpr && + DebugLoc == Other.DebugLoc; + } +}; + +template <> struct MappingTraits { + static void mapping(yaml::IO &YamlIO, EntryValueObject &Object) { + YamlIO.mapRequired("entry-value-register", Object.EntryValueRegister); + YamlIO.mapRequired("debug-info-variable", Object.DebugVar); + YamlIO.mapRequired("debug-info-expression", Object.DebugExpr); + YamlIO.mapRequired("debug-info-location", Object.DebugLoc); + } + static const bool flow = true; +}; + /// Serializable representation of the fixed stack object from the /// MachineFrameInfo class. struct FixedMachineStackObject { @@ -572,6 +596,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::EntryValueObject) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CallSiteInfo) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue) @@ -716,6 +741,7 @@ // Frame information MachineFrameInfo FrameInfo; std::vector FixedStackObjects; + std::vector EntryValueObjects; std::vector StackObjects; std::vector Constants; /// Constant pool. std::unique_ptr MachineFuncInfo; @@ -760,6 +786,8 @@ std::vector()); YamlIO.mapOptional("stack", MF.StackObjects, std::vector()); + YamlIO.mapOptional("entry_values", MF.EntryValueObjects, + std::vector()); YamlIO.mapOptional("callSites", MF.CallSitesInfo, std::vector()); YamlIO.mapOptional("debugValueSubstitutions", MF.DebugValueSubstitutions, diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -1297,6 +1297,14 @@ }); } + /// Returns the collection of variables for which we have debug info and that + /// have been assigned an entry value register. + auto getEntryValueVariableDbgInfo() const { + return make_filter_range(getVariableDbgInfo(), [](const auto &VarInfo) { + return VarInfo.inEntryValueRegister(); + }); + } + /// Start tracking the arguments passed to the call \p CallI. void addCallArgsForwardingRegs(const MachineInstr *CallI, CallSiteInfoImpl &&CallInfo) { diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -803,6 +803,24 @@ return true; } + for (const auto &Object : YamlMF.EntryValueObjects) { + SMDiagnostic Error; + Register Reg; + if (parseNamedRegisterReference(PFS, Reg, Object.EntryValueRegister.Value, + Error)) + return error(Error, Object.EntryValueRegister.SourceRange); + if (!Reg.isPhysical()) + return error(Object.EntryValueRegister.SourceRange.Start, + "Expected physical register for entry value field"); + std::optional MaybeInfo = parseVarExprLoc( + PFS, Object.DebugVar, Object.DebugExpr, Object.DebugLoc); + if (!MaybeInfo) + return true; + if (MaybeInfo->DIVar || MaybeInfo->DIExpr || MaybeInfo->DILoc) + PFS.MF.setVariableDbgInfo(MaybeInfo->DIVar, MaybeInfo->DIExpr, + Reg.asMCReg(), MaybeInfo->DILoc); + } + // Initialize the ordinary frame objects. for (const auto &Object : YamlMF.StackObjects) { int ObjectIdx; diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -119,6 +119,9 @@ const MachineJumpTableInfo &JTI); void convertStackObjects(yaml::MachineFunction &YMF, const MachineFunction &MF, ModuleSlotTracker &MST); + void convertEntryValueObjects(yaml::MachineFunction &YMF, + const MachineFunction &MF, + ModuleSlotTracker &MST); void convertCallSiteObjects(yaml::MachineFunction &YMF, const MachineFunction &MF, ModuleSlotTracker &MST); @@ -221,6 +224,7 @@ MST.incorporateFunction(MF.getFunction()); convert(MST, YamlMF.FrameInfo, MF.getFrameInfo()); convertStackObjects(YamlMF, MF, MST); + convertEntryValueObjects(YamlMF, MF, MST); convertCallSiteObjects(YamlMF, MF, MST); for (const auto &Sub : MF.DebugValueSubstitutions) { const auto &SubSrc = Sub.Src; @@ -373,6 +377,19 @@ } } +void MIRPrinter::convertEntryValueObjects(yaml::MachineFunction &YMF, + const MachineFunction &MF, + ModuleSlotTracker &MST) { + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); + for (const MachineFunction::VariableDbgInfo &DebugVar : + MF.getEntryValueVariableDbgInfo()) { + yaml::EntryValueObject &Obj = YMF.EntryValueObjects.emplace_back(); + printStackObjectDbgInfo(DebugVar, Obj, MST); + MCRegister EntryValReg = DebugVar.getEntryValueRegister(); + printRegMIR(EntryValReg, Obj.EntryValueRegister, TRI); + } +} + void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF, const MachineFunction &MF, ModuleSlotTracker &MST) { diff --git a/llvm/test/CodeGen/MIR/AArch64/entry_values.mir b/llvm/test/CodeGen/MIR/AArch64/entry_values.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AArch64/entry_values.mir @@ -0,0 +1,39 @@ +# RUN: llc -mtriple=aarch64 -run-pass none -o - %s | FileCheck %s + +# This test ensures that the MIR parser parses machine entry_value properties +# correctly. + +--- | + + define void @foo(ptr swiftasync %arg) !dbg !4 { + call void @llvm.dbg.declare(metadata ptr %arg, metadata !9, metadata !DIExpression(DW_OP_LLVM_entry_value, 1)), !dbg !10 + ret void + } + + declare void @llvm.dbg.declare(metadata, metadata, metadata) + !llvm.module.flags = !{!0, !1} + !llvm.dbg.cu = !{!2} + !0 = !{i32 7, !"Dwarf Version", i32 4} + !1 = !{i32 2, !"Debug Info Version", i32 3} + !2 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !3, runtimeVersion: 0, emissionKind: FullDebug) + !3 = !DIFile(filename: "blah", directory: "") + !4 = distinct !DISubprogram(linkageName: "foo", scope: null, file: !3, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !6) + !5 = !DISubroutineType(types: null) + !6 = !{!7, !9} + !7 = !DILocalVariable(name: "k1", scope: !4, file: !3, line: 7, type: !8) + !8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Klass") + !9 = !DILocalVariable(name: "k2", scope: !4, file: !3, line: 7, type: !8) + !10 = !DILocation(line: 6, scope: !4) + +... +--- +name: foo +entry_values: + - { entry-value-register: '$x22', debug-info-variable: '!9', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1)', + debug-info-location: '!10' } +# CHECK: entry_values: +# CHECK: - { entry-value-register: '$x22', debug-info-variable: '![[#]]', debug-info-expression: '!DIExpression(DW_OP_LLVM_entry_value, 1)', +# CHECK: debug-info-location: '![[#]]' } +body: | + bb.1: +... diff --git a/llvm/test/CodeGen/PowerPC/unreachable-mbb-jtreference-elimination.ll b/llvm/test/CodeGen/PowerPC/unreachable-mbb-jtreference-elimination.ll --- a/llvm/test/CodeGen/PowerPC/unreachable-mbb-jtreference-elimination.ll +++ b/llvm/test/CodeGen/PowerPC/unreachable-mbb-jtreference-elimination.ll @@ -4,6 +4,7 @@ define dso_local void @foo() #0 { ; CHECK-LABEL: fixedStack: ; CHECK-NEXT: stack: [] +; CHECK-NEXT: entry_values: [] ; CHECK-NEXT: callSites: [] ; CHECK-NEXT: debugValueSubstitutions: [] ; CHECK-NEXT: constants: [] diff --git a/llvm/test/DebugInfo/X86/empty-metadata-dbg-declare.ll b/llvm/test/DebugInfo/X86/empty-metadata-dbg-declare.ll --- a/llvm/test/DebugInfo/X86/empty-metadata-dbg-declare.ll +++ b/llvm/test/DebugInfo/X86/empty-metadata-dbg-declare.ll @@ -10,7 +10,7 @@ ; CHECK-NEXT: stack-id: default, callee-saved-register: '', callee-saved-restored: true, ; CHECK-NEXT: debug-info-variable: '![[f]]', debug-info-expression: '!DIExpression()', ; CHECK-NEXT: debug-info-location: '{{.+}}' } -; CHECK-NEXT: callSites: +; CHECK-NEXT: entry_values: target triple = "x86_64-unknown-linux-gnu"