[PATCH] D83236: [DWARF] Add cutoff guarding validThroughout to avoid near-quadratic behaviour

Jeremy Morse via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 6 12:54:20 PDT 2020


jmorse created this revision.
jmorse added reviewers: aprantl, probinson, dblaikie, Orlando, vsk.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

Occasionally we see absolutely massive basic blocks, typically in global constructors that are vulnerable to heavy inlining.  When these blocks are dense with DBG_VALUE instructions, we can hit near quadratic complexity in DwarfDebug's validThroughout function. The problem is caused by:

- validThroughout having to step through all instructions in the block to examine their lexical scope, and
- a high proportion of instructions in that block being DBG_VALUEs for a unique variable fragment,

Leading to us stepping through every instruction in the block, for (nearly) each instruction in the block. In the particular sample I'm looking at, there's a block with 120K instructions and maybe two-thirds of them are DBG_VALUEs. Not running validThroughout for this block cuts time in DWARF emission in half (which is many tens of seconds).

By adding this guard, we force variables in this block to use a location list rather than a single-location expression, as shown in the added test . This shouldn't change the meaning of the output DWARF at all: instead we use a less efficient DWARF encoding to avoid a poor-performance code path. In the long term this could be fixed by Orlando's D82129 <https://reviews.llvm.org/D82129> providing enough instruction ordering information to make validThroughouts checks less complex, but we're not there yet.

The testing technique is shamelessly ripped off from D80662 <https://reviews.llvm.org/D80662>. I've used a set of very-large block pointers rather than calling size() each time, because size() isn't constant-time with ilists.

The default setting of  blocks that are over 30,000 instructions long being considered too large isn't determined scientifically; rather, it solves the problem in front of me, and doesn't trigger on a stage2 clang build. Suggestions on a good mechanism to pick this number most welcome.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83236

Files:
  llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
  llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
  llvm/test/DebugInfo/MIR/X86/singlelocation-cutoffs.mir

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D83236.275714.patch
Type: text/x-patch
Size: 7137 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200706/54a7529a/attachment-0001.bin>


More information about the llvm-commits mailing list