This is an archive of the discontinued LLVM Phabricator instance.

[RemoveRedundantDebugValues] Track registers to efficiently handle many DBG_VALUEs.
Needs ReviewPublic

Authored by rupprecht on Apr 14 2023, 12:51 PM.

Details

Summary

When checking if instructions clobber any locations, we do so by looking at each entry in VariableMap and call MI.modifiesRegister() on that variable. If the size of VariableMap is large, this can be very slow, because modifiesRegister isn't very fast.

Instead, we track just the specified registers, and only call MI.modifiesRegister() for each entry in that much smaller set. If there are no matches, we avoid needing to iterate over VariableMap entirely. If there are any matches, we can then iterate over VariableMap and do the much cheaper equality comparison for registers to decide if remove it.

This brings compilation of a seemingly-simle file from 5 minutes to 10 seconds. The stats added in this patch show the relative sizes of data sets:

$ llc -run-pass=removeredundantdebugvalues /tmp/repro.O3.mir -o /dev/null -stats
===-------------------------------------------------------------------------===
                          ... Statistics Collected ...
===-------------------------------------------------------------------------===

     6 removeredundantdebugvalues - Maximum size of RegisterSet (forward scan)
183077 removeredundantdebugvalues - Maximum size of VariableMap (forward scan)

This patch is purely a compile time improvement. It is not intended to have any visible effect on the output IR.

Diff Detail

Event Timeline

rupprecht created this revision.Apr 14 2023, 12:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 14 2023, 12:51 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
rupprecht requested review of this revision.Apr 14 2023, 12:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 14 2023, 12:51 PM

Trying to get an actual reduction to share in case this isn't the right approach. The source is basically this:

#include <string>
#include <map>

static auto* kFoo = new std::map<std::string, std::string>({
#include "values.inc"
});

where values.inc is a super long list like:

{"key_1", "value_1" },
{"key_2", "value_2" },
{"key_3", "value_3" },
{"key_4", "value_4" },
{"key_5", "value_5" },
{"key_6", "value_6" },
{"key_7", "value_7" },
{"key_8", "value_8" },
{"key_9", "value_9" },
{"key_10", "value_10" },
...

(~3000 lines long)

But it still isn't reproducing like that, so I'm trying to figure out what else is different compared to the internal build.

Thanks for this!

So, currently you are trying to find a counterexample where this does not improve the build time, right?

llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
143
&Reg : ``` instead?
144

an early exit here?