From f86694cb808f22253e00742ccd279760ef0c688d Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Mon, 26 Jul 2021 15:00:08 +0100 Subject: [PATCH] [InstrRef][AArch64][1/4] Accept constant physreg variable locations Late in SelectionDAG we join up instruction numbers with their defining instructions, if it couldn't be done during the main part of SelectionDAG. One exception is function arguments, where we have to point a DBG_PHI instruction at the incoming live register, as they don't have a defining instruction. This patch adds another exception, for constant physregs, like aarch64 has. It may seem wasteful to use two instructions where we could use a single DBG_VALUE, however the whole point of instruction referencing is to decouple the identification of values from the specification of where variable location ranges start. (Part of my aarch64 work to ease adoption of instruction referencing, as in the meta comment on D104520) Differential Revision: https://reviews.llvm.org/D104520 --- llvm/lib/CodeGen/MachineFunction.cpp | 21 ++++++++---- .../DebugInfo/AArch64/instr-ref-const-physreg.ll | 38 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 llvm/test/DebugInfo/AArch64/instr-ref-const-physreg.ll diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index 72e5870..dc4b1a6 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -1131,15 +1131,24 @@ auto MachineFunction::salvageCopySSA(MachineInstr &MI) } } + MachineBasicBlock &InsertBB = *CurInst->getParent(); + // We reached the start of the block before finding a defining instruction. - // It must be an argument: assert that this is the entry block, and produce - // a DBG_PHI. - assert(!State.first.isVirtual()); - MachineBasicBlock &TargetBB = *CurInst->getParent(); - assert(&*TargetBB.getParent()->begin() == &TargetBB); + // It could be from a constant register, otherwise it must be an argument. + if (TRI.isConstantPhysReg(State.first)) { + // We can produce a DBG_PHI that identifies the constant physreg. Doesn't + // matter where we put it, as it's constant valued. + assert(CurInst->isCopy()); + } else { + // Assert that this is the entry block. If it isn't, then there is some + // code construct we don't recognise that deals with physregs across + // blocks. + assert(!State.first.isVirtual()); + assert(&*InsertBB.getParent()->begin() == &InsertBB); + } // Create DBG_PHI for specified physreg. - auto Builder = BuildMI(TargetBB, TargetBB.getFirstNonPHI(), DebugLoc(), + auto Builder = BuildMI(InsertBB, InsertBB.getFirstNonPHI(), DebugLoc(), TII.get(TargetOpcode::DBG_PHI)); Builder.addReg(State.first, RegState::Debug); unsigned NewNum = getNewDebugInstrNum(); diff --git a/llvm/test/DebugInfo/AArch64/instr-ref-const-physreg.ll b/llvm/test/DebugInfo/AArch64/instr-ref-const-physreg.ll new file mode 100644 index 0000000..93a7e00 --- /dev/null +++ b/llvm/test/DebugInfo/AArch64/instr-ref-const-physreg.ll @@ -0,0 +1,38 @@ +; RUN: llc %s -stop-before=finalize-isel -march=aarch64 -o - \ +; RUN: -experimental-debug-variable-locations | FileCheck %s + +; Test that when an SSA Value becomes a constant-physreg copy, under the +; instruction referencing model, the COPY is labelled. In the general case +; labelling a copy is undesirable -- this test really checks that we don't +; crash, and we don't just drop the information. + +; CHECK: DBG_PHI $xzr, 1 +; CHECK: DBG_INSTR_REF 1, 0 + +define i64 @test() !dbg !7 { + %foo = add i64 0, 0 + call void @llvm.dbg.value(metadata i64 %foo, metadata !12, metadata !DIExpression()), !dbg !13 + ret i64 %foo, !dbg !13 +} + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/tmp/out.c") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!""} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !11, !11} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed) +!12 = !DILocalVariable(name: "bar", arg: 1, scope: !7, file: !1, line: 3, type: !11) +!13 = !DILocation(line: 0, scope: !7) +!14 = !DILocalVariable(name: "baz", arg: 2, scope: !7, file: !1, line: 3, type: !11) -- 2.7.4