This is an archive of the discontinued LLVM Phabricator instance.

Remove debug info when hoisting instruction from then/else branch.
ClosedPublic

Authored by danielcdh on Sep 1 2016, 3:50 PM.

Details

Summary

The hoisted instruction is executed speculatively. It could affect the debugging experience as user would see gdb go into code that may not be expected to execute. It will also affect sample profile accuracy by assigning incorrect frequency to source within then/else branch.

Diff Detail

Event Timeline

danielcdh updated this revision to Diff 70085.Sep 1 2016, 3:50 PM
danielcdh retitled this revision from to Remove debug info when hoisting instruction from then/else branch..
danielcdh updated this object.
danielcdh added reviewers: davidxl, dblaikie.
danielcdh added a subscriber: llvm-commits.
dblaikie edited edge metadata.Sep 1 2016, 7:49 PM

I would worry that this might produce a worse experience for a sanitizer user, for example - but I'm not sure. (the sanitizer user won't have any trail back to why the store in this example is happening - granted, the way the code currently works, they may be told the store is happening in the wrong branch, which isn't great either)

Would mind getting Eric, Chandler, and/or Kostya's perspective on this.

As for the mechanics: might want to sure-up the CHECK lines to actually trace the lines back to the instructions - depending on the ordering of the DILocations being emitted is probably a bit too brittle.

danielcdh edited reviewers, added: echristo; removed: eric_niebler.

I would worry that this might produce a worse experience for a sanitizer user, for example - but I'm not sure. (the sanitizer user won't have any trail back to why the store in this example is happening - granted, the way the code currently works, they may be told the store is happening in the wrong branch, which isn't great either)

I don't know about the sanitizer user experience. However, based on my experience with sample pgo, this kind of changes tend to improve the quality of the sample profile from autofdo.

@Dehao,
we have identified a couple of similar issues where the debug location of a tail-merged instruction is incorrectly set. We already have plans to send a couple of small patches to fix these issues (those would need D24180); in our sample-pgo experiments, this kind of small fixes for hoisted/tail merged instructions tend to have a very positive impact on the quality of the sample profile.

This comment was removed by eric_niebler.

I would worry that this might produce a worse experience for a sanitizer user, for example - but I'm not sure. (the sanitizer user won't have any trail back to why the store in this example is happening - granted, the way the code currently works, they may be told the store is happening in the wrong branch, which isn't great either)

I don't know about the sanitizer user experience. However, based on my experience with sample pgo, this kind of changes tend to improve the quality of the sample profile from autofdo.

@Dehao,
we have identified a couple of similar issues where the debug location of a tail-merged instruction is incorrectly set. We already have plans to send a couple of small patches to fix these issues (those would need D24180); in our sample-pgo experiments, this kind of small fixes for hoisted/tail merged instructions tend to have a very positive impact on the quality of the sample profile.

I also have a related debug-info fix for tail-merging (attached below), but haven't had time to make a unittest and send out for review. It would be great if your patch can cover this case, so that I don't need to prepare a patch for it :)

Could you send us your debug info patches for sample pgo so that we can test them on our workload to see performance impact?

About D24180, we just use -mllvm -use-unknown-locations=true for similar purposes.

Dehao

Index: ../lib/CodeGen/BranchFolding.cpp

  • ../lib/CodeGen/BranchFolding.cpp (revision 280454)

+++ ../lib/CodeGen/BranchFolding.cpp (working copy)
@@ -939,6 +939,11 @@

MachineBasicBlock *MBB = SameTails[commonTailIndex].getBlock();

+ // Remove debug info
+ for (MachineInstr &MI : *MBB)
+ if (!MI.isDebugValue())
+ MI.setDebugLoc(nullptr);
+

// Recompute common tail MBB's edge weights and block frequency.
setCommonTailEdgeWeights(*MBB);

@Dehao,
we have identified a couple of similar issues where the debug location of a tail-merged instruction is incorrectly set. We already have plans to send a couple of small patches to fix these issues (those would need D24180); in our sample-pgo experiments, this kind of small fixes for hoisted/tail merged instructions tend to have a very positive impact on the quality of the sample profile.

I also have a related debug-info fix for tail-merging (attached below), but haven't had time to make a unittest and send out for review. It would be great if your patch can cover this case, so that I don't need to prepare a patch for it :)

Could you send us your debug info patches for sample pgo so that we can test them on our workload to see performance impact?

Sure, I will send you our patches (we have a few fixes - not only the tail-merging - that we can share). If you don't mind, I will send those patches to you on monday as it is almost end of the day here..

About D24180, we just use -mllvm -use-unknown-locations=true for similar purposes.

Interesting, I will look at it.
At the moment I am using D24180 and it seems to be doing a good job with sample pgo. In my experiments, it fixes a few nasty cases where instructions at the top of a basic block are implicitly attributed to the source line for the physically preceding instruction simply because they don't have a debug loc. Anyway, I will explain all the details in the email that I will send to you :-).

Dehao

Index: ../lib/CodeGen/BranchFolding.cpp

  • ../lib/CodeGen/BranchFolding.cpp (revision 280454)

+++ ../lib/CodeGen/BranchFolding.cpp (working copy)
@@ -939,6 +939,11 @@

MachineBasicBlock *MBB = SameTails[commonTailIndex].getBlock();

+ // Remove debug info
+ for (MachineInstr &MI : *MBB)
+ if (!MI.isDebugValue())
+ MI.setDebugLoc(nullptr);
+

// Recompute common tail MBB's edge weights and block frequency.
setCommonTailEdgeWeights(*MBB);

I guess that works well because you specify -use-unknown-locations=true (our patch is almost identical btw).

Cheers,
Andrea

About D24180, we just use -mllvm -use-unknown-locations=true for similar purposes.

Interesting, I will look at it.
At the moment I am using D24180 and it seems to be doing a good job with sample pgo. In my experiments, it fixes a few nasty cases where instructions at the top of a basic block are implicitly attributed to the source line for the physically preceding instruction simply because they don't have a debug loc. Anyway, I will explain all the details in the email that I will send to you :-).

Using -mllvm -use-unknown-locations=true is a superset of D24180. The latter tries to be smarter about where the line-0 attributions are really needed, in order to minimize the size penalty in the debug line table. Also D24180 works for Codeview as well as DWARF.

ping...

Chandler, Eric and Kostya, could you shed some lights on this patch?

Thanks,
Dehao

echristo added inline comments.Sep 6 2016, 6:27 PM
lib/Transforms/Utils/SimplifyCFG.cpp
1256

I think you have a use after free here, IS->eraseFromParent() above.

1256

This needs a comment about the point of what we're doing.

That said while this may help the AFDO type of use case I think it might the debug experience worse for sanitizers/debuggers. For the easy case, take one of the instructions that's being hoisted and make it a load of NULL. If we assert/trap/etc on this then the back trace will give us a fairly unhelpful line in the basic block that doesn't correlate to any of the source that the user wrote.

dblaikie added inline comments.Sep 6 2016, 6:29 PM
lib/Transforms/Utils/SimplifyCFG.cpp
1256

That's my concern as well - but conversely, even if we did pick a location for this, half the time we'd pick the wrong one which would also be confusing for the user (we could diagnose a null dereference that we would describe as coming from the 'if' block, even though the 'else' was taken - the user could easily see a contradiction here that may be quite confusing).

So, dunno what the right call is - just has some complications.

echristo added inline comments.Sep 6 2016, 6:32 PM
lib/Transforms/Utils/SimplifyCFG.cpp
1256

Well, we'd at least pick a line of code that resembled what failed rather than something from another block...

dblaikie added inline comments.Sep 6 2016, 6:35 PM
lib/Transforms/Utils/SimplifyCFG.cpp
1256

Yep.

Alternatively we could use line zero - more correct, technically, but probably no better for most debuggers/tools (& would make the line tables bigger - coming back to Paul's recent patch/direction/discussion)

danielcdh added inline comments.Sep 6 2016, 6:41 PM
lib/Transforms/Utils/SimplifyCFG.cpp
1256

So the impact of this patch (or changing it to line 0) will be:

for debugging/sanitizer, it will make already-bad situation a little worse
for afdo, it will make a very bad situation much better

looks like it's still a win?

andreadb added inline comments.Sep 7 2016, 4:10 AM
lib/Transforms/Utils/SimplifyCFG.cpp
1256

It indeed looks like a win to me.
As David said, the debug location was already wrong in the first place. To me, this is clearly one of those cases where we should use the line zero. That said, I will let Eric/Paul/David decide as I don't claim to be a debug info experert.

echristo edited edge metadata.Sep 7 2016, 9:54 PM

Still need to fix the use after free and add the comment.

That said, also please add a FIXME to use location 0 rather than ignoring the location completely.

Thanks!

-eric

I'm pretty sure DWARF inherently can't attribute the same instruction to two source locations, so I think it is preferable to say "don't know" all the time than to give the wrong answer half the time.
I'd be curious how the sanitizers actually handle the line-0 case.

I'm pretty sure DWARF inherently can't attribute the same instruction to two source locations, so I think it is preferable to say "don't know" all the time than to give the wrong answer half the time.

Right, but I'd prefer an answer that's slightly inaccurate to one that attributes the location to a source line that just doesn't even resemble it :)

I'd be curious how the sanitizers actually handle the line-0 case.

Ditto.

danielcdh updated this revision to Diff 70728.Sep 8 2016, 11:06 AM
danielcdh marked 2 inline comments as done.
danielcdh edited edge metadata.

update

echristo accepted this revision.Sep 8 2016, 11:08 AM
echristo edited edge metadata.

WFM.

-eric

This revision is now accepted and ready to land.Sep 8 2016, 11:08 AM
danielcdh closed this revision.Sep 8 2016, 3:01 PM