[DebugInfo] Generate debug information for labels.
ClosedPublic

Authored by HsiangKai on Mar 29 2018, 7:35 AM.

Diff Detail

Repository
rL LLVM
HsiangKai created this revision.Mar 29 2018, 7:35 AM
HsiangKai changed the repository for this revision from rL LLVM to rC Clang.Mar 29 2018, 7:35 AM
chenwj requested changes to this revision.Mar 30 2018, 6:23 AM

Nits.

lib/CodeGen/CGDebugInfo.cpp
3644 ↗(On Diff #140248)

Indent.

lib/CodeGen/CGStmt.cpp
535 ↗(On Diff #140248)

I assume you emit debug info for the label only if it's reachable by checking HaveInsertPoint(). If so, make the comment as

// Emit debug info for the label only if it's reachable.

I prefer adding braces here. Please check indent as well.

This revision now requires changes to proceed.Mar 30 2018, 6:23 AM
HsiangKai updated this revision to Diff 140423.Mar 30 2018, 7:19 AM
HsiangKai retitled this revision from [DebugInfo] Generate debug information about labels to [DebugInfo] Generate DILabel metadata for labels..
HsiangKai edited the summary of this revision. (Show Details)
  1. No generating llvm.dbg.label intrinsic.
  2. Modify commits according to chenwj's comments.
HsiangKai updated this revision to Diff 140627.Apr 2 2018, 8:14 AM
HsiangKai retitled this revision from [DebugInfo] Generate DILabel metadata for labels. to [DebugInfo] Generate debug information for labels..
HsiangKai edited the summary of this revision. (Show Details)
HsiangKai updated this revision to Diff 141989.Apr 11 2018, 6:12 AM

Update the test case for inlined functions. The inlined label will attach to DISubprogram(..., labels: !n)

One question, but otherwise this looks fine.

lib/CodeGen/CGStmt.cpp
535 ↗(On Diff #141989)

Shouldn't it be added to the list of labels/variables of the DISubprogram regardless?

HsiangKai updated this revision to Diff 142533.Apr 14 2018, 7:02 PM

Update test cases.

HsiangKai marked 2 inline comments as done.Apr 16 2018, 8:00 AM

Always add labels to DISubprogram even unreachable.

aprantl accepted this revision.Apr 16 2018, 9:09 AM

Please run your changes through clang format before checking this in; otherwise LGTM.

  • Update test cases.
  • Checked with clang-format.
HsiangKai marked an inline comment as done.Apr 26 2018, 11:21 PM

@chenwj Do you have any comments for this patch?

This revision was not accepted when it landed; it landed in state Needs Review.May 8 2018, 7:47 PM
Closed by commit rL331843: [DebugInfo] Generate debug information for labels. (authored by shiva, committed by ). · Explain Why
This revision was automatically updated to reflect the committed changes.
hans added a subscriber: hans.May 9 2018, 2:33 AM

This broke the Chromium build. I've uploaded a reproducer at https://bugs.chromium.org/p/chromium/issues/detail?id=841170#c1

I'm guessing maybe a Clang bootstrap with debug info might also reproduce the problem, but I haven't tried that.

Reverted in r331861.

This broke the Chromium build. I've uploaded a reproducer at https://bugs.chromium.org/p/chromium/issues/detail?id=841170#c1

I'm guessing maybe a Clang bootstrap with debug info might also reproduce the problem, but I haven't tried that.

Reverted in r331861.

https://reviews.llvm.org/D46738 should fix the bug.

This broke the Chromium build. I've uploaded a reproducer at https://bugs.chromium.org/p/chromium/issues/detail?id=841170#c1

I'm guessing maybe a Clang bootstrap with debug info might also reproduce the problem, but I haven't tried that.

Reverted in r331861.

https://reviews.llvm.org/D46738 should fix the bug.

rL336176 has fixed the bug. Could I revert the commit?
You could refer to PR37395.

hans added a comment.Jul 3 2018, 2:38 AM

This broke the Chromium build. I've uploaded a reproducer at https://bugs.chromium.org/p/chromium/issues/detail?id=841170#c1

I'm guessing maybe a Clang bootstrap with debug info might also reproduce the problem, but I haven't tried that.

Reverted in r331861.

https://reviews.llvm.org/D46738 should fix the bug.

rL336176 has fixed the bug. Could I revert the commit?
You could refer to PR37395.

I'm not familiar with your patch, but if you're confident that it works (for example, a clang bootstrap works), then committing again sounds good to me.

vext01 added a subscriber: vext01.Aug 1 2018, 7:09 AM
vext01 added a comment.Aug 1 2018, 7:16 AM

Looks like this was backed out (reverted) yesterday.

I'm really interested in inserting DILabels from LLVM in my research project, so I hope it can be recovered.

Looks like this was backed out (reverted) yesterday.

I'm really interested in inserting DILabels from LLVM in my research project, so I hope it can be recovered.

You could apply it locally. In most cases, it works fine.

Currently, I still work on some problems when you use label in goto expression and you do some calculation on it under optimization.
Following is the test case I try to resolve the problem.

int tab[9];

void execute(unsigned short *oip, unsigned short *ip)
{
  int x = 0;
  int *xp = tab;
base:
  x++;
  if (x == 4)
    {
      *xp = 0;
      return;
    }
  *xp++ = ip - oip;
  goto *(&&base + *ip++);
}

int main()
{
  unsigned short ip[10];
  int i;
  for (i = 0; i < 10; i++)
    ip[i] = 0;
  execute(ip, ip);

  return 0;
}

If you do not use label in such complex way, I think you could apply it temporarily.

vext01 added a comment.Aug 1 2018, 8:19 AM

Hi HsiangKai,

Thanks for the response.

Indeed, I've just rolled back to just before the revert for now to experiment, but I do hope this change hits LLVM-7.

Wishing you the best of luck with getting it merged!

vext01 added a comment.Aug 6 2018, 4:13 AM

Hi,

I've been experimenting some more with this patch.

It seems to me that if a label is optimised away, but you've requested it be preserved, then you get a DWARF label with a zero offset. Is that the expected behaviour? Should it be documented?

E.g.:

< 6><0x000000dc>              DW_TAG_label
                                DW_AT_name                  __YK_BLK_2_19418_0
                                DW_AT_low_pc                0x00000000

Thanks!

Hi,

I've been experimenting some more with this patch.

It seems to me that if a label is optimised away, but you've requested it be preserved, then you get a DWARF label with a zero offset. Is that the expected behaviour? Should it be documented?

E.g.:

< 6><0x000000dc>              DW_TAG_label
                                DW_AT_name                  __YK_BLK_2_19418_0
                                DW_AT_low_pc                0x00000000

Thanks!

I expect that even the code is optimized out, the label will point to somewhere in the function. If the whole function is optimized out, the label should not exist any more. It should not have address zero.

Do you have any test snippet to reproduce the bug? Thanks.

vext01 added a comment.Aug 7 2018, 3:57 AM

Hi,

I'm generating these labels from the Rust compiler, which is far from a minimal example.

I'm actually conflicted about what should happen if code containing a label is removed, but the label is marked to be "retained". Maybe it does make sense for those to stay with some kind of a special offset or flag to indicate so. What do you think?

FWIW, my working assumption is that the -unreachableblockelim pass is removing code that contains labels, resulting in 0x0 offsets.

I'll try to get a simple example that gives a label with an 0x0 offset.

vext01 added a comment.Aug 7 2018, 5:45 AM

Got one!

Here's a dumb program which simply adds 3 to 1 using a function. There is one label in the add_3 function, named XXXYYYZZZ:

; ModuleID = 'mymod'
source_filename = "mymod"

define i32 @add_3(i32 %x) !dbg !3 {
entry:
  %res = add i32 %x, 3, !dbg !9
  call void @llvm.dbg.label(metadata !8), !dbg !9
  ret i32 %res, !dbg !9
}

; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.label(metadata) #0

define i32 @main() {
entry:
  %0 = call i32 @add_3(i32 1)
  ret i32 %0
}

attributes #0 = { nounwind readnone speculatable }

!llvm.module.flags = !{!0}
!llvm.dbg.cu = !{!1}

!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2, producer: "API Example", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
!2 = !DIFile(filename: "main.xxx", directory: ".")
!3 = distinct !DISubprogram(name: "add_3", scope: null, file: !2, type: !4, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !1, retainedNodes: !7)
!4 = !DISubroutineType(types: !5)
!5 = !{!6, !6}
!6 = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned)
!7 = !{!8}
!8 = !DILabel(scope: !3, name: "XXXYYYZZZ", file: !2, line: 1)
!9 = !DILocation(line: 0, column: 1, scope: !3)

If we compile this (using LLVM just before your change was backed out), and inspect the debuginfo:

$ clang -g -c -O0 -o example.o example.ll
warning: overriding the module target triple with x86_64-unknown-linux-gnu [-Woverride-module]
1 warning generated.
$ dwarfdump example.o
...
< 2><0x00000041>      DW_TAG_label
                        DW_AT_name                  XXXYYYZZZ
                        DW_AT_decl_file             0x00000001 ./main.xxx
                        DW_AT_decl_line             0x00000001
                        DW_AT_low_pc                0x00000000
...

Here we can see that DW_AT_low_pc is 0. What does this mean? Perhaps a bug? The code is clearly not dead, although I would understand if add_3 were inlined. Either way, I'd expect a non-zero low_pc, right?

Hi @vext01,

It should be fixed in https://reviews.llvm.org/D50495.
Please help me to confirm it in your environment. Thanks so much. :)

The latest reland of this patch triggers a segfault in clang (seemingly only on k8 and ppc).
I've bisected it to r341519 but don't understand the cause.
The stacktrace is:

1.	<eof> parser at end of file
2.	Code generation
#0 0x00005649754494d4 SignalHandler(int) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x10db4d4)
#1 0x00007f72c7f849a0 __restore_rt (/usr/grte/v4/lib64/libpthread.so.0+0xf9a0)
#2 0x000056497495f950 llvm::MCObjectStreamer::visitUsedSymbol(llvm::MCSymbol const&) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x5f1950)
#3 0x0000564974927858 llvm::MCELFStreamer::EmitValueImpl(llvm::MCExpr const*, unsigned int, llvm::SMLoc) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x5b9858)
#4 0x0000564975bdb18c llvm::AddressPool::emit(llvm::AsmPrinter&, llvm::MCSection*) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x186d18c)
#5 0x0000564975bb5525 llvm::DwarfDebug::endModule() (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x1847525)
#6 0x00005649748d185a llvm::AsmPrinter::doFinalization(llvm::Module&) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x56385a)
#7 0x000056497535f883 llvm::FPPassManager::doFinalization(llvm::Module&) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0xff1883)
#8 0x000056497535ff05 llvm::legacy::PassManagerImpl::run(llvm::Module&) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0xff1f05)
#9 0x0000564974acff27 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x761f27)
#10 0x00005649764c40cd clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x21560cd)
#11 0x0000564974cc4f78 clang::ParseAST(clang::Sema&, bool, bool) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x956f78)
#12 0x000056497649a3e7 clang::FrontendAction::Execute() (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x212c3e7)
#13 0x00005649764e1c02 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x2173c02)
#14 0x000056497683e8b3 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x24d08b3)
#15 0x00005649754110de cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0x10a30de)
#16 0x0000564974e4682a main (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0xad882a)
#17 0x00007f72c7cf2bbd __libc_start_main (/usr/grte/v4/lib64/libc.so.6+0x38bbd)
#18 0x0000564974e51069 _start (third_party/crosstool/v18/llvm_unstable/toolchain/bin/clang+0xae3069)
clang: error: unable to execute command: Segmentation fault
clang: error: clang frontend command failed due to signal (use -v to see invocation)

I can try to isolate a reproducer if the buildbots don't pick this up.