This is an archive of the discontinued LLVM Phabricator instance.

Add a new pass to compute DWARF path discriminators.
ClosedPublic

Authored by dnovillo on Feb 4 2014, 12:21 PM.

Details

Reviewers
echristo
Summary

DWARF discriminators are used to distinguish multiple control flow paths
on the same source location. When this happens, instructions across
basic block boundaries will share the same debug location.

This pass detects this situation and creates a new lexical scope to
one of the two instructions. This lexical scope is a child scope of
the original and contains a new discriminator value. This discriminator
is then picked up from MCObjectStreamer::EmitDwarfLocDirective to be
written on the object file.

Finally, the discriminator is emitted in EmitDwarfLineTable according
to the DWARF spec.

Diff Detail

Event Timeline

rafael added inline comments.Feb 4 2014, 2:59 PM
lib/MC/MCObjectStreamer.cpp
266 ↗(On Diff #6859)

leftover debug? :-)

dnovillo added inline comments.Feb 4 2014, 3:03 PM
lib/MC/MCObjectStreamer.cpp
268 ↗(On Diff #6859)

Clearly, I will remove this at some point.

dnovillo updated this revision to Unknown Object (????).Feb 7 2014, 3:21 PM

This changes the way scopes are generated. When an instruction requires
a new discriminator, it creates a new lexical block inside the instruction's
original scope. This new lexical block is then annotated with a new
discriminator value.

I'm still not sure if this is the right approach or not, but it seems to
be doing what I need.

  • The pass is still missing tests.
  • I'm not picking up discriminator values from the binary, so something is not being written properly.
dnovillo updated this revision to Unknown Object (????).Feb 10 2014, 11:06 AM

This avoids calling replaceOperandWith. When building the vector
of Values for the new MDNode, it uses the operands from the original
DILocation, except operand 2.

I'm running into an odd failure with the DILexicalBlock created by
DIBuilder::createLexicalBlock. It sometimes returns a lexical block that
causes an ICE when I insert it in the new DILocation I'm creating in
DILocation::copyWithNewScope.

It happens when building some of the ASAN runtime
(projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_list_test.c). The
failure is in:

554 LLVMContextImpl *pImpl = VP.getPointer()->getContext().pImpl;

VP is the Value for the newly created DILexicalBlock. The problem is that
the call to getContext() returns NULL.

I'm not sure why this is returning NULL. When I build the DILexicalBlock,
the Scope I'm using in AddDiscriminators::runOnFunction() is:

(gdb) call Scope->dump()
!{i32 786443, metadata <badref>, metadata <badref>, i32 65, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [/ssd/dnovillo/llvm/bld/projects/compiler-rt/lib/sanitizer_common/tests//ssd/dnovillo/llvm/llvm/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_list_test.cc]

I am calling DIBuilder::createLexicalBlock with:

DILexicalBlock NewScope = Builder.createLexicalBlock(Scope, File,

FirstDIL.getLineNumber(), FirstDIL.getColumnNumber());
  • The Scope I show above.
  • The File argument I create with: Builder.createFile(FirstDIL.getFilename(), Scope.getDirectory()) FirstDIL is the DILocation for the instruction I want to modify.

Trying to dump the DILexicalBlock I get returned also ICEs the compiler,
so I suppose that createLexicalBlock is doing something bad or I'm calling
it with bad arguments.

Any hints?

Thanks.

I think you're calling it with bad arguments - the Scope for a lexical block should never be NULL. You could probably just assert that in the DIBuilder. Look for the call to getNonCompileUnitScope - it's likely there that you're running into problems.

A small patch to add the assert at the right place for creating a lexical block should probably work as well.

dnovillo updated this revision to Unknown Object (????).Feb 11 2014, 9:05 AM

This update fixes the failures I was getting before. Instead of
modifying the DILexicalBlock after creation, I've changed
DIBuilder::createLexicalBlock to accept a discriminator value. This
seems cleaner as well.

I suppose that when I was mutating the block, this was invalidating
some caching done by the MDNode machinery? I'm not really sure what
was happening.

With this I get no ICEs, but I still don't seem to fully get
discriminators all the way down to the executable. Is there any other
place for me to look at?

dnovillo updated this revision to Unknown Object (????).Feb 11 2014, 3:18 PM

With this update, we are now generating discriminators in the object
file. The assembly streamer was already emitting discriminator values,
but not the object streamer.

The patch still needs tests. I will work on them next. In the meantime,
could you start going through the patch?

Thanks. Diego.

dnovillo updated this revision to Unknown Object (????).Feb 11 2014, 3:28 PM

Fixlet for -save-temps.

When using -save-temps, the 'discriminator' keyword was not emitted
with the proper formatting. It needs a space before it. The 'isa'
keyword had the same problem.

Seems like a reasonable start. I think it'd be good to start looking at breaking things out. The pass and then everything else (though some of the everything else can be split out into separate patches as well). Otherwise tests and documentation changes for the individual patches and it's probably good to go.

dnovillo updated this revision to Unknown Object (????).Feb 18 2014, 1:47 PM

This adds documentation, tests and cleans up the original submission
to remove already committed code.

dnovillo updated this revision to Unknown Object (????).Feb 21 2014, 5:52 AM

Fix buglet in DILocation::getDiscriminator. It only makes sense
to lookup a discriminator on lexical blocks. Before looking it up,
make sure that the location's scope is a lexical block.

echristo requested changes to this revision.Feb 25 2014, 5:38 PM

One more split I think, the pass, the two helper functions, and table can be separate from the rest of it. It would be nice to see the patch without them using some discriminator information to make sure that we emit the right code.

dnovillo updated this revision to Unknown Object (????).Feb 26 2014, 3:13 PM

Factored changes to DILexicalBlock into http://llvm-reviews.chandlerc.com/D2891.

echristo accepted this revision.Mar 3 2014, 10:13 AM

LGTM. Thanks for doing all of this and putting up with the reviews!

dnovillo closed this revision.Mar 5 2014, 8:46 AM
kula85 added a subscriber: kula85.May 25 2015, 2:54 PM
ychen added a subscriber: ychen.May 25 2015, 2:57 PM