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