Fix HHBBC monotonicity violation
commit3e36529206f4335a044b633bd1d843d6f04cfacd
authorRick Lavoie <rlavoie@fb.com>
Thu, 4 Nov 2021 16:01:41 +0000 (4 09:01 -0700)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Thu, 4 Nov 2021 16:03:24 +0000 (4 09:03 -0700)
treeda09d6c58a46a22a4bf2b613a0afd35e5b224cb1
parent8c7abad3799010f66c097fcbd2d0debdc6dc9a99
Fix HHBBC monotonicity violation

Summary:
When HHBBC attempts to inline interp a function call, and it fails to
obtain a useful type, it attempts to mark that particular call site as
ineligible for further inline interpretation. This keeps us from
wasting time by doing the (expensive) inline interp logic everytime we
examine that call site.

However, the forbid set (which only persists for a single analysis
round) was keyed off of the callee and block id. This is problematic
if you have multiple calls to the same func in the same block. If one
fails, you'll forbid the call site, and the remaining calls will never
attempt to do an inline interp.

This isn't just an optimization issue. It can cause monotonicity
violations. Suppose that we have a block which calls the same func
twice. During the 1st analysis round, we don't have a precise enough
param type for the first call, so we attempt nothing. However we do
have a precise enough param for the second call, so we successfully do
an inline interp and obtain a specialized return type. During the 2nd
analysis round, we now have a better param type for the first call, so
we attempt an inline interp. This fails (for whatever reason), so we
forbid the call site. The second call now skips the inline interp
(because the call site has been forbidden), so now we obtain the more
generic (and worse!) return type. This is a monotonicity violation.

Instead of using the callee and block as the key for the forbid se,
use the CallContext instead. The inline interp logic is already using
this, so we can just move it up somewhat. The CallContext contains the
callee and the arguments, which is what's really important. We want to
forbid/allow a particular call based on the callee's behavior with a
specific set of arguments.

Reviewed By: mofarrell

Differential Revision: D32167129

fbshipit-source-id: 0f21b5471e5f05983fa71d56197b1ef41645e19f
hphp/hhbbc/analyze.h
hphp/hhbbc/context.h
hphp/hhbbc/index.cpp
hphp/hhbbc/index.h
hphp/hhbbc/interp-internal.h
hphp/hhbbc/interp-state.h
hphp/hhbbc/interp.cpp