This is an archive of the discontinued LLVM Phabricator instance.

PR26055: Teach LiveDebugValues about lexical scopes.
ClosedPublic

Authored by aprantl on Sep 27 2016, 5:25 PM.

Details

Summary

Contrary to the old LiveDebugVariables pass LiveDebugValues currently doesn't look at the lexical scopes before inserting a DBG_VALUE intrinsic. This means that we often propagate DBG_VALUEs much further down than necessary. This is especially noticeable in large C++ functions with many inlined method calls that all use the same "this"-pointer.

For example, in the following code it makes no sense to propagate the inlined variable a from the first inlined call to f() into any of the subsequent basic blocks, because the variable will always be out of scope:

void sink(int a);
void __attribute((always_inline)) f(int a) { sink(a); }
void foo(int i) {
   f(i);
   if (i)
     f(i);
   f(i);
}

This patch reuses the LexicalScopes infrastructure we have for LiveDebugVariables to take this into account. (I will commit a separate patch to rip out the now dead use of LexicalScopes from LiveDebugVariables.)

The effect on compile time and memory consumption is quite noticeable :-)
I have a benchmark that is a large C++ source with an enormous amount of inlined "this"-pointers that would previously eat >24GiB (most of them for DBG_VALUE intrinsics) and whose compile time was dominated by LiveDebugValues. With this patch applied the memory consumption is 1GiB and 1.7% of the time is spent in LiveDebugValues.

Diff Detail

Event Timeline

aprantl updated this revision to Diff 72737.Sep 27 2016, 5:25 PM
aprantl retitled this revision from to PR26055: Teach LiveDebugValues about lexical scopes..
aprantl updated this object.
aprantl set the repository for this revision to rL LLVM.

Looks good to me .... but I'll let Daniel give the final OK.

lib/CodeGen/LiveDebugValues.cpp
576–577

Was already in the previous code, but isn't this just

bool Changed = ExtendRanges(MF);

dberlin added inline comments.Sep 28 2016, 8:44 AM
lib/CodeGen/LiveDebugValues.cpp
81

Note that this is N^2 as called in a bunch of cases, because each dominates call will iterate over all instructions in the mbb (at least, it looks like it is calling bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB). If not, ignore this)

This is fixable, however:

  1. The data isn't changing, so we could collect and cache the answers for LS, MBB (at O(NBB^2) space cost), but very low practical cost, by using bitvectors. Or, alternatively, caching the list of lexical scopes in the block :).
  1. You could also just store at least the max and min dfsin/out of the scopes in a block, and use it to return answers for at least some queries (in particular, you will avoid all the work for blocks with zero or one lexical scope in them, and the odds probably go down that you will be able to return an answer as the number of unordered scopes in the block goes up).

(or LRU cache any of the above if you are concerned about space cost).

440

Just to make sure i understand:

Though we compute it on the fly repeatedly, the *maximal* killset for a block doesn't really change, right?
(because the set of values not in scope for a given block is computable by just walking all possible values and seeing if they are in scope for the block)
So this is really just computing a given subset of the true maximal killset (presumably to avoid the space storage cost of the maximal killset).

You can always intersect with complement with the larger set, so this is just a time/space tradeoff.
Right?

aprantl updated this revision to Diff 72845.Sep 28 2016, 9:01 AM
aprantl edited edge metadata.
aprantl removed rL LLVM as the repository for this revision.

Address review feedback and further simplify code.

aprantl added inline comments.Sep 28 2016, 10:25 AM
lib/CodeGen/LiveDebugValues.cpp
81

[Quick side note: UserValueScopes is just copied and pasted from LiveDebugVariables (where it is currently dead code because LiveDebugVariables doesn't propagate values beyond BB boundaries any more). With this patch LiveDebugValues is now effectively the only user of LexicalScopes.]

The call to LexicalScopes::dominates is already behind one layer of caching for positive results (LBlocks) which we are likely to hit in the BBs that already carry the value. The call to LexicalBlocks::dominate() is going to happen in the BBs that are direct successors to blocks that carry the value. In many cases the value will not dominate the successor BB and the value will be eliminated. Based on that I think having a very small cache for DL, MBB in UserValueScopes should be sufficient.

440

Correct, the (maximal) killset never changes. I opted for recomputing it here to avoid having to check every value against every basic block.

aprantl updated this revision to Diff 72856.Sep 28 2016, 10:26 AM

Here's a small patch that cached the calls to LexicalBlocks::dominates().
Let me know if you think this is too excessive memory-wise.

dberlin accepted this revision.Sep 28 2016, 10:38 AM
dberlin edited edge metadata.
dberlin added inline comments.
lib/CodeGen/LiveDebugValues.cpp
81

Sounds like it's already pretty reasonable to me.
If it turns out to trigger a perf problem in real code somewhere, we can do it then.

This revision is now accepted and ready to land.Sep 28 2016, 10:38 AM
aprantl closed this revision.Sep 28 2016, 11:00 AM

Thanks! Committed (without DomCache) as r282611.