hphp/runtime/vm/jit/memelim.cpp
/*
 * If the local doesn't live on the main frame, we can dynamically allocate a
 * bit to represent it here during the initial analysis pass that computes
 * per-block transfer functions.  Currently this is only possible for frames
 * produced by DefInlineFP.
 *
 * The reason this works for locals is that when we deal with memory effects
 * that affect all tracked locations, we flip the entire gen or kill set bits
 * instead of just the ones we have already allocated.  This means transfer
 * functions that were computed before all these bits are allocated will still
 * be correct.
 */
If the local doesn't live on the main frame, we can dynamically allocate a
bit to represent it here during the initial analysis pass that computes
per-block transfer functions.  Currently this is only possible for frames
produced by DefInlineFP.

The reason this works for locals is that when we deal with memory effects
that affect all tracked locations, we flip the entire gen or kill set bits
instead of just the ones we have already allocated.  This means transfer
functions that were computed before all these bits are allocated will still
be correct.
If the local doesn ' t live on the main frame we can dynamically allocate a bit to represent it here during the initial analysis pass that computes per - block transfer functions . Currently this is only possible for frames produced by DefInlineFP . The reason this works for locals is that when we deal with memory effects that affect all tracked locations we flip the entire gen or kill set bits instead of just the ones we have already allocated . This means transfer functions that were computed before all these bits are allocated will still be correct .
FrameBits frame_bits(Global& genv, const SSATmp* fp) {
  if (fp == genv.mainFp) {
    return FrameBits { genv.numMainFpLocals, 0 };
  }
  auto& info = genv.frameBitsMap[fp];
  if (!info) {
    auto const func = fp->inst()->extra<DefInlineFP>()->target;
    info = FrameBits { static_cast<uint32_t>(func->numLocals()),
                       genv.allocatedBits };
    genv.allocatedBits += func->numLocals();
    FTRACE(2, "      alloc [{}, {}) for {}\n",
      info->startIndex,
      info->startIndex + info->numLocals,
      fp->toString());
  }
  return *info;
}
FrameBits frame_bits ( Global & genv , const SSATmp * fp ) { if ( fp == genv . mainFp ) { return FrameBits { genv . numMainFpLocals , 0 } ; } auto & info = genv . frameBitsMap [ fp ] ; if ( ! info ) { auto const func = fp -> inst ( ) -> extra < DefInlineFP > ( ) -> target ; info = FrameBits { static_cast < uint32_t > ( func -> numLocals ( ) ) , genv . allocatedBits } ; genv . allocatedBits += func -> numLocals ( ) ; FTRACE ( 2 , " \n " , info -> startIndex , info -> startIndex + info -> numLocals , fp -> toString ( ) ) ; } return * info ; }
If the local doesn't live on the main frame, we can dynamically allocate a
 bit to represent it here during the initial analysis pass that computes
 per-block transfer functions.
If the local doesn ' t live on the main frame we can dynamically allocate a bit to represent it here during the initial analysis pass that computes per - block transfer functions .