This is an archive of the discontinued LLVM Phabricator instance.

[BDCE/DebugInfo] Preserve llvm.dbg.value's argument
ClosedPublic

Authored by davide on Dec 6 2016, 10:31 AM.

Details

Summary

BDCE has two phases:

  1. It asks SimplifyDemandedBits if all the bits of an instruction are dead, and if so, replaces all its uses with the constant zero.
  2. Then, it asks SimplifyDemandedBits again if the instruction is really dead (no side effects etc..) and if so, eliminates it.

Now, in 1) if all the bits of an instruction are dead, we may end up replacing a dbg use:

%call = tail call i32 (...) @g() #4, !dbg !15
tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !8, metadata !16), !dbg !17

->

%call = tail call i32 (...) @g() #4, !dbg !15
tail call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !8, metadata !16), !dbg !17

but not eliminating the call because it may have arbitrary side effects.
In other words, we lose some debug informations.

There are various possible solutions to the problem. E.g.:

  1. If the instruction has side effects and no non-dbg uses, BDCE should do nothing with it.
  2. We could introduce a variant of RAUW, called RAUWExceptDbg that doesn't strip dbg uses.

I tried to implement 2), but things get very ugly very quickly. Therefore, this patch implements 1), after discussing the solution with David/Hal.

Diff Detail

Repository
rL LLVM

Event Timeline

davide updated this revision to Diff 80444.Dec 6 2016, 10:31 AM
davide retitled this revision from to [BDCE/DebugInfo] Preserve llvm.dbg.value's argument.
davide updated this object.
davide added reviewers: hfinkel, aprantl, majnemer, andreadb.
davide added a subscriber: llvm-commits.
aprantl added inline comments.Dec 6 2016, 11:38 AM
test/Transforms/BDCE/pr26587.ll
10 ↗(On Diff #80444)

Does this also work with a non-asserts opt? I'm not sure if it is clang that is stripping out the values' names or if the parser does that, too.

CHECK-NEXT: %[[CALL:.*]] = tail call i32 (...) @g()

Probably don't need to check for the !dbg !10 here.

davide added inline comments.Dec 6 2016, 11:44 AM
test/Transforms/BDCE/pr26587.ll
10 ↗(On Diff #80444)

Done. Confirmed that the test passes also with Release (non assert)

davide updated this revision to Diff 80457.Dec 6 2016, 11:45 AM
aprantl added inline comments.Dec 6 2016, 12:42 PM
lib/Transforms/Scalar/BDCE.cpp
45 ↗(On Diff #80457)

It looks like this alters the behavior of the optimization beyond debug info. It would be great if someone else could sign off on this change.

davide added inline comments.Dec 6 2016, 12:47 PM
lib/Transforms/Scalar/BDCE.cpp
45 ↗(On Diff #80457)

I discussed this with David M. and he was OK with this solution. I'm still a little nervous this may break optimizations, so I'll be more confident to get this in if Hal signs it off.

efriedma added inline comments.
lib/Transforms/Scalar/BDCE.cpp
44 ↗(On Diff #80457)

"I.use_empty()" is a bit more straightforward than "!I.hasNUsesOrMore(1)".

45 ↗(On Diff #80457)

I don't think this alters visible behavior without debug info: if the instruction has no uses, RAUW is a no-op, and if mayHaveSideEffects() is true, isInstructionDead() is false. So this looks fine, I think.

davide added inline comments.Dec 6 2016, 1:09 PM
lib/Transforms/Scalar/BDCE.cpp
45 ↗(On Diff #80457)

Thanks for your review, Eli!

davide updated this revision to Diff 80468.Dec 6 2016, 1:11 PM

Address Eli's comment.

majnemer accepted this revision.Dec 6 2016, 1:50 PM
majnemer edited edge metadata.

LGTM

This revision is now accepted and ready to land.Dec 6 2016, 1:50 PM
This revision was automatically updated to reflect the committed changes.