Scale block prof counts in hot-CFG region selector
commitccdeaf7f15c12ce73c98f25159adbe8295a4eb51
authorRick Lavoie <rlavoie@fb.com>
Tue, 8 Dec 2020 09:14:00 +0000 (8 01:14 -0800)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Tue, 8 Dec 2020 09:16:20 +0000 (8 01:16 -0800)
tree4419fb67af54b7e0c21740616f1556ba97498ea9
parent8c0f525a13a2806fba69605e751d8f085694c579
Scale block prof counts in hot-CFG region selector

Summary:
The prof counts for a block in a region reflect all the times the
block was executed via all paths. However, when we form the region, we
might not include all of those paths. Thus, the block prof counts
might not reflect the expected execution counts in the region we've
formed.

A common way this can manifest is by a block with a single predecessor
have a prof count (much) larger than its predecessor's prof count. A
different (hotter) predecessor, which wasn't included in the region,
was responsible for most of the execution counts. This happens a lot
during inlining, particularily with memoize wrappers. These have
highly polymorphic entry blocks, which then branch to a set of common
blocks. The common blocks appear way hotter than possible, based on
the prof counts of the entry blocks.

This isn't just a quality of optimization issue. This, combined with
how we scale blocks during inlining, can result in blocks with massive
prof counts. So large that they can easily overflow when manipulating
them. For example, vasm-graph-color can overflow them (and trigger
assertions).

Fix this by attempting to scale the blocks' prof counts after we form
the region. We use a simple technique. For each block, sum the
prof-counts of all of its predecessors (even if not in the
region). Also sum the prof-counts of just the predecessors which are
in the region (these prof-counts have their already calculated scale
factor applied). We calculate the ratio between the two, and use that
as the block's scale factor. The idea being, for example, if one
predecessor is responsible for 90% of the sum predecessor counts, and
its not included in the region, we should expect (roughly) that the
block's prof count should be 1/10.

The calculated scale factors are stored in the region, and they are
applied to the raw block prof count when it is requested.

This not only fixes the weight overflow assertions, but (from eye)
seems to produce more reasonable block counts. fixupBlockWeights()
used to accomplish much of the same thing and hid this issue for a
long time.

Reviewed By: ottoni

Differential Revision: D25366308

fbshipit-source-id: ef7a44980e020a6f1fefbf533b77434546016c30
hphp/runtime/vm/jit/region-hot-cfg.cpp
hphp/runtime/vm/jit/region-selection.cpp
hphp/runtime/vm/jit/region-selection.h
hphp/runtime/vm/jit/trans-db.cpp
hphp/test/slow/array/giant-arrays.php.opts [new file with mode: 0644]
hphp/test/slow/jit-time/big-array.php.opts [new file with mode: 0644]