Drop unused tc_dump_helpers_addrs.txt file
[hiphop-php.git] / hphp / doc / ir.specification
blob7b87ebb3a3a8162c1e2e6a287969293549842d1c
1 *******************************************
2 * HipHop Intermediate Representation (HHIR)
3 *******************************************
7 Introduction
8 ------------
10 The HipHop Intermediate Representation (IR) is a typed, in-memory,
11 static-single-assignment, intermediate-level representation of HHBC programs
12 used for just in time compilation, with these goals:
14   1. Complete. The IR represents a program or program fragment entirely,
15      without reference to HHBC or other upstream forms of the program.
17   2. Type-Safe. Since the IR deals directly with refined types and internal VM
18      types, all operations are typesafe. All instruction parameters have a
19      parameter type P, and all variables have a type S. Given an instruction
20      with source parameter type P and variable type S, S must be equal to or
21      more refined than P (S == P or S <: P).
23   3. Machine Independent. Since this IR is intended to be used in a JIT
24      compiler, it will always be used in a machine specific context.
25      Nevertheless, we rely on machine independence in order to separate
26      concerns and increase portability of the VM. Passes which manipulate IR
27      based on PHP or HHBC semantics should be portable. Passes which deal with
28      machine specifics (such as register allocation) should be done in the
29      lower level IR (vasm). Types are machine independent.
31 The unit of compilation is the IRUnit, which is a collection of Blocks
32 containing IRInstructions that produce and consume SSATmp values. Blocks are
33 single-entry, single-exit sequences of instructions (i.e. basic
34 blocks). Instructions may be annotated with Type parameter which modifies the
35 instruction's behavior, or with additional compile-time constant data (see
36 extra-data.h). Each SSATmp has a Type which describes the set of values it may
37 hold, over its entire live range. Instructions may have side effects, which
38 occur in execution order.
40 The static single assignment form guarantees the following two invariants for a
41 well-formed compilation unit:
43   1. Each SSATmp is assigned to by exactly one IRInstruction.
45   2. Definitions dominate uses. Every path to an IRInstruction using an SSATmp
46      first executes the IRInstruction defining the SSATmp.
48 Any pass that generates or manipulates IR must preserve these invariants,
49 however it is possible and expected for the invariants to be temporarily broken
50 during IR generation or during an optimization pass.
53 Control Flow
54 ------------
56 IRUnits have one entry block, zero or more exit blocks, and zero or more catch
57 blocks. Exit blocks leave the compilation unit in the middle of the same PHP
58 function using one of several instructions that exit a compilation unit
59 (e.g. ReqBindJmp). Catch blocks are blocks that are reachable from exceptional
60 control flow edges, and are executed during unwinding if an exception
61 propagates through the instruction that had it as a `taken' edge.
63 No SSATmps are defined on entry to the main Block.
65 Blocks which are join points may start with a DefLabel with destination
66 SSATmps. In that case, each predecessor must be a Jmp passing a matching number
67 of sources. In this case the Jmp acts as a tail-call, passing arguments the
68 same way a plain call would.
70 Together, the sources of the Jmp instructions and the destinations of the
71 DefLabel instructions act as traditional SSA Phi pseudo-functions; The type of
72 the DefLabel's destination is the type-union of the corresponding sources.
73 Because the Jmp sources are at the ends of blocks, they do not violate the SSA
74 dominator rule (rule 2, above).
77 Types
78 -----
80 For an overview of the HHIR type system, see the "Type System" section in
81 hackers-guide/jit-core.md.
84 SSATmps
85 -------
87 An SSATmp represents a virtual register. Since HHIR uses SSA, an SSATmp may
88 only be assigned to by one instruction. The type of an SSATmp represents the
89 set of values it may hold at the point it is defined, which is invariant over
90 the lifetime of the variable (from the definition point to the last use).
93 IRInstructions
94 --------------
96 An instruction is an executable operation with zero or more inputs (sources),
97 zero or one result (destination), and possible side effects such as accessing
98 memory, doing I/O, and which may branch or throw an exception. Some
99 instructions have a Type parameter which modifies its behavior, or other "extra
100 data" in an arbitrary C++ struct (see extra-data.h).
102 Each instruction has a signature which describes its effect, parameter types,
103 and return type, for example:
105   IsType<T>, D(Bool), S(Cell), NF
107 The first column is the instruction name (and optional Type parameter in <>).
109 The second column describes the result (destination) using one of the D*
110 macros documented in hphp/runtime/vm/jit/ir-opcode.h, or ND for no destination.
112 The third column describes the sources, separated by whitespace, using macros
113 documented in hphp/runtime/vm/jit/ir-opcode.h, or NA if there are no sources.
115 The fourth column contains the flags, described below. The short name of the
116 flag (used in this file) is given first, with the long name that it expands to
117 in hphp/runtime/vm/jit/ir-opcode.cpp in parentheses after it.
121   The instruction has no flags.
123 Er (MayRaiseError)
125   The instruction may raise an error, and must have an edge to a catch block.
127 PRc (ProducesRC)
129   The instruction produces a value with an unconsumed reference that must be
130   consumed, either by DecRefing it or storing it somewhere in memory.
132 CRc (ConsumesRC)
134   The instruction consumes a reference to one or more of its sources, either by
135   decreasing its refcount or storing the reference to memory.
137 T (Terminal)
139   The instruction has no next instruction; it either jumps, returns, or throws.
141 B (Branch)
143   The instruction has a (sometimes optional) taken edge. Instructions that are
144   conditional branches (i.e. a Branch that is not Terminal) will also have a
145   next edge.
147 P (Passthrough)
149   The value of the instruction's dest is the same as one of its inputs; it
150   differs only in the type of the variable, or some other property that doesn't
151   affect the value of the variable itself.
153 MProp (MInstrProp)
155   The instruction may affect the type and/or value of its base operand,
156   operating on object properties.
158 MElem (MInstrElem)
160   The instruction may affect the type and/or value of its base operand,
161   operating on array elements.
164 Instruction set
165 ---------------
167 1. Checks and Asserts
169 Note: Instructions that check boxed types only check that the operand is boxed,
170 and they ignore the type of the value inside the box (the inner type). The
171 inner type is normally checked when the value within the box is about to be
172 loaded, using a separate CheckRefInner instruction.
174 | CheckType<T>, DRefineS(0), S(Gen,Cls), B|P
176   Check that the type of the src S0 is T, and if so copy it to D, and
177   fallthrough. If S0 cannot be proven to be T, branch to block B. Note that
178   this means S0 still /may/ be a subtype of T in block B in some circumstances.
180   Specifically, subtypes of Type::Static may not be checked precisely,
181   depending on the type of the source.  This means the instruction may take the
182   branch in some circumstances even when S0 is a subtype of T, if T has a
183   non-empty intersection with Type::Static.
185   Also note that many types are not supported as the typeParam right now.
187 | CheckNullptr, ND, S(CountedStr,Nullptr), B|CRc
189   If S0 is not a null pointer, branch to block B. This is used to check the
190   return value of a native helper that returns a potentially null StringData*.
192 | AssertType, DRefineS(0), S(Gen,Cls,Ctx), P
194   Assert that the type of S0 is T, copying it to D.
196 | CheckTypeMem<T>, ND, S(PtrToGen), B
198   If the value pointed to by S0 is not type T, branch to the block B.
200 | HintLocInner<T,localId>, ND, S(FramePtr), NF
202   Hint that the inner type of a BoxedCell in localId is likely type T, where T
203   is a subtype of BoxedCell. The type must be guarded on before it is known to
204   be true (via CheckRefInner).
206 | HintStkInner<T,offset>, ND, S(StkPtr), NF
208   Hint that the inner type of the BoxedInitCell on the stack pointed to by S0
209   at offset (in cells) is T. The type must be guarded on before it is known to
210   be true (via CheckRefInner).
212 | HintMBaseInner<T>, ND, NA, NF
214   Hint that the inner type of the BoxedInitCell pointed to by the member base
215   register is T.  The type must be guarded on before it is known to be true
216   (via CheckRefInner).
218 | CheckLoc<T,localId>, ND, S(FramePtr), B
220   Check that type of the given localId on the frame S0 is T; if not, branch to
221   block B.
223 | CheckStk<T,offset>, ND, S(StkPtr), B
225   Check that the type of the cell on the stack pointed to by S0 at offset (in
226   cells) is T; if not, branch to block B.
228 | CheckMBase<T>, ND, S(PtrToGen), B
230   Check that the value pointed to by the member base register S0 has type T; if
231   not, branch to block B.  This is functionally the same as CheckTypeMem.
233 | AssertLoc<T,localId>, ND, S(FramePtr), NF
235   Asserts that type of the supplied local on the frame S0 is T. This is used
236   for local type information, and is similar to CheckLoc except it doesn't
237   imply a runtime check (the assertion must've already been proven to be true)
238   and cannot cause control flow.
240 | AssertStk<T,offset>, ND, S(StkPtr), NF
242   Assert that stack element at `offset' (in cells) from S0 has type T. This is
243   similar to a CheckStk except that it does not imply a runtime check and
244   cannot cause control flow.
246 | AssertMBase<T>, ND, NA, NF
248   Assert that the value pointed to by the member base register has type T.
249   This is similar to a CheckMBase except that it does not imply a runtime check
250   and cannot cause control flow.
252 | CastStk<T,offset>, ND, S(StkPtr), Er
254   Cast the stack element at `offset' (in cells) from S0 to type T.
256 | CastMem<T>, ND, S(PtrToGen), Er
258   Cast the TypedValue at S0 to type T.
260 The following instructions deal with parameter coercion (the standard type
261 conversion for arguments to HNI functions). If parameter coercion fails these
262 functions will throw a TVCoercion exception. They may throw other types of
263 exceptions depending on how coercion is implemented.
265 | CoerceStk<T,offset,fn,argNum>, ND, S(StkPtr), Er
267   Converts the stack slot at offset (in cells) to type T, with the semantics
268   needed for calling a builtin function. May throw a TVCoercionException in the
269   case of failed parameter coercion. The callee is f, and the position of the
270   argument being coerced is argNum.
272 | CoerceMem<T,fn,argNum>, ND, S(PtrToGen), Er
274   Coerces the TypedValue at S0 to type T, with the semantics
275   needed for calling a builtin function. May throw a TVCoercionException in the
276   case of failed parameter coercion. The callee is fn, and the position of the
277   argument being coerced is argNum.
279 | CoerceCellToBool<fn,argNum>, D(Bool), S(Cell), Er
281 | CoerceCellToInt<fn,argNum>,  D(Int), S(Cell), Er
283 | CoerceStrToInt<fn,argNum>,   D(Int), S(Str), Er
285 | CoerceCellToDbl<fn,argNum>,  D(Dbl), S(Cell), Er
287 | CoerceStrToDbl<fn,argNum>,   D(Dbl), S(Str), Er
289   These instructions convert either a Cell or a Str to a primitive type (Bool,
290   Int, Dbl) and return the resulting value. They may throw an exception upon
291   failed type coercion. They are encoded along with callee Func, fn, and the
292   integer position of the argument, argNum, being coerced.
294 | CheckInit, ND, S(Gen), B
296   If S0's type is Uninit, branch to block B.
298 | CheckInitMem, ND, S(PtrToGen), B
300   If the value pointed to by S0 has type Uninit, branch to block B.
302 | CheckCold<TransID>, ND, NA, B
304   Check if the counter associated with translation TransID is cold (i.e. within
305   a fixed threshold). If it's not (i.e. such translation has reached the
306   "hotness threshold"), then branch to block B.
308 | CheckRefs<firstBit,mask,vals>, ND, S(Func) S(Int), B
310   Perform reffiness guard checks. Operands:
312     S0 - function pointer for the frame
313     S1 - num params expected in the func
314     firstBit - first bit to check, must be a multiple of 64
315     mask - mask to check (RefDeps::Record::m_mask entries)
316     vals - values to check (RefDeps::Record::m_vals entries)
318   If any of the checks fail, branch to block B.
320 | EndGuards, ND, NA, NF
322   A no-op at runtime, this instruction serves to mark the end of the initial
323   sequence of guards in a trace.
325 | CheckNonNull, DSubtract(0, Nullptr), S(Nullptr,Func,PtrToGen,TCA,Cls), B
327   If the value in S0 is Nullptr, branch to block B.
329 | AssertNonNull, DSubtract(0, Nullptr), S(Nullptr,CountedStr,Func), P
331   Returns S0, with Nullptr removed from its type. This instruction currently
332   supports a very limited range of types but can be expanded if needed.
334 | CheckClosureStaticLocInit, ND, S(BoxedCell), B
336   Check if the closure static local represented by S0 is initialized, and if
337   not branch to block B.
339 2. Arithmetic
341 | AddInt, D(Int), S(Int) S(Int), NF
343 | SubInt, D(Int), S(Int) S(Int), NF
345 | MulInt, D(Int), S(Int) S(Int), NF
347 | AddIntO, D(Int), S(Int) S(Int), B
349 | SubIntO, D(Int), S(Int) S(Int), B
351 | MulIntO, D(Int), S(Int) S(Int), B
353 | AddDbl, D(Dbl), S(Dbl) S(Dbl), NF
355 | SubDbl, D(Dbl), S(Dbl) S(Dbl), NF
357 | MulDbl, D(Dbl), S(Dbl) S(Dbl), NF
359 | DivDbl, D(Dbl), S(Dbl) S(Dbl), NF
361 | DivInt, D(Int), S(Int) S(Int), NF
363 | Floor, D(Dbl), S(Dbl), NF
365 | Ceil, D(Dbl), S(Dbl), NF
367 | AbsDbl, D(Dbl), S(Dbl), NF
369 | Sqrt, D(Dbl), S(Dbl), NF
371 | AndInt, D(Int), S(Int) S(Int), NF
373 | OrInt, D(Int), S(Int) S(Int), NF
375 | XorInt, D(Int), S(Int) S(Int), NF
377 | Shl, D(Int), S(Int) S(Int), NF
379 | Shr, D(Int), S(Int) S(Int), NF
381   Double arithmetic, integer arithmetic, and integer bitwise operations.
382   Performs the operation described by the opcode name on S0 and S1, and puts
383   the result in D.
385   Undefined behavior occurs if Mod is given a divisor of zero, or if the
386   divisor is -1 and the dividend is the minimum representable integer.
388   AbsDbl computes the absolute value of a double-precision value.
390   DivDbl conforms to IEEE 754. In particular, division by zero returns +/- INF
391   or NAN depending on the dividend; and should the result of a division be zero
392   the sign will follow the normal sign rules for division.
394   DivInt will perform integer division of S1 by S0. S0 should not be zero and
395   must divide S1.
397   Note that Shr is an arithmetic right shift: The MSB is sign-extended.
399   Floor and Ceil will return an integral value not greater, or not less
400   than their input respectively. Their use requires SSE 4.1, availability
401   should be checked before they are emitted.
403   AddIntO, SubIntO, MulIntO perform integer arithmetic on S0 and S1, but will
404   branch to block B on integer overflow.
406 | XorBool, D(Bool), S(Bool) S(Bool), NF
408   Logical XOR of the two sources. (Note that && and || do not have
409   corresponding opcodes because they're handled at the bytecode level, to
410   implement short-circuiting.)
412 | Mod, D(Int), S(Int) S(Int), NF
414   Compute S0 mod S1. If S1 is -1 or 0 the results are undefined.
417 3. Type conversions
419 To array conversions:
421 | ConvBoolToArr,                D(Arr), S(Bool),                         PRc
423 | ConvDblToArr,                 D(Arr), S(Dbl),                          PRc
425 | ConvIntToArr,                 D(Arr), S(Int),                          PRc
427 | ConvObjToArr,                 D(Arr), S(Obj),                   Er|PRc|CRc
429 | ConvStrToArr,                 D(Arr), S(Str),                      PRc|CRc
431 | ConvVecToArr,                 D(Arr), S(Vec),                      PRc|CRc
433 | ConvDictToArr,                D(Arr), S(Dict),                     PRc|CRc
435 | ConvKeysetToArr,              D(Arr), S(Keyset),                   PRc|CRc
437 | ConvCellToArr,                D(Arr), S(Cell),                  Er|PRc|CRc
440 To vec conversions:
442 | ConvArrToVec,                 D(Vec), S(Arr),                   Er|PRc|CRc
444 | ConvDictToVec,                D(Vec), S(Dict),                     PRc|CRc
446 | ConvKeysetToVec,              D(Vec), S(Keyset),                   PRc|CRc
448 | ConvObjToVec,                 D(Vec), S(Obj),                   Er|PRc|CRc
451 To dict conversions:
453 | ConvArrToDict,                D(Dict), S(Arr),                  Er|PRc|CRc
455 | ConvVecToDict,                D(Dict), S(Vec),                     PRc|CRc
457 | ConvKeysetToDict,             D(Dict), S(Keyset),                  PRc|CRc
459 | ConvObjToDict,                D(Dict), S(Obj),                  Er|PRc|CRc
462 To keyset conversions:
464 | ConvArrToKeyset,              D(Keyset), S(Arr),                Er|PRc|CRc
466 | ConvVecToKeyset,              D(Keyset), S(Vec),                Er|PRc|CRc
468 | ConvDictToKeyset,             D(Keyset), S(Dict),               Er|PRc|CRc
470 | ConvObjToKeyset,              D(Keyset), S(Obj),                Er|PRc|CRc
473 To bool conversions:
475 | ConvArrToBool,               D(Bool), S(Arr),                           NF
477 | ConvDblToBool,               D(Bool), S(Dbl),                           NF
479 | ConvIntToBool,               D(Bool), S(Int),                           NF
481 | ConvStrToBool,               D(Bool), S(Str),                           NF
483 | ConvObjToBool,               D(Bool), S(Obj),                           NF
485 | ConvCellToBool,              D(Bool), S(Cell),                          NF
487 To double conversions:
489 | ConvArrToDbl,                 D(Dbl), S(Arr),                           NF
491 | ConvBoolToDbl,                D(Dbl), S(Bool),                          NF
493 | ConvIntToDbl,                 D(Dbl), S(Int),                           NF
495 | ConvObjToDbl,                 D(Dbl), S(Obj),                           Er
497 | ConvStrToDbl,                 D(Dbl), S(Str),                           NF
499 | ConvResToDbl,                 D(Dbl), S(Res),                           NF
501 | ConvCellToDbl,                D(Dbl), S(Cell),                          Er
504 To int conversions:
506 | ConvBoolToInt,                D(Int), S(Bool),                          NF
508 | ConvDblToInt,                 D(Int), S(Dbl),                           NF
510 | ConvObjToInt,                 D(Int), S(Obj),                           Er
512 | ConvStrToInt,                 D(Int), S(Str),                           NF
514 | ConvResToInt,                 D(Int), S(Res),                           NF
516 | ConvCellToInt,                D(Int), S(Cell),                          Er
519 To object conversions:
521 | ConvCellToObj, D(Obj), S(Cell), Er|CRc|PRc
524 To string conversions:
526 | ConvDblToStr,                 D(Str), S(Dbl),                          PRc
528 | ConvIntToStr,                 D(Str), S(Int),                          PRc
530 | ConvObjToStr,                 D(Str), S(Obj),                       PRc|Er
532 | ConvResToStr,                 D(Str), S(Res),                       PRc|Er
534 | ConvCellToStr,                D(Str), S(Cell),                      PRc|Er
537   All the above opcodes convert S0 from its current type to the destination
538   type, according to the PHP semantics of such a conversion.
540 | ConvClsToCctx, D(Cctx), S(Cls), NF
542   Convert a class to a class context (i.e. the class with a 1 or'd into the low
543   bit).
545 | OrdStr,                       D(Int), S(Str),                           NF
547   Convert the first byte in a string to an unsigned integer.
548   Intended as an optimization for ord($str)
550 | OrdStrIdx,                    D(Int), S(Str) S(Int),                    Er
552   Convert the character at position S1 in base string S0 to an unsigned
553   integer.  Raises a notice if the position is out of bounds.
554   Intended as an optimization for ord($str[$idx]).
556 | ChrInt,                      D(StaticStr), S(Int),                      NF
558   Convert the integer S0 to a the one character string with ascii code
559   S0 & 255.
561 4. Boolean predicates
563 | GtInt,                       D(Bool), S(Int) S(Int),                    NF
565 | GteInt,                      D(Bool), S(Int) S(Int),                    NF
567 | LtInt,                       D(Bool), S(Int) S(Int),                    NF
569 | LteInt,                      D(Bool), S(Int) S(Int),                    NF
571 | EqInt,                       D(Bool), S(Int) S(Int),                    NF
573 | NeqInt,                      D(Bool), S(Int) S(Int),                    NF
575 | CmpInt,                      D(Int),  S(Int) S(Int),                    NF
577   Perform 64-bit integer comparisons.
579 | GtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
581 | GteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
583 | LtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
585 | LteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
587 | EqDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
589 | NeqDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
591 | CmpDbl,                      D(Int),  S(Dbl) S(Dbl),                    NF
593   Perform comparisons of doubles. Comparisons that are unordered according to
594   IEEE 754 (such as when at least one operand is NaN) result in false.
596 | GtStr,                       D(Bool), S(Str) S(Str),                    NF
598 | GteStr,                      D(Bool), S(Str) S(Str),                    NF
600 | LtStr,                       D(Bool), S(Str) S(Str),                    NF
602 | LteStr,                      D(Bool), S(Str) S(Str),                    NF
604 | EqStr,                       D(Bool), S(Str) S(Str),                    NF
606 | NeqStr,                      D(Bool), S(Str) S(Str),                    NF
608 | SameStr,                     D(Bool), S(Str) S(Str),                    NF
610 | NSameStr,                    D(Bool), S(Str) S(Str),                    NF
612 | CmpStr,                      D(Int),  S(Str) S(Str),                    NF
614   Performs comparison of strings using PHP semantics.
616 | GtStrInt,                    D(Bool), S(Str) S(Int),                    NF
618 | GteStrInt,                   D(Bool), S(Str) S(Int),                    NF
620 | LtStrInt,                    D(Bool), S(Str) S(Int),                    NF
622 | LteStrInt,                   D(Bool), S(Str) S(Int),                    NF
624 | EqStrInt,                    D(Bool), S(Str) S(Int),                    NF
626 | NeqStrInt,                   D(Bool), S(Str) S(Int),                    NF
628 | CmpStrInt,                   D(Int),  S(Str) S(Int),                    NF
630   Performs comparison of strings with integers using PHP semantics.
632 | GtBool,                      D(Bool), S(Bool) S(Bool),                  NF
634 | GteBool,                     D(Bool), S(Bool) S(Bool),                  NF
636 | LtBool,                      D(Bool), S(Bool) S(Bool),                  NF
638 | LteBool,                     D(Bool), S(Bool) S(Bool),                  NF
640 | EqBool,                      D(Bool), S(Bool) S(Bool),                  NF
642 | NeqBool,                     D(Bool), S(Bool) S(Bool),                  NF
644 | CmpBool,                     D(Int),  S(Bool) S(Bool),                  NF
646   Performs comparison of booleans.
648 | GtObj,                       D(Bool), S(Obj) S(Obj),                    Er
650 | GteObj,                      D(Bool), S(Obj) S(Obj),                    Er
652 | LtObj,                       D(Bool), S(Obj) S(Obj),                    Er
654 | LteObj,                      D(Bool), S(Obj) S(Obj),                    Er
656 | EqObj,                       D(Bool), S(Obj) S(Obj),                    Er
658 | NeqObj,                      D(Bool), S(Obj) S(Obj),                    Er
660 | SameObj,                     D(Bool), S(Obj) S(Obj),                    NF
662 | NSameObj,                    D(Bool), S(Obj) S(Obj),                    NF
664 | CmpObj,                      D(Int),  S(Obj) S(Obj),                    Er
666   Perform comparison of objects using PHP semantics. All versions except for
667   SameObj and NSameObj may re-enter the VM and therefore may throw
668   exceptions. SameObj and NSameObj never re-enter or throw.
670 | GtArr,                       D(Bool), S(Arr) S(Arr),                    Er
672 | GteArr,                      D(Bool), S(Arr) S(Arr),                    Er
674 | LtArr,                       D(Bool), S(Arr) S(Arr),                    Er
676 | LteArr,                      D(Bool), S(Arr) S(Arr),                    Er
678 | EqArr,                       D(Bool), S(Arr) S(Arr),                    Er
680 | NeqArr,                      D(Bool), S(Arr) S(Arr),                    Er
682 | SameArr,                     D(Bool), S(Arr) S(Arr),                    NF
684 | NSameArr,                    D(Bool), S(Arr) S(Arr),                    NF
686 | CmpArr,                      D(Int),  S(Arr) S(Arr),                    Er
688   Perform comparison of arrays using PHP semantics. All versions except for
689   SameArr and NSameArr may re-enter the VM and therefore may throw
690   exceptions. SameArr and NSameArr never re-enter or throw.
692 | GtVec,                       D(Bool), S(Vec) S(Vec),                    Er
694 | GteVec,                      D(Bool), S(Vec) S(Vec),                    Er
696 | LtVec,                       D(Bool), S(Vec) S(Vec),                    Er
698 | LteVec,                      D(Bool), S(Vec) S(Vec),                    Er
700 | EqVec,                       D(Bool), S(Vec) S(Vec),                    Er
702 | NeqVec,                      D(Bool), S(Vec) S(Vec),                    Er
704 | SameVec,                     D(Bool), S(Vec) S(Vec),                    NF
706 | NSameVec,                    D(Bool), S(Vec) S(Vec),                    NF
708 | CmpVec,                      D(Int),  S(Vec) S(Vec),                    Er
710   Perform comparison of vecs. All versions except for SameVec and NSameVec may
711   re-enter the VM and therefore may throw exceptions. SameVec and NSameVec
712   never re-enter or throw.
714 | EqDict,                      D(Bool), S(Dict) S(Dict),                  Er
716 | NeqDict,                     D(Bool), S(Dict) S(Dict),                  Er
718 | SameDict,                    D(Bool), S(Dict) S(Dict),                  NF
720 | NSameDict,                   D(Bool), S(Dict) S(Dict),                  NF
722   Perform comparison of dicts. EqDict and NeqDict may re-enter the VM and
723   therefore may throw exceptions. SameDict and NSameDict never re-enter or
724   throw. Relational comparisons for dicts are not supported.
726 | EqKeyset,                    D(Bool), S(Keyset) S(Keyset),              NF
728 | NeqKeyset,                   D(Bool), S(Keyset) S(Keyset),              NF
730 | SameKeyset,                  D(Bool), S(Keyset) S(Keyset),              NF
732 | NSameKeyset,                 D(Bool), S(Keyset) S(Keyset),              NF
734   Perform comparison of keysets. As keysets can only contain ints and strings,
735   comparisons never re-enter or throw. Relational comparisons for keysets are
736   not supported.
738 | GtRes,                       D(Bool), S(Res) S(Res),                    NF
740 | GteRes,                      D(Bool), S(Res) S(Res),                    NF
742 | LtRes,                       D(Bool), S(Res) S(Res),                    NF
744 | LteRes,                      D(Bool), S(Res) S(Res),                    NF
746 | EqRes,                       D(Bool), S(Res) S(Res),                    NF
748 | NeqRes,                      D(Bool), S(Res) S(Res),                    NF
750 | CmpRes,                      D(Int),  S(Res) S(Res),                    NF
752   Perform comparison of resources using PHP semantics. Resource comparisons
753   never re-enter or throw.
755 | EqCls,                       D(Bool), S(Cls) S(Cls),                    NF
757   Checks if two Class values are equal.
759 | EqFunc,                      D(Bool), S(Func) S(Func),                  NF
761   Checks if two Func values are equal.
763 | EqStrPtr,                    D(Bool), S(Str) S(Str),                    NF
765   Checks if two string values represent the same underlying string. That is,
766   that they point at the same underlying storage.
768 | EqArrayDataPtr,              D(Bool), S(ArrLike) S(ArrLike),            NF
770   Checks if the two arguments represent the same underlying ArrayData. That is,
771   that they point at the same underlying storage.
773 | ProfileInstanceCheck, ND, C(StaticStr), NF
775   Profile that S0 has been used as the RHS of an instance check.
777 | InstanceOf, D(Bool), S(Cls) S(Cls|Nullptr), NF
779   Sets D based on whether S0 is a descendant of the class, interface, or trait
780   in S1. (Note that this is always false for a trait). S1 may be null at
781   runtime if the class is not defined.
783 | InstanceOfIface, D(Bool), S(Cls) CStr, NF
785   Fast path for interface checks. Sets D based on whether S0 implements S1, but
786   S1 must be a unique interface. This should only be used in repo-authoritative
787   mode.
789 | InstanceOfIfaceVtable<iface>, D(Bool), S(Cls), NF
791   Faster path for interface checks. Sets D based on whether S0 implements
792   iface, which must be a unique interface with an assigned vtable slot.
794 | ExtendsClass<cls,strictLikely>, D(Bool), S(Cls), NF
796   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
797   of cls, where cls must be a unique class that is not an interface or a trait.
799   If strictLikely is true, optimize for the case where S0 is not equal to S1.
801 | InstanceOfBitmask,           D(Bool), S(Cls) CStr,                      NF
803 | NInstanceOfBitmask,          D(Bool), S(Cls) CStr,                      NF
805   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
806   of the class named by S1, where S1 must have a bit allocated for it in the
807   fast instance check bitvector (see class.h).
809 | InterfaceSupportsArr,        D(Bool), S(Str), NF
811 | InterfaceSupportsVec,        D(Bool), S(Str), NF
813 | InterfaceSupportsDict,       D(Bool), S(Str), NF
815 | InterfaceSupportsKeyset,     D(Bool), S(Str), NF
817 | InterfaceSupportsStr,        D(Bool), S(Str), NF
819 | InterfaceSupportsInt,        D(Bool), S(Str), NF
821 | InterfaceSupportsDbl,        D(Bool), S(Str), NF
823   Returns whether t instanceof S0 returns true when t is of the given type.
825 | HasToString, D(Bool), S(Obj), NF
827   Returns whether the object S0 has a toString method.
829 | IsType<T>, D(Bool), S(Cell), NF
831   Sets D to true iff S0 holds a value that is of type T. T must not be a
832   specialized type.
834 | IsNType<T>, D(Bool), S(Cell), NF
836   Sets D to true iff S0 holds a value that is not of type T. T must not be a
837   specialized type.
839 | IsTypeMem<T>, D(Bool), S(PtrToGen), NF
841   Sets D to true iff the value referenced by S0 is of type T. T must not be a
842   specialized type.
844   The value in S0 must not be a pointer into the evaluation stack or frame
845   locals.
847 | IsNTypeMem<T>, D(Bool), S(PtrToGen), NF
849   Sets D to true iff the value referenced by S0 is not of type T. T must not be
850   a specialized type.
852 | IsScalarType, D(Bool), S(Cell), NF
854   Returns true if S0 is of type Int, Bool, Dbl or Str. Returns false otherwise.
856 | IsWaitHandle, D(Bool), S(Obj), NF
858   Sets D to true iff S0 is a subclass of WaitHandle.
860 | IsCol, D(Bool), S(Obj), NF
862   Sets D to true iff S0 is a collection.
865 5. Branches
867 | JmpZero,                          ND, S(Int,Bool),                     B
869 | JmpNZero,                         ND, S(Int,Bool),                     B
871   Conditionally jump to based on S0.
873 | JmpSSwitchDest, ND, S(TCA) S(StkPtr) S(FramePtr), T
875   Jump to the target of a sswitch statement, leaving the region, where the
876   target TCA is S0.
878 | JmpSwitchDest, ND, S(Int) S(StkPtr) S(FramePtr), T
880   Jump to the target of a switch statement, leaving the region, using table
881   metadata <JmpSwitchData> and index S0, which must be a valid index in the
882   jump table.
884 | ProfileSwitchDest<handle,nCases>, ND, S(Int), NF
886   Profile a switch statement target.
888 | CheckSurpriseFlags, ND, S(FramePtr,StkPtr), B
890   Tests the implementation-specific surprise flags. If they're true, branches
891   to block B. This is done by comparing an evaluation stack pointer to the RDS
892   stackLimitAndSurprise word. Note that in a resumed, the frame pointer is not
893   pointing into the eval stack, so S0 should be a StkPtr in that case.
895 | ReturnHook, ND, S(FramePtr) S(Gen), Er
897   Surprise flag hook for function returns.
899 | SuspendHookE, ND, S(FramePtr) S(FramePtr) S(Obj), Er
901   Surprise flag hook for suspending eagerly executing async functions or
902   generators.  Decrefs S2 if it throws an exception.
904 | SuspendHookR, ND, S(FramePtr) S(Obj|Nullptr), Er
906   Surprise flag hook for suspending resumed async functions or generators.  For
907   generators, the second parameter should be Nullptr.
909 | Unreachable, ND, NA, T
911   Indicates an unreachable code path. Any instructions that are post-dominated
912   by an Unreachable may be treated as unreachable by the optimizer, and the
913   behavior of a program that attempts to execute an Unreachable is undefined.
915 | EndBlock, ND, NA, T
917   Halt execution, without implying anything about the reachability of
918   instructions preceding this. Intended for use in internal tests or other code
919   not meant to be executed.
921 | Jmp, ND, SVar(Top), B|T
923   Unconditional jump to block B. In the second form, the target block must
924   start with a DefLabel with the same number of destinations as Jmp's number of
925   sources. Jmp parallel-copies its sources to the DefLabel destinations.
927 | DefLabel, DMulti, NA, NF
929   DefLabel defines variables received from a previous Jmp. A DefLabel with zero
930   destinations is a no-op, and the predecessor blocks may not necessarily end
931   in Jmp. A DefLabel with one or more destinations may only be reached by a Jmp
932   instruction with the same number of sources. Ordinary branch instructions may
933   not pass values to a DefLabel.
935 | Select, DUnion(1,2), S(Bool,Int) S(Top) S(Top), NF
937   If S0 is true/non-zero, return S1, otherwise return S2.
940 6. Reference manipulation
942 | Box, D(BoxedInitCell), S(Cell), CRc|PRc
944   Box S0 and put the resulting BoxedInitCell in D. If S0 is Uninit, then
945   InitNull will be boxed instead.
947 | UnboxPtr, DUnboxPtr, S(PtrToGen), NF
949   If S0 points to a cell that is KindOfRef, dereference the pointer in the
950   TypedValue and return a pointer to the inner-cell in D.
952 | BoxPtr, DBoxPtr, S(PtrToGen), NF
954   Boxes the TypeValue that S0 points to if it is not boxed. The result D points
955   to the same TypedValue as S0 but has a more refined type.
957   S0 may not already point into a RefData (due to VM invariants), although the
958   IR type system does not enforce it.
961 7. Loads
963 | LdStk<T,offset>, DParamMayRelax(Gen), S(StkPtr), NF
965   Loads from S0 at offset (in cells), and puts the value in D as type T.
967 | LdLoc<T,localId>, DParamMayRelax(Gen), S(FramePtr), NF
969   Loads local slot localId from the frame S0 and puts the value in D as type T.
971 | LdLocPseudoMain<T,localId>, DParam(Gen), S(FramePtr), B
973   Loads local number localId from frame S0 and puts the value in D if the
974   local's type is a subtype of T. If the local's type is not a subtype of T,
975   then the load does not happen, and this instruction branches to B. This
976   instruction is used for loading locals in pseudo-mains, where they can alias
977   globals.
979 | LdClsRef<T,slot>, DParamMayRelax(Cls), S(FramePtr), NF
981   Loads class-ref from slot `slot` in frame S0 and puts the value in D as type
982   T. T must be a sub-type of TCls.
984 | LdStkAddr<T,offset>, D(PtrToStkGen), S(StkPtr), NF
986   Loads the address of the stack slot given by the pointer in S0 at the offset
987   (in cells). T must be a subtype of PtrToStkGen.
989 | LdLocAddr<localId>, D(PtrToFrameGen), S(FramePtr), NF
991   Loads the address of the local slot localId from the frame S0 into D.
993 | LdRDSAddr<T,RDSHandle>, DParam(PtrToGen), NA, NF
995   Load the address of a Gen that lives at the specified RDS handle. The type
996   param must be a subtype of PtrToGen.
998 | LdVectorBase, D(PtrToMembCell), S(Obj), NF
1000 | LdPairBase, D(PtrToMembCell), S(Obj), NF
1002   Loads the base pointer to an array of Cells from the given collection
1003   instance in S0.
1005 | LdMem<T>, DParam(Gen), S(PtrToGen), NF
1007   Loads from S0 and puts the value in D.
1009 | LdContField<T>, DParam(Gen), S(Obj) C(Int), NF
1011   Loads a property from the object referenced by S0 at the offset given by S1
1012   and puts the value in D. S0 must be a Generator.
1014 | LdElem, D(Cell), S(PtrToCell) S(Int), NF
1016   Loads the element at index S1 from the base pointer in S0. The index in S1 is
1017   the number of bytes from the base in S0.
1019 | LdColVec, D(Vec), S(Obj), NF
1021   Load the vec array backing a collection instance in S0, which must be a
1022   Vector or ImmVector, and that specific object type must be known at compile
1023   time.
1025 | LdColArray, D(Arr), S(Obj), NF
1027   Load the array backing a collection instance in S0, which must be a Map, Set,
1028   ImmMap, or ImmSet, and that specific object type must be known at compile
1029   time.
1031 | CheckRefInner<T>, ND, S(BoxedCell), B
1033   TODO(#2939547): this should take BoxedInitCell
1035   Check that the inner type of the boxed cell in S0 is T, and if not take the
1036   branch to B.
1038 | LdRef<T>, DParam(Cell), S(BoxedCell), NF
1040   TODO(#2939547): this should take BoxedInitCell
1042   Loads the value held in the box referenced by S0 and puts the value in D. The
1043   inner type of S0 must be a subtype of T (usually ensured with a previous
1044   CheckRefInner).
1046 | LdCtx, DCtx, S(FramePtr), NF
1048   Loads into D the value of the m_this/m_cls field out of the frame pointer S0,
1049   which must be a frame for the function in the LdCtx's marker. The result
1050   could be either an object representing the this pointer or a class context.
1052 | LdCctx, DCtx, S(FramePtr), NF
1054   Loads into D the value of the m_cls field out of the frame pointer S0. The
1055   compiler should generate this only if it can prove that the frame does not
1056   contain a nullptr or $this pointer.
1058 | LdClosure<T>, DParam(Ctx), S(FramePtr), NF
1060   Loads into D the value of the m_this/m_cls field out of the frame pointer S0.
1061   The compiler should generate this only if it can prove that the frame context
1062   is a closure object of type T.  Unlike LdCtx and LdCctx, there are no special
1063   rules about the relative positions of LdClosure and InitCtx instructions.
1065 | CheckCtxThis, ND, S(Ctx), B
1067   Check that the context (m_this or m_cls) in S0 is a non-null $this
1068   pointer. If not, branch to B.
1070 | LdClsCtx, DCtxCls, S(Ctx), NF
1072   Loads into D the class representing the current context. Extracts the class
1073   from S0, which can be either the this pointer or the context class.
1075 | LdClsCctx, DCtxCls, S(Cctx), NF
1077   Loads into D the class representing the current context. Extracts the class
1078   from the S0, which is a context class.
1080 | LdClsCtor, D(Func), S(Cls) S(FramePtr), Er
1082   Loads into D the constructor of class S0. If the constructor cannot be called
1083   from the context in S1, raise an error.
1085 | DefCls, D(Cls), S(Int), Er
1087   Define the class corresponding to PreClass S0 in the current unit.
1089 | DefConst<T>, DParam(Top), NA, NF
1091   Define a constant value of type T. D is presumed to be globally available and
1092   the DefConst instruction will not actually appear in the IR instruction
1093   stream.
1095 | Conjure<T>, DParam(Top), NA, NF
1097   Define a value of type T. This instruction aborts at runtime; it is meant to
1098   be used in tests or code that is known to be unreachable.
1100 | ConjureUse, ND, S(Gen), NF
1102   Define a "use" of S0 effectively keeping the value alive. As with Conjure it
1103   should not appear in reachable code.
1105 | LdCls, D(Cls), S(Str) C(Cls), Er
1107   Loads the class named S0 in the context of the class S1. Invokes autoload and
1108   may raise an error if the class is not defined. The explicit context
1109   parameter allows the compiler to simplify this instruction to a DefConst in
1110   some cases. If S0 is constant, this instruction may be simplified to a
1111   LdClsCached.
1113 | LdClsCached, D(Cls), CStr, Er
1115   Loads the class named S0 via the RDS. Invokes autoload and may raise an error
1116   if the class is not defined.
1118 | LdClsCachedSafe, D(Cls), CStr, B
1120   Loads the class whose name is S0 out of the RDS. If the class is not defined,
1121   branch to B.
1123 | LdClsInitData, D(PtrToClsInitCell), S(Cls), NF
1125   Loads the pointer to the property initializer array for class S0.
1127 | LookupClsRDS, D(Cls|Nullptr), S(Str), NF
1129   Lookup the cached-class RDS handle for a given class name. Dereference that
1130   handle and return the associated Class, or null if not present.
1132 | LdCns, DCns, CStr, B|PRc
1134   Load the constant named S0, branching to B if isn't present.
1136 | LookupCns<T,constName>,   DCns, CStr, Er|PRc
1138 | LookupCnsE<T,constName>,  DCns, CStr, Er|PRc
1140   Load a constant via the RDS. Raises an undefined constant notice if the
1141   constant cannot be defined.  The E variant will instead throw a fatal error if
1142   it cannot define the constant.  These should only be executed if LdCns on the
1143   same constant has failed.
1145 | LookupCnsU<T,constName,fallbackName>, DCns, CStr CStr, Er|PRc
1147   Load an unqualified constant via the RDS, first by trying constName, then by
1148   trying fallbackName.  Raises a notice if neither can be found.  Should only
1149   be executed if LdCns on the same constant has failed.
1151 | LdClsCns<className,constantName>, D(PtrToGen), NA, B
1153   Load the address of the constant 'constantName' for the class 'className' in
1154   RDS. If not initialized, branch to B.
1156 | LdClsMethodFCacheFunc<clsName,methodName>, D(Func), NA, B
1158   Loads the target cache entry for a forwarding call to clsName::methodName.
1159   If the method does not exist, or the cache hasn't been filled yet, branch to
1160   B.
1162 | LookupClsMethodFCache<clsName,methodName>,
1163 |    D(Func|Nullptr), C(Cls) S(FramePtr),
1164 |    Er
1166   Lookup clsName::methodName in the forwarding class method cache. S0 should be
1167   the Class named by clsName and S1 should be the current vm frame pointer. May
1168   return Nullptr if lookup fails using a subset of the required lookup paths,
1169   indicating that a more complete lookup path should be taken. May throw if the
1170   method does not exist.
1172 | CheckFuncStatic, ND, S(Func), B
1174   Tests to see if Func::m_attrs & AttrStatic, and if so branch to B.
1175   This instruction is intended to be used in forwarding calls, where we know
1176   that Func is not a closure.
1178 | FwdCtxStaticCall, D(Cctx), S(Ctx), NF
1180   If S0 is an object, this opcode returns S0's class with the low bit set
1181   (i.e., as a Cctx). Otherwise this instruction returns S0.
1183 | LdClsMethodCacheFunc<clsName,methodName>, D(Func), NA, B
1185   Loads the target cache entry for the method clsName::methodName. If the
1186   method does not exist or the cache hasn't been filled yet, branch to B.
1188 | LdClsMethodCacheCls<clsName,methodName>, D(Cctx), NA, NF
1190   Loads the target cache class context entry for a call to clsName::methodName
1191   from the current context. This instruction must only be used when the value
1192   is known to not be empty (i.e., LdClsMethodCacheFunc must have succeeded, or
1193   LookupClsMethodCache returned a non-null value).
1195 | LookupClsMethodCache<clsName,methodName>, D(Func|Nullptr),
1196 |                                           S(FramePtr),
1197 |                                           Er
1199   Lookup a function in the class method targetcache. The class name and method
1200   name are clsName and methodName, respectively. S0 is the current vm frame
1201   pointer. Returns Nullptr if the method cannot be found using a subset of the
1202   required lookup paths, indicating that a more complete lookup path should be
1203   taken. May throw if the method does not exist.
1205 | LdIfaceMethod<vtableIdx,methodIdx>, D(Func), S(Cls), NF
1207   Load the Func* at methodIdx from the vtable at vtableIdx in S0.
1209 | LdFuncVecLen, D(Int), S(Cls,Cctx), NF
1211   Load the funcVecLen field from S0.
1213 | LdClsMethod, D(Func), S(Cls,Cctx) C(Int), NF
1215   Load a Func* off of the class method table for S0, at offset S1 (in method
1216   slots).
1218 | LookupClsMethod<calleeAROffset,forward>,
1219 |   ND,
1220 |   S(Cls) S(Str) S(StkPtr) S(FramePtr),
1221 |   Er
1223   Store a pointer to a class method into an activation record. S0 points to the
1224   class, S1 is the method name, S2 is a stack pointer that has an activation
1225   record to modify at `spToActRecOffset', and S3 is a pointer to the current
1226   frame (used to get the context). `forward` indicates if we should forward the
1227   current context. May throw or fatal if method is not accessible.
1229 | LdPropAddr<T,offset>, DParamPtr(Prop), S(Obj), NF
1231   Load the address of the object property for S0 + `offset' (in bytes).  T must
1232   be a subtype of PtrToPropGen.
1234 | LdGblAddr, D(PtrToGblGen), S(Str), B
1236   Loads a pointer to a global. S0 is the global's name. Branches to B if the
1237   global is not defined.
1239 | LdGblAddrDef, D(PtrToGblGen), S(Str), NF
1241   Loads a pointer to a global. S0 is the global's name. Defines the global if
1242   it is not already defined.
1244 | LdClsPropAddrOrNull, D(PtrToSPropGen|Nullptr),
1245 |                      S(Cls) S(Str) C(Cls),
1246 |                      Er
1248   Loads a pointer to a static class property. S0 points to the class, S1 is the
1249   property name, and S2 is the class representing the context of the code
1250   accessing the property. If class S0 does not have a visible and accessible
1251   static property named S1, then nullptr is returned.
1253 | LdClsPropAddrOrRaise, D(PtrToSPropGen), S(Cls) S(Str) C(Cls), Er
1255   Loads a pointer to a static class property. S0 points to the class, S1 is the
1256   property name, and S2 is the class representing the context of the code
1257   accessing the property. If class S0 does not have a visible and accessible
1258   static property named S1, throw a fatal error.
1260 | LdObjMethod<offset,methodName,fatal>, ND, S(Cls) S(StkPtr), Er
1262   Stores a pointer to an object's method into an activation record. S0 points
1263   to the object's class, S1 has the pre-live activation record at `offset'.
1264   Caches the mapping in the target cache. If `fatal' is true, raises a fatal if
1265   the class does not have an accessible method with the given name and does not
1266   have a __call method; otherwise (if `fatal' is false), raises a warning and
1267   puts func that does nothing and returns null (SystemLib::s_nullFunc) on the
1268   activation record.
1270 | LdObjInvoke, D(Func), S(Cls), B
1272   Try to load a cached non-static __invoke Func from the Class in S0, or branch
1273   to block B if it is not present.
1275 | LdArrFuncCtx<offset>, ND, S(Arr) S(StkPtr) S(FramePtr), Er
1277   Try to load an array as a function context. This is for use translating
1278   FPushFunc when the callee is an array. This instruction attempts to populate
1279   a partially created ActRec pointed to by S1 + `offset' (in cells).
1281 | LdArrFPushCuf<offset>, ND, S(Arr) S(StkPtr) S(FramePtr), Er
1283 | LdStrFPushCuf<offset>, ND, S(Str) S(StkPtr) S(FramePtr), Er
1285   Try to resolve a method target for FPushCuf when the callee is an Arr or Str,
1286   respectively. These instructions mutate a partially created ActRec pointed to
1287   by S1 + `offset' (in cells).
1289 | LdObjClass, DLdObjCls, S(Obj), NF
1291   Load the class out of the object in S0 and put it in D.
1293 | LdClsName, D(StaticStr), S(Cls), NF
1295   Load the name of the Class* in S0.
1297 | LdFunc<offset>, ND, S(Str) S(StkPtr) S(FramePtr), Er
1299   Loads the Func whose name is S0 into the partially constructed ActRec pointed
1300   to by S1 + `offset` (in cells). Also populate the m_this/m_cls field if
1301   necessary.  Fatal if the named function is not defined, and the autoloader
1302   fails to define it.
1304 | LdFuncCached<funcName>, D(Func), NA, Er
1306   Loads the Func whose name is funcName from the RDS, invoking autoload if it
1307   not defined yet. Fatal if function autoloader fails to define it.
1309 | LdFuncCachedU<funcName,fallbackName>, D(Func), NA, Er
1311   Try to load a Func named funcName from the RDS, if it isn't defined, try to
1312   load a Func named fallbackName. If that also isn't defined, invoke autoload.
1313   If this still doesn't result in a Func, raise a fatal error.
1315 | LdFuncCachedSafe<funcName>, D(Func), NA, B
1317   Try to load the Func named funcName from the RDS. If the function is not
1318   defined, branch to B.
1320 | LdARFuncPtr<offset>, D(Func), S(StkPtr), NF
1322   Loads the m_func member of an ActRec. S0 is the base address, with `offset'
1323   cells to the ActRec.
1325 | LdARCtx<T,offset>, DParam(Ctx), S(StkPtr), NF
1327   Loads the m_this/m_cls member of an ActRec. S0 is the base address, with
1328   `offset' cells to the ActRec.
1330 | LdARNumParams, D(Int), S(FramePtr), NF
1332   Loads the number of params from an ActRec. S0 is the address of the ActRec
1334 | LdFuncNumParams, D(Int), S(Func), NF
1336   Returns the value of func->numParams().
1338 | LdStrLen, D(Int), S(Str), NF
1340   Load the length of the string in S0.
1342 | LdClosureStaticLoc, D(BoxedCell), CStr S(FramePtr), NF
1344   Get boxed value to initialize static local named S0 in frame S1, where S1
1345   must be either a closure or generatorFromClosure function.
1347 | LdStaticLoc<func,staticLocalName>, D(BoxedInitCell), NA, B
1349   Load the address of the static local variable named 'staticLocalName' for
1350   function 'func' in RDS. If the variable isn't initialized, branch to B.
1352 8. Allocation
1354 | AllocObj, DAllocObj, S(Cls), PRc|Er
1356   Allocates a new object of class S1.
1358 | RegisterLiveObj, ND, S(Obj), NF
1360   When EnableObjDestructCall is on, we need to keep track of objects to be able
1361   to call their destructors when a request exists.  This instruction is
1362   conditionally emitted to implement that.
1364 | CheckInitProps<class>, ND, NA, B
1366   Check if the properties for class are initialized and branches if not.
1368 | InitProps<class>, ND, NA, Er
1370   Calls the property initializer function (86pinit) for class.  May throw.
1372 | CheckInitSProps<class>, ND, NA, B
1374   Check if static properties for class are initialized and branches if not.
1376 | InitSProps<class>, ND, NA, Er
1378   Calls the static property initializer function (86sinit) for class. May
1379   throw.
1381 | DebugBacktrace, D(Arr), S(Int), PRc
1383   Obtain stack trace by calling the debug_backtrace() method.
1385 | InitThrowableFileAndLine, ND, S(Obj), NF
1387   Initialize Throwable's file name and line number assuming the stack trace
1388   was already initialized and the current vmfp() is a built-in.
1390 | NewInstanceRaw<class>, DAllocObj, NA, PRc
1392   Allocates an instance of class.
1394 | InitObjProps<class>, ND, S(Obj), NF
1396   Initializes properties of object S0.
1398 | ConstructInstance<class>, DAllocObj, NA, Er
1400   Call the custom instance constructor of an extension class.
1402 | NewArray, D(Arr), C(Int), PRc
1404   Allocate a new array with the expected capacity S0.
1406 | NewMixedArray, D(Arr), C(Int), PRc
1408   Allocate a new array in mixed mode with the expected capacity S0.
1410 | NewDictArray, D(Dict), C(Int), PRc
1412   Allocate a new dict with the expected capacity S0.
1414 | NewKeysetArray<offset,keys>, D(Keyset), S(StkPtr), PRc|CRc|Er
1416   Allocate a new keyset containing N elements off the stack given by S0, at
1417   `offset'. This instruction moves the elements off the stack without
1418   manipulating their reference counts.
1420 | NewLikeArray, D(Arr), S(Arr) C(Int), PRc
1422   Allocate a new array in the same mode as S0 and with expected capacity S1,
1423   unless S1 == 0, in which case the capacity is set to S0's size.
1425 | AllocPackedArray<size>, DArrPacked, NA, PRc
1427   Allocate a new uninitialized packed array with space for size elements in it.
1428   The array will be initialized with values using either InitPackedLayoutArray
1429   or InitPackedLayoutArrayLoop.
1431 | AllocVecArray<size>, D(Vec), NA, PRc
1433   Allocate a new uninitialized vector array with space for size elements in it.
1434   The array will be initialized with values using either InitPackedLayoutArray
1435   or InitPackedLayoutArrayLoop.
1437 | InitPackedLayoutArray<index>, ND, S(Arr,Vec) S(Cell), CRc
1439   Store the S1 into the slot at index in array S0. This instruction assumes
1440   that it doesn't have to incref the value being stored. Used to initialize an
1441   array allocated with AllocPackedArray or AllocVecArray.
1443 | InitPackedLayoutArrayLoop<offset,size>, ND, S(Arr,Vec) S(StkPtr), CRc
1445   Move `size' elements from the stack given by S1, at `offset', into the array
1446   S0.  Assumes that the first element on the stack is the last element in the
1447   array.  Used to initialize an array allocated with AllocPackedArray or
1448   AllocVecArray that was too big to use a series of InitPackedLayoutArray
1449   instructions.
1451 | NewStructArray<offset,keys...>, D(Arr), S(StkPtr), PRc|CRc
1453   Allocate a new key/value array, given N immediate keys and taking N elements
1454   off the stack given by S0, at `offset'. This instruction assumes it can take
1455   the values from the stack without increfing them.
1457 | NewCol<type>, DCol, NA, PRc
1459   Create an empty new collection of `type'.
1461 | NewColFromArray<type>, DCol, S(Arr|Vec), PRc|CRc
1463   Create a collection of `type` from an array. `type` cannot be Pair. The array
1464   will be used to back the new collection without duplication or conversion.
1465   Thus it should not contain references. In addition, the array must be in
1466   packed mode when `type` is Vector or ImmVector, and must be in mixed mode
1467   otherwise. Ownership of the array is transferred from $1 to the collection,
1468   without manipulating the refcount.
1470 | Clone, DofS(0), S(Obj), PRc|Er
1472   Allocate an object by cloning S0.
1475 9. Call & Return
1477 | SpillFrame<offset,numArgs,invName>,
1478 |   ND,
1479 |   S(StkPtr) S(Func,Nullptr) S(Ctx,Cls,Nullptr),
1480 |   CRc
1482   Operands:
1484      S0 - caller stack pointer
1485      S1 - callee Func or nullptr
1486      S2 - object (for FPushObjMethod*), class (for FPushClsMethod*), context
1487           (for FPushClsMethodF), or nullptr (for FPushFunc*).
1489   Defines the fields for an activation record and writes them to the stack
1490   pointed to by S0, at `offset'.
1492 | CufIterSpillFrame<offset,numArgs,iterId>, ND,
1493 |                                           S(StkPtr) S(FramePtr),
1494 |                                           NF
1496   Operands:
1498      S0 - caller stack pointer
1499      S1 - caller frame pointer
1501   Defines the fields for an activation record using data from the iterator
1502   iterId, and writes them to the stack pointed to by S1, at offset.
1504 | FreeActRec, D(FramePtr), S(FramePtr), NF
1506   Load the saved frame pointer from the activation record pointed to by S0 into
1507   D.
1509 | BeginInlining<offset>, ND, S(StkPtr), NF
1511   Marks the start of an inlined function whose stack resides offset cells below
1512   the SP. It has no effect other than to hint to optimization passes that at the
1513   start of the inlined function its stack is dead.
1515 | DefInlineFP<func,retBCOff,retSPOff>, D(FramePtr),
1516 |                                      S(StkPtr) S(FramePtr),
1517 |                                      NF
1519   Defines a frame pointer for an inlined function.
1521   `func' is the function being inlined. `retBCOff' and `retSPOff' represent
1522   what the bytecode and stack offsets should be after the FCall instruction in
1523   ther caller.
1525   This instruction is primarily used to represent a frame in the IR in a way
1526   that allows us to eliminate it entirely. When it cannot be eliminated (or if
1527   it is pushed into an unlikely path) it performs callee-side responsibilities
1528   for setting up an activation record (i.e. setting the return ip and m_soff,
1529   storing the frame pointer into D).
1531   The caller frame pointer is passed as S1. This is used to keep track of the
1532   call chain of inlined functions for simplification and dead code elimination.
1534 | InlineReturn<callerFPOff>, ND, S(FramePtr), NF
1536   Unlinks a frame constructed by DefInlineFP.  `callerFPOff' is the offset of
1537   the caller's frame pointer relative to S0.
1539 | InlineReturnNoFrame<InlineFrameStart>, ND, NA, NF
1541   Mark the end of an inlined function for which no DefInlineFP was required. The
1542   primary purpose of this instruction is to mark the result of a SpillFrame as
1543   dead. InlineFrameStart is the caller FP-relative offset of the start of the
1544   callee frame. Everything below InlineFrameStart is dead.
1546 | CallArray<spOffset,numParams,callOff,after,funcd,destroyLocals>,
1547 |                       DCall,
1548 |                       S(StkPtr) S(FramePtr),
1549 |                       Er
1551   Invoke function corresponding to the current FPI with numParams arguments,
1552   the last of which is an array of the remaining args. Used for FCallArray (in
1553   which case numParams == 1), and FCallUnpack. S0+spOffset points to the stack
1554   resulting after the ActRec for the function and numParams arguments have been
1555   pushed. CallArray pops the array off the stack, pushes the elements of the
1556   array as arguments, and invokes the function in the ActRec.
1558 | SyncReturnBC<spOffset,bcOffset>, ND, S(StkPtr) S(FramePtr), NF
1560   Stores bcOffset into the frame at spOffset from S0 as the return bytecode
1561   address and the frame S1 as the return frame.
1563 | Call<offset,numParams,returnOff,funcd,destroyLocals>, DCall,
1564 |                                                       S(StkPtr) S(FramePtr),
1565 |                                                       Er
1567   Transfer control to a callee, based on the pre-live activation record and set
1568   of args on the stack pointed to by S0 at `offset'. S1 is the current caller
1569   frame pointer. The `funcd' in the extra data is a Func* for the callee if we
1570   know the callee statically.
1572 | NativeImpl<func>, ND, S(FramePtr) S(StkPtr), Er
1574   Execute a call to the native builtin specified by the current function. S0
1575   and S1 should be the current vmfp and vmsp, respectively.
1577 | CallBuiltin, DBuiltin, S(FramePtr) S(StkPtr) SVar(PtrToGen,Gen,Cls,Nullptr), Er|PRc
1579   Call builtin function with N arguments. S0 and S1 should be the current vmfp
1580   and vmsp, respectively.
1582   The source and destination types correspond to C++ parameter and return types
1583   as follows:
1585     C++ type            HHIR type         Position
1586     -----------------   ---------         --------
1587     bool                Bool              source, destination
1588     int64_t             Int               source, destination
1589     double              Dbl               source, destination
1590     const String&       PtrToStr          source
1591     const Array&        PtrToArr          source
1592     const Object&       PtrToObj          source
1593     const Variant&      PtrToGen          source
1594     Variant&            PtrToGen          source (ref param)
1595     String              {Str|InitNull}    destination
1596     Array               {Arr|InitNull}    destination
1597     Object              {Obj|InitNull}    destination
1598     Variant             {Gen-UninitNull}  destination
1600 | RetCtrl<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Gen), T
1602   Ensure that S0 + `spOff' (in cells) is stored in rvmsp and that S1's saved
1603   frame pointer is stored in rvmfp, then return to the saved return address in
1604   S1.  The return value is S2, which is passed via the rret_*() registers to
1605   the caller.  The `suspendingResumed' flag indicates when this instruction is
1606   suspending a resumable rather than performing a normal function return.
1608 | AsyncRetCtrl<spOff,suspendingResumed>, ND,
1609 |                                        S(StkPtr) S(FramePtr) S(InitNull),
1610 |                                        T
1612   Ensure that S0 + `spOff` (in cells) is stored in rvmsp and that S1 is stored
1613   in rvmfp.  The `suspendingResumed' flag indicates when this instruction is
1614   suspending a resumable rather than performing an async function return.
1615   Returns by leaving the TC to enterTCHelper.
1617   The return value is S2, which is passed via the rret_*() registers, and must
1618   be null---it is only used for enterTCHelper and ignored by everything else;
1619   resumed functions store their real return value into the Resumable object.
1621 | AsyncRetFast<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1623   Packs retVal (S2) into registers, sync stack (S0) and calls the asyncRetCtrl
1624   unique stub. The stub unblocks parents of the async function (represented by
1625   the frame pointer S1) and determines if it's possible to resume parent
1626   directly (fast path).
1628 | AsyncSwitchFast<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1630   Pass control to any pending fast resumable wait handles, bypassing the
1631   scheduler.  If no fast resumables are pending, behave like AsyncRetCtrl.
1633 | LdRetVal<T>, DParam(Gen), S(FramePtr), NF
1635   Load the return value from the already-returned-from ActRec pointed to by S0
1636   into the dest.  This is used by NativeImpl.  TODO(#7150575): We want to make
1637   NativeImpl return a TypedValue in the C++ ABI registers.
1639 | DbgTrashRetVal, ND, S(FramePtr), NF
1641   For debugging purposes.  Store kTVTrashJITRetVal to the return value slot on
1642   the activation record pointed to by S0.
1644 | ReleaseVVAndSkip, ND, S(FramePtr), B
1646   Loads the VarEnv slot off the ActRec pointed to by S0. If it is null, does
1647   nothing. If it is an ExtraArgs, deallocates the ExtraArgs structure.
1648   Otherwise it frees the VarEnv and jumps to block B. This instruction may not
1649   occur in an inlined call.
1651 | GenericRetDecRefs, ND, S(FramePtr), NF
1653   Does decrefs of all the current function's locals, where S0 is a pointer to
1654   the relevant activation record. This instruction may not occur in an inlined
1655   call.
1658 10. Stores
1660 | StMem, ND, S(PtrToGen) S(Gen), CRc
1662   Store S1 into the location pointed to by S0.
1664 | StElem, ND, S(PtrToCell) S(Int) S(Cell), CRc
1666   Store S2 into the location given by the index S1 from base pointer S0. The
1667   index in S1 is the number of bytes from the base in S0.
1669 | StLoc<localId>, ND, S(FramePtr) S(Gen), CRc
1671   Store S1 to local number localId on the frame pointed to by S0.
1673 | StLocPseudoMain<localId>, ND, S(FramePtr) S(Gen), CRc
1675   Behaves just like StLoc, except the hard requirement that it is only emitted
1676   for pseudo-mains. We don't optimize StGbl the same way as StLoc, as we need
1677   intraprocedural analysis to know whether the store is truly dead.
1679 | StLocRange<localIds>, ND, S(FramePtr) S(Gen), CRc
1681   Store S1 to the local variables corresponding to localIds, on the frame
1682   pointed to by S0.
1684 | StClsRef<slot>, ND, S(FramePtr) S(Cls), NF
1686   Store S1 to class-ref slot `slot` on the frame pointed to by S0.
1688 | StRef, ND, S(BoxedCell) S(Cell), CRc
1690   Store the value in S1 into the RefData pointed to by S0. Stores the
1691   RefData::m_type also.
1693 | StStk<offset>, ND, S(StkPtr) S(Gen), CRc
1695   Store S1 to the stack pointed to by S0, at a given offset (in cells).
1697 | DbgTrashStk<offset>, ND, S(StkPtr), NF
1699   For debugging purposes.  Store kTVTrashJITStk to the stack slot pointed to
1700   by S0, at a given offset (in cells).
1702 | DbgTrashFrame<offset>, ND, S(StkPtr), NF
1704   For debugging purposes.  Store kTVTrashJITFrame to kNumActRecCells stack
1705   slots starting at the offset (in cells), and going toward higher memory
1706   addresses.
1708 | DbgTrashMem, ND, S(PtrToGen), NF
1710   For debugging purposes.  Store kTVTrashJITHeap to a heap slot pointed to by
1711   S0.
1714 11. Trace exits
1716 | EagerSyncVMRegs, ND, S(FramePtr) S(StkPtr), NF
1718   Sync the given vmfp and vmsp to their in-memory locations.
1720 | ReqBindJmp<bcOff,transFlags>, ND, S(StkPtr) S(FramePtr), T
1722   Emit a jump to a REQ_BIND_JMP service request to the target offset bcOff.
1724 | ReqRetranslate<transFlags>, ND, S(StkPtr) S(FramePtr), T
1726   Emit a jump to a service request that will chain to a retranslation of this
1727   tracelet.
1729   This instruction is used in exit traces for a type prediction that occurs at
1730   the first bytecode offset of a tracelet.
1732 | ReqRetranslateOpt<transId,bcOff>, ND, S(StkPtr) S(FramePtr), T
1734   Emit a service request to retranslate, with a higher optimization gear,
1735   translation transID, which starts at bcOff. This instruction is used in exit
1736   traces that trigger profile-guided optimizations.
1739 12. Refcounting and copies
1741 | Mov, DofS(0), S(Top), P
1743   Defines D as S0. May imply register-to-register moves at code generation
1744   time. Does not imply an incref or any other manipulation of S0.
1746 | IncRef, ND, S(Gen,Ctx), NF
1748   If S0 is a refcounted type, increment its refcount.
1750 | DecRef<locId>, ND, S(Gen,Ctx), CRc
1752   Decrease the reference count of S0 by one, and call a destructor for types
1753   that require it if it goes to zero.
1755   Note that although DecRef takes a Gen, we don't allow it to use information
1756   about the inner types of a BoxedCell. This is because we don't guard on the
1757   inner types of a BoxedCell except when doing LdRef. For any S0 that is a
1758   strict subtype of BoxedCell, the DecRef must just decref it as if it were a
1759   BoxedCell.
1761   The locId is just a hint to the runtime indicating which local variable is
1762   being DecRef'd, if any.
1764 | DecRefNZ, ND, S(Gen,Ctx), CRc
1766   Decrease the reference count of S0 by one, do not check if it goes to zero.
1767   This instruction can be used for more efficient code when it is provable that
1768   the reference count cannot go to zero.
1771 13. Misc
1773 | DefFP, D(FramePtr), NA, NF
1775   Creates a temporary D representing the current vm frame pointer.
1777 | DefSP<stackOff>, D(StkPtr), S(FramePtr), NF
1779   Creates a temporary D representing the current vm stack pointer. S0 is a
1780   pointer to the current frame. The 'stackOff' is the logical offset between S0
1781   and the stack pointer, but in the case of generators this is not the
1782   physical offset at runtime.
1784   This instruction is used at the beginning of tracelets to represent the state
1785   of the stack on entry and does not emit code.
1787 | Count, D(Int), S(Cell), Er
1789   Computes the number of elements in S0. The count of an array is the number of
1790   elements it contains, without recursing into containers in the array.
1791   Subtypes of Bool|Int|Dbl|Str|Res have a count of 1, subtypes of Null have a
1792   count of 0. The count of objects that implement the Countable interface is
1793   computed by returning the value of their count method. Objects that do not
1794   implement Countable have a count of 1.
1796 | CountArray,      D(Int), S(Arr),    NF
1798 | CountArrayFast,  D(Int), S(Arr),    NF
1800 | CountVec,        D(Int), S(Vec),    NF
1802 | CountDict,       D(Int), S(Dict),   NF
1804 | CountKeyset,     D(Int), S(Keyset), NF
1806 | CountCollection, D(Int), S(Obj),    NF
1808   Computes the number of elements in S0 using the same definition as Count, but
1809   with a restriction on the input type.
1811   CountArray expects any array. CountArrayFast expects an array whose kind is
1812   not kGlobalsKind or kProxyKind. CountCollection expects a collection object.
1814 | Nop, ND, NA, NF
1816   Does nothing. It's sometimes useful for the simplifier to insert one of these
1817   in the instruction stream.
1819 | ExitPlaceholder, ND, NA, B
1821   Does nothing if executed. Semantically, this instruction carries a taken edge
1822   to a block that was a pure side-exit during initial IR generation.  This
1823   allows later passes to test conditions and create new exits from the region
1824   at this point in the program.
1826 14. Runtime helpers
1828 | VerifyParamCls, ND, S(Cls) S(Cls|Nullptr) C(Int) C(Int), Er
1830   Verify parameter type for classes or traits. If S0 does not extend (if S1 is
1831   a class) or implement (if S1 is an interface) S1, this instruction will raise
1832   a recoverable fatal error describing the type mismatch.
1834 | VerifyParamCallable, ND, S(Gen) C(Int), Er
1836   If S0 is not callable, as defined by the php function is_callable, this
1837   instruction will raise a recoverable fatal error describing the type
1838   mismatch.
1840 | VerifyParamFail, ND, C(Int), Er
1842   Assumes that parameter number S0 in the current function has failed a its
1843   type check. Depending on the typehint being verified and a number of runtime
1844   options, may coerce the parameter to the correct type or raise a recoverable
1845   fatal error describing the type mismatch.
1847 | VerifyParamFailHard, ND, C(Int), Er|T
1849   A terminal version of VerifyParamFail, to be used when the compiler can
1850   statically prove that this failure will result in a fatal error rather than a
1851   type coercion.
1853 | VerifyRetCallable, ND, S(Gen), Er
1855   Verify a return type hint.
1857 | VerifyRetCls, ND, S(Cls) S(Cls|Nullptr) C(Int) S(Cell), Er
1859   Verify a return type hint.
1861 | VerifyRetFail, ND, S(PtrToGen), Er
1863   Failure to verify a return type hint.
1865 | RaiseUninitLoc<localId>, ND, S(Str), Er
1867   Raise a notice for an uninitialized local variable.
1869 | RaiseUndefProp, ND, S(Obj) CStr, Er
1871   Raise a notice for an undefined property named S1 on the class of S0.
1873 | RaiseMissingArg<func,argc>, ND, NA, Er
1875   Raise a missing argument warning because only S1 arguments were passed to
1876   function S0.
1878 | RaiseError, ND, S(Str), T|Er
1880   Raises a fatal error with the text in S0 as its message.
1882 | RaiseWarning, ND, S(Str), Er
1884   Raises a warning with the text in S0 as its message.
1886 | RaiseNotice, ND, S(Str), Er
1888   Raises a notice with the text in S0 as its message.
1890 | RaiseArrayIndexNotice, ND, S(Int), Er
1892   Raises a notice that S0 is an undefined index for an array.
1894 | RaiseArrayKeyNotice, ND, S(StaticStr), Er
1896   Raises a notice that S0 is an undefined key for an array.
1898 | RaiseMissingThis, ND, S(Func), Er
1900   Raises an appropriate notice or fatal to indicate that Func was
1901   called with null $this. In most cases its a notice, but for
1902   builtins and special class methods its a fatal.
1904 | FatalMissingThis, ND, S(Func), T|Er
1906   Similar to RaiseMissingThis, but for cases where we know it will fatal.
1908 | RaiseVarEnvDynCall, ND, S(Func), Er
1910   Indicates that Func, which can access the caller's environment, was called
1911   dynamically. Depending on the setting of the `DisallowDynamicVarEnvFuncs`
1912   runtime option, this opcode might fatal, raise a warning, or do nothing. Used
1913   inside generated wrapper functions for builtins which can modify the caller's
1914   frame. These wrapper functions are called instead of the builtin when the
1915   builtin is called dynamically. Func should refer to the builtin, not the
1916   wrapper itself.
1918 | RaiseHackArrCompatNotice, ND, S(Str), Er
1920   Raises a Hack array compat notice with the text in S0 as its message.
1922 | InitClosureStaticLoc, ND, S(BoxedCell) S(Cell), NF
1924   Assuming S0 is an uninitialized closure static local, initialize it by
1925   setting it to the value in S1.
1927 | InitStaticLoc<func,staticLocalName>, D(BoxedInitCell), S(Cell), NF
1929   Initialize the static local variable named 'staticLocalName' for
1930   function 'func' with S0 and return it.
1932 | InitClsCns<className,constName>, DCns, NA, Er|PRc
1934   Initialize the RDS entry for a constant for a class, invoking autoload if it
1935   is not defined. The initialized value is returned. This instruction may raise
1936   an undefined constant error if autoload cannot define the constant.
1938 | PrintStr,  ND, S(Str),  Er|CRc
1940 | PrintInt,  ND, S(Int),  Er|CRc
1942 | PrintBool, ND, S(Bool), Er|CRc
1944   Print for various types.
1946 | ConcatIntStr, D(Str), S(Int) S(Str), Er|PRc
1948   Concatenate S0 and S1 after converting S0 to String.
1950 | ConcatStrInt, D(Str), S(Str) S(Int), Er|CRc|PRc
1952   Concatenate S0 and S1 after converting S1 to String.
1954 | ConcatStrStr, D(Str), S(Str) S(Str), Er|CRc|PRc
1956   Concatenate S0 and S1.
1958 | ConcatStr3, D(Str), S(Str) S(Str) S(Str), Er|CRc|PRc
1960   Concatenate S0, S1, and S2.
1962 | ConcatStr4, D(Str), S(Str) S(Str) S(Str) S(Str), Er|CRc|PRc
1964   Concatenate S0, S1, S2, and S3.
1966 | AddElemStrKey, D(Arr), S(Arr) S(Str) S(Cell), Er|CRc|PRc
1968   Add S2 to the array S0 for the key S1, and return the resulting array.
1970 | AddElemIntKey, D(Arr), S(Arr) S(Int) S(Cell), Er|CRc|PRc
1972   Add S2 to the array S0 for the key S1, and return the resulting array.
1974 | AddNewElem, D(Arr), S(Arr) S(Cell), Er|CRc|PRc
1976   Add S1 as a new element to the array S0.  (Note: S1 must actually be a
1977   subtype of InitCell for array invariants, but we can't assert this yet in the
1978   IR because many eval stack slots are not entirely typed wrt initness right
1979   now.)
1981 | DictAddElemStrKey, D(Dict), S(Dict) S(Str) S(Cell), Er|CRc|PRc
1983   Add S2 to the dict S0 for the key S1, and return the resulting dict.
1985 | DictAddElemIntKey, D(Dict), S(Dict) S(Int) S(Cell), Er|CRc|PRc
1987   Add S2 to the dict S0 for the key S1, and return the resulting dict.
1989 | ArrayAdd, D(Arr), S(Arr) S(Arr), Er|CRc|PRc
1991   Has the effects of the php + operator on the two source arrays.
1993 | AKExistsArr, D(Bool), S(Arr) S(Int,Str), NF
1995   Has the effects of array_key_exists(S0, S1).
1997 | AKExistsDict, D(Bool), S(Dict) S(Int,Str), NF
1999   Has the effects of array_key_exists(S0, S1).
2001 | AKExistsKeyset, D(Bool), S(Keyset) S(Int,Str), NF
2003   Has the effects of array_key_exists(S0, S1).
2005 | AKExistsObj, D(Bool), S(Obj) S(Int,Str), Er
2007   Has the effects of array_key_exists(S0, S1) on an object S0. This either does
2008   collection accesses, or uses the ArrayAccess API.
2010 | GetMemoKey, DMemoKey, S(Cell), Er|PRc
2012   Given a cell, produces a string or an int that can be used as a memoize cache
2013   key. Valid values for the input include all basic types, arrays and
2014   collections, and objects that implement IMemozieParam. Any other type will
2015   cause GetMemoKey to throw. This op can only be used within functions marked
2016   as memoize wrappers.
2018 | ArrayIdx, D(Gen), S(Arr) S(Int,Str) S(Cell), NF
2020   Checks if S0 contains the key S1, and returns the result if found. Otherwise
2021   S2 is returned.
2023 | DictIdx, DDictElem, S(Dict) S(Int,Str) S(Cell), NF
2025   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2026   S2 is returned.
2028 | KeysetIdx, DKeysetElem, S(Keyset) S(Int,Str) S(Cell), NF
2030   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2031   S2 is returned.
2033 | MapIdx, D(Gen), S(Obj) S(Str) S(Cell), NF
2035   Checks if S0, which must be an HH\Map or an HH\ImmMap, contains the key S1,
2036   and returns the result if found. Otherwise S2 is returned.
2038 | MethodExists, D(Bool), S(Cls) S(Str), NF
2040   Checks if the method named S1 exists on class S0.  S0 must be a normal class
2041   that is not abstract.
2043 | LdBindAddr<SrcKey,spOff>, D(TCA), NA, NF
2045   Creates a service request to bind the given target address. Returns a TCA
2046   pointing either to the service request (before the service request is
2047   satisfied) or to the native code for the given target address (once the
2048   service request is satisfied).
2050 | LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), NF
2052 | LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc
2054 | LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc|Er
2056   These instructions are used to determine the target of a switch statement
2057   with target range [S1:S1 + S2), when invoked with the value S0. They call
2058   helper functions to check whether S0 is an numeric integer in the range
2059   [S1:S1 + S2), and if so return the value S1 - (Int)S0. Else, they return the
2060   target of the default target, S2 + 1.
2062 | LdSSwitchDestFast, D(TCA), S(Gen), NF
2064 | LdSSwitchDestSlow, D(TCA), S(Gen), Er
2066   Load string switch destinations (two different compilation strategies).
2068 | InterpOne<T,spOff,bcOff,numPopped,numPushed>, ND,
2069 |                                               S(StkPtr) S(FramePtr),
2070 |                                               Er
2072   Call the interpreter implementation function for one opcode. S0 + `spOff' (in
2073   cells) and S1 are, respectively, the VM stack and frame pointers before this
2074   instruction. T is only present if the instruction pushes to the stack, in
2075   which case it is the type of the top stack element after the call. `bcOff' is
2076   the bytecode offset. `numPopped' is the number of stack cells consumed by the
2077   instruction, and `numPushed' is the number of stack cells produced by the
2078   instruction.
2080 | InterpOneCF<T,bcOff,numPopped,numPushed>, ND,
2081 |                                           S(StkPtr) S(FramePtr),
2082 |                                           T
2084   Similar to InterpOne, but for instructions that may modify vmpc. This is
2085   implemented as a tail call to a stub, so any exceptions thrown will be thrown
2086   in the context of the stub, not the InterpOneCF instruction.
2088 | OODeclExists<kind>, D(Bool), S(Str) S(Bool), Er
2090   Returns a bool indicating whether the class, interface, or trait named by S0
2091   exists. Invokes autoload if S1 is true.
2093 | SetOpCell<op>, ND, S(PtrToCell) S(Cell), Er
2095   Performs S0 <op>= S1.
2097 | GetTime, D(Dbl), NA, NF
2099   Returns a double of the current time in seconds.
2101 | KillClsRef<slot>, ND, S(FramePtr), NF
2103   Mark the class-ref slot `slot` in frame S0 as no longer containing a
2104   meaningful value. This is used to aid in memory analysis. In debugging
2105   builds, it may overwrite the slot with a poison value.
2107 15. Generators & Closures
2109 | LdClosureCtx, DCtx, S(Obj), NF
2111   Load the context from the closure object S0 into D.
2112   May only be used in S0's closure Func.
2114 | StClosureCtx, ND, S(Obj) S(Ctx,Nullptr), CRc
2116   Store the context represented by S1 into the closure object S0. S1 may be a
2117   Nullptr when there is no context (i.e. the closure is being used in a
2118   non-method).
2120 | StClosureArg<offsetBytes>, ND, S(Obj) S(Gen), CRc
2122   Store one of the closure environment arguments (i.e. from the closure's use
2123   clause) from S1 into the closure object S0.
2125 | CreateCont, D(Obj), S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2127   Create a Generator object and suspend the ActRec provided by S0 into its
2128   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2129   resume address to S2 and resume offset to S3.
2131 | CreateAFWH, DAllocObj,
2132 |             S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2133 |             CRc|PRc
2135   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2136   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2137   the native resume address to S2, resume offset to S3, and mark it blocked on
2138   non-finished child S4.
2140 | CreateAFWHNoVV, DAllocObj,
2141 |                 S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2142 |                 CRc|PRc
2144   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2145   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2146   the native resume address to S2, resume offset to S3, and mark it blocked on
2147   non-finished child S4.  This version of the instruction guarantees that the
2148   VarEnv is unused.
2150 | CreateSSWH, DAllocObj, S(Cell), CRc|PRc
2152   Call c_StaticWaitHandle::CreateSucceeded.
2154 | AFWHPrepareChild, ND, S(FramePtr) S(Obj), Er
2156   Prepare unfinished WaitableWaitHandle object specified by S1 for getting
2157   awaited by an AsyncFunctionWaitHandle object specified by its ActRec
2158   provided by S0.
2160   Injects S1 into the currently running scheduler instance and performs
2161   cross-scheduler and intra-scheduler cycle detection. Throws if the
2162   dependency cannot be established.
2164 | ContEnter<spOffset,returnBCOffset>, ND,
2165 |                                     S(StkPtr) S(FramePtr) S(FramePtr) S(TCA),
2166 |                                     Er
2168   Enters a generator body. S0 + `spOffset' (in cells) is a pointer to the
2169   stack, S1 is the current frame pointer, S2 is the generator frame pointer
2170   embedded in the Generator object, and S3 is the address to jump to. The
2171   `returnBCOffset' will be stored to the m_soff field of the pre-live ActRec on
2172   the stack.
2174 | ContPreNext, ND, S(Obj) C(Bool), B
2176   Performs operations needed for the next() method of Generator object S0.
2177   If the generator is already running or finished, or it was not started yet
2178   and the S1 check-started flag is set, the branch B is taken. Otherwise,
2179   the generator is marked as running.
2181 | ContStartedCheck, ND, S(Obj), B
2183   Checks if the Generator object S0 has started, and if not branches to
2184   block B.
2186 | ContValid, D(Bool), S(Obj), NF
2188   Return true if a generator is not done, false otherwise.
2190 | ContStarted, D(Bool), S(Obj), NF
2192   Return true if a generator has been run at least once, i.e. is not in the
2193   Created state, false otherwise.
2195 | ContArIncKey, ND, S(FramePtr), NF
2197   Special-case key update for generator, ActRec of which is S0, which
2198   increments the key of a generator if that generator's key is an Int.
2199   This will cause undefined behavior if the generator's key is not an Int.
2201 | ContArIncIdx, D(Int), S(FramePtr), NF
2203   Increment the internal index in the Generator in S0, and return the new index
2204   value.
2206 | ContArUpdateIdx, ND, S(FramePtr) S(Int), NF
2208   Updates the internal index of generator with S1 if necessary, i.e. if S1
2209   is larger than the index. S0 is the pointer to the embedded ActRec.
2211 | LdContActRec, D(FramePtr), S(Obj), NF
2213   Loads the Generator object's ActRec, given a pointer to the generator
2214   object in S0.
2216 | LdContResumeAddr, D(TCA), S(Obj), NF
2218   Load the resume addr from the Generator in S0.
2220 | StContArState<state>, ND, S(FramePtr), NF
2222   Change the state of the Generator object which has frame pointer S0.
2224 | StContArResume<offset>, ND, S(FramePtr) S(TCA), NF
2226   Store the resume address S1 into the Generator whose ActRec is given by S0,
2227   marking the offset to resume at as `offset'.
2229 | LdContArValue, DParam(Cell), S(FramePtr), PRc
2231   Loads 'value' from the Generator object ActRec of which is S0.
2233 | StContArValue, ND, S(FramePtr) S(Cell), CRc
2235   Stores 'value' into the Generator object ActRec of which is S0. S1 is the
2236   new value.
2238 | LdContArKey, DParam(Cell), S(FramePtr), PRc
2240   Loads 'key' from the Generator object ActRec of which is S0.
2242 | StContArKey, ND, S(FramePtr) S(Gen), CRc
2244   Stores 'key' into the Generator object ActRec of which is S0. S1 is the
2245   new value.
2247 | StAsyncArSucceeded, ND, S(FramePtr), NF
2249   Mark the AsyncFunctionWaitHandle object whose ActRec is given by S0 as
2250   STATE_SUCCEEDED.
2252 | StAsyncArResume<offset>, ND, S(FramePtr) S(TCA), NF
2254   Store the resume address S1 into the AsyncFunctionWaitHandle whose ActRec is
2255   given by S0, marking the offset to resume at as `offset'.
2257 | StAsyncArResult, ND, S(FramePtr) S(Cell), CRc
2259   Stores result into the AsyncFunctionWaitHandle object ActRec of which is S0.
2260   S1 is the value.
2262 | LdAsyncArParentChain, D(ABC), S(FramePtr), NF
2264   Loads the first parent of the AsyncFunctionWaitHandle object ActRec of which
2265   is S0.
2267 | AFWHBlockOn, ND, S(FramePtr) S(Obj), CRc
2269   Establish dependency between parent AsyncFunctionWaitHandle object, whose
2270   ActRec is given by S0, and child WaitableWaitHandle object referenced by S1.
2272 | ABCUnblock, ND, S(ABC), NF
2274   Calls AsioBlockableChain::Unblock. This instruction may not occur in an
2275   inlined function.
2277 | LdWHState, D(Int), S(Obj), NF
2279   Loads the state of the WaitHandle in S0, which is a value from the wait
2280   handle states in ext_asio.h. This instruction has undefined behavior if S0 is
2281   not a WaitHandle.
2283 | LdWHResult, DParam(Gen), S(Obj), NF
2285   Loads the result of the WaitHandle in S0. This instruction has undefined
2286   behavior if S0 is not a WaitHandle, or if S0 is not finished.
2288 | LdAFWHActRec, D(FramePtr), S(Obj), NF
2290   Loads the AsyncFunctionWaitHandle object's ActRec, given a pointer to the
2291   AsyncFunctionWaitHandle object in S0.
2293 | LdResumableArObj, D(Obj), S(FramePtr), NF
2295   Loads the Resumable object, given a Resumable's frame pointer in S0.
2298 16. Debugging, instrumentation, and profiling
2300 | IncStat, ND, C(Int) C(Int) C(Bool), NF
2302   Increment stat counter. S0 is the implementation defined stat counter index,
2303   S1 is the amount to increment the counter (may be negative), and S2 is a
2304   'force' flag. This opcode becomes a noop iff (force == false and runtime
2305   stats are not enabled) at translation time.
2307 | IncStatGrouped, ND, CStr CStr C(Int), NF
2309   Adds the value S2 to the counter named S1, in the category S0.
2311 | IncProfCounter<TransID>, ND, NA, NF
2313   Increment the profiling counter associated with translation TransID.
2315 | DbgAssertRefCount, ND, S(Gen,TCtx), NF
2317   Assert that S0 has a valid refcount. If S0 has a reference counted type and
2318   its count is implausible then execute a hardware trap instruction.
2320 | DbgTraceCall<spOffset>, ND, S(FramePtr) S(StkPtr), NF
2322   When EvalHHIRGenerateAsserts is on, this instruction is inserted at the
2323   start of each region, to emit some sanity checking code.
2325 | DbgAssertARFunc<offset>, ND, S(StkPtr) S(Func), NF
2327   Assert that S1 is the function in the ActRec given by s0+offset. If the
2328   assertion fails, execution is aborted via a hardware exception.
2330 | RBTraceEntry, ND, NA, NF
2332 | RBTraceMsg, ND, NA, NF
2334   Ring buffer tracing.
2336 | ZeroErrorLevel, D(Int), NA, NF
2338 | RestoreErrorLevel, ND, S(Int), NF
2340   Helper instructions for fast implementation of the PHP error silencing
2341   operator (@foo()).
2344 17. Iterators
2346 | IterInit<IterData>,   D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2348 | IterInitK<IterData>,  D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2350 | WIterInit<IterData>,  D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2352 | WIterInitK<IterData>, D(Bool), S(ArrLike,Obj) S(FramePtr), Er|CRc
2354 | MIterInit<T,IterData>,  D(Bool), S(BoxedCell) S(FramePtr), Er
2356 | MIterInitK<T,IterData>, D(Bool), S(BoxedCell) S(FramePtr), Er
2358   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2359   the index of the iterator variable, keyId and valId are indices of local
2360   variables.
2362   Initializes the iterator variable whose index is given by iterId.
2363   This instruction creates the appropriate iterator for the array or object that
2364   S0 references, and rewinds the new iterator to its start. S0 points to the
2365   stack frame containing the iterator and local variables with the indices
2366   iterId, keyId and valId.
2368   If the new iterator is at its end (i.e., has no elements to iterate over),
2369   this instruction decrements the refcount of S0 and returns false; otheriwse,
2370   it stores a reference to S0 in the new iterator and returns true. If the
2371   iterator is not at its end, then this instruction stores the iterator's first
2372   value (and key) into the local variable with index valId (and keyId,
2373   respectively).
2375   The IterInit and IterInitK instructions always copy the array element by
2376   value.
2378   The WIterInit and WIterInitK instructions copy referenced array elements by
2379   reference, and non-referenced array elements by value.
2381   The MIterInit and MIterInitK instructions always copy the array element by
2382   reference, and take a type parameter indicating the inner type of S0.  (This
2383   must have been proven via guards prior to running this opcode.)  Right now T
2384   must be Obj or Arr.
2386   This instruction has the ConsumesRC property because it either decrements the
2387   reference count of S0 or stores a reference to S0 into the new iterator.
2389 | IterNext<IterData>,   D(Bool), S(FramePtr), Er
2391 | IterNextK<IterData>,  D(Bool), S(FramePtr), Er
2393 | WIterNext<IterData>,  D(Bool), S(FramePtr), Er
2395 | WIterNextK<IterData>, D(Bool), S(FramePtr), Er
2397 | MIterNext<IterData>,  D(Bool), S(FramePtr), NF
2399 | MIterNextK<IterData>, D(Bool), S(FramePtr), NF
2401   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2402   the index of the iterator variable, keyId and valId are indices of local
2403   variables.  S0 points to the stack frame containing the iterator and local
2404   variables with the indices iterId, keyId and valId.
2406   Advances the iterator variable whose index is given by iterId.
2408   If the iterator has reached the end, this instruction frees the iterator
2409   variable and returns false; otherwise, it returns true. If the iterator has
2410   not reached its end, then this instruction stores the iterator's next value
2411   (and key) into the local variable with index valId (and keyId, respectively).
2413   The IterInit and IterInitK instructions always copy the array element by
2414   value. The WIterInit and WIterInitK instructions copy referenced array
2415   elements by reference, and non-referenced array elements by value. The
2416   MIterNext and MIterNextK instructions always copy the array element by
2417   reference.
2419 | IterFree,  ND, S(FramePtr), NF
2421 | MIterFree, ND, S(FramePtr), NF
2423   Free the iterator variable whose index is given by S1 in the stack frame
2424   pointed to by S0.
2426 | DecodeCufIter<iterId>, D(Bool), S(ArrLike,Obj,Str)  S(FramePtr), Er
2428   Decode S0 as a callable, and write the decoded values to the iterator
2429   specified by IterId. Returns true iff it successfully decoded the callable.
2430   Does not raise warnings, or throw exceptions.
2432 | CIterFree<iterId>, ND, S(FramePtr), NF
2434   Free the iterator variable whose index is given by IterId in the stack frame
2435   pointed to by S0.
2438 18. Member instruction support
2440 | LdMIStateAddr, D(PtrToMISGen), C(Int), NF
2442   Load an MInstrState address. Returns a pointer to offset S0 within the
2443   current MInstrState.
2445 | LdMBase, DParam(PtrToGen), NA, NF
2447   Load the current value of the member base register.
2449 | StMBase, ND, S(PtrToGen), NF
2451   Store a new value to the member base register. It is illegal for any
2452   instruction other than StMBase or InterpOne (when interpreting a member
2453   instruction) to modify the member base register.
2455 | FinishMemberOp, ND, NA, NF
2457   Mark the end of a member operation. This has no effect at runtime but exists
2458   to provide information for certain optimizations.
2460 All of the remaining opcodes in this section are simple wrappers around helper
2461 functions (specified in S0) to perform the corresponding vector operation. If
2462 S1 is a ConstCls it represents the context class for the operation.
2464 SetElem, SetProp, and SetNewElem are used to implement part of the SetM hhbc
2465 opcode, which almost always pushes its first stack input or a CountedStr as its
2466 stack result. The combinations of input types that cause SetM to push anything
2467 other than those two values are vanishingly rare in correct PHP programs, so
2468 these three instructions have been optimized for the common cases. SetNewElem
2469 and SetProp have no destination, allowing the compiler to predict that the
2470 SetM's output will be the same as its input (and optimize accordingly). If that
2471 turns out to not be the case at runtime, the instruction will throw an
2472 InvalidSetMException. The exception will hold a Cell containing the value the
2473 SetM should push on the stack instead of its input value. The runtime is
2474 responsible for catching this exception, finishing execution of the SetM
2475 instruction, pushing the value from the exception on the stack, and proceeding
2476 as appropriate (most likely with a side exit to the next bytecode instruction,
2477 since it has pushed an unexpected type onto the stack).
2479 SetElem is similar to SetProp and SetNewElem but can also be used for setting
2480 characters within strings. When given a string base and a valid offset, SetElem
2481 returns a string representation of the newly inserted character. In all other
2482 cases it returns nullptr or throws an InvalidSetMException. It will throw this
2483 exception when it detects invalid input types, or when trying to set a string
2484 offset that would grow the string beyond the maximum supported size.
2486 The input types that will cause the errors described above are listed here:
2488 SetNewElem will fail if the base is not a subtype of {Null|Str|Arr|Obj} and not
2489            Bool<false>.
2490 SetElem has the same base constraint as SetNewElem. In addition, the key must
2491         not be a subtype of {Arr|Obj}.
2492 SetProp will fail if the base is not a subtype of {Obj|Null}.
2494 Any instructions that take a pointer to an MInstrState struct use the various
2495 fields of that struct for holding intermediate values.
2497 | BaseG, D(PtrToRMembCell), S(Str), Er
2499   Get a base from global named S0.
2501   NB: BaseG returns either a PtrToGblGen, OR a pointer to a ref that is rooted
2502   in a GblGen.  (I.e. the unbox happens in the C++ helper that this instruction
2503   calls.)  If it is not a defining BaseG it can also return the
2504   init_null_variant, so for now it returns a PtrToRMembCell.
2506 | PropX, D(PtrToMembGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), Er
2508   Lookup intermediate property in S0, with key S1.
2510 | PropQ, D(PtrToMembGen), S(Obj,PtrToGen) S(StaticStr) S(PtrToMISGen), Er
2512   A nullsafe version of PropX, returns null if the base S0 is null.
2514 | PropDX, D(PtrToMembGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), MProp|Er
2516   Like PropX, but used for intermediate element lookups that may modify the
2517   base.
2519 | CGetProp, D(Cell), S(Obj,PtrToGen) S(Cell), PRc|Er
2521   Get property with key S1 from S0.
2523 | CGetPropQ, D(Cell), S(Obj,PtrToGen) S(StaticStr), PRc|Er
2525   A nullsafe version of CGetProp, returns null if the base S0 is null.
2527 | VGetProp, D(BoxedInitCell), S(Obj,PtrToGen) S(Cell), MProp|PRc|Er
2529   Get property with key S1 from base S0 as a reference.
2531 | BindProp, ND,
2532 |           S(Obj,PtrToGen) S(Cell) S(BoxedCell),
2533 |           MProp|Er
2535   Bind property with key S1 in base S0 to the reference in S2.
2537 | SetProp, ND, S(Obj,PtrToGen) S(Cell) S(Cell), MProp|Er
2539   Set property with key S1 in S0 to S2.
2541 | UnsetProp, ND, S(Obj,PtrToGen) S(Cell), Er
2543   Unset an object property.
2545 | SetOpProp<op>, D(Cell),
2546 |                S(Obj,PtrToGen) S(Cell) S(Cell),
2547 |                MProp|PRc|Er
2549   Set op propery with key S1 in base S0, using S2 as the right hand side.
2551 | IncDecProp<op>, D(Cell),
2552 |                 S(Obj,PtrToGen) S(Cell),
2553 |                 MProp|PRc|Er
2555   Increment/decrement property with key S1 in base S0.
2557 | EmptyProp, D(Bool), S(Obj,PtrToGen) S(Cell), Er
2559   Returns true iff the property with key S1 in base S0 is empty.
2561 | IssetProp, D(Bool), S(Obj,PtrToGen) S(Cell), Er
2563   Returns true iff the property with key S1 in base S0 is set.
2565 | ElemX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), Er
2567   Get intermediate element with key S1 from base S0. The base will not be
2568   modified.
2570 | ProfileMixedArrayOffset, ND, S(Arr) S(Int,Str), NF
2572   Profile the offset of the element keyed by S1 in S0.
2574 | CheckMixedArrayOffset<pos>, ND, S(AK(Mixed)) S(Int,Str), B
2576   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2577   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2578   fail, branch to B.  This check is allowed to have false negatives, in the
2579   case of int-like strings.
2581 | CheckArrayCOW, ND, S(ArrLike), B
2583   Check that S0 has a refcount of exactly 1; if not, branch to B.
2585 | ProfileDictOffset, ND, S(Dict) S(Int,Str), NF
2587   Profile the offset of the element keyed by S1 in S0.
2589 | CheckDictOffset<pos>, ND, S(Dict) S(Int,Str), B
2591   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2592   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2593   fail, branch to B.  This check is allowed to have false negatives.
2595 | ProfileKeysetOffset, ND, S(Keyset) S(Int,Str), NF
2597   Profile the offset of the element keyed by S1 in S0.
2599 | CheckKeysetOffset<pos>, ND, S(Keyset) S(Int,Str), B
2601   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2602   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2603   fail, branch to B.  This check is allowed to have false negatives.
2605 | ElemArray,  D(PtrToMembGen), S(Arr) S(Int,Str), Er
2607 | ElemArrayW, D(PtrToMembGen), S(Arr) S(Int,Str), Er
2609 | ElemArrayD<T>, D(PtrToElemGen), S(PtrToGen) S(Int,Str), MElem|Er
2611 | ElemArrayU<T>, D(PtrToMembGen), S(PtrToGen) S(Int,Str), MElem|Er
2613   Similar to ElemX, but the base S0 is an array and the key S1 is an int/str.
2614   ElemArrayW is for Warn member instrs, ElemArrayD is for Define member instrs,
2615   and ElemArrayU is for Unset.
2617   ElemArray{D,U} both take a PtrToGen for the base operand, but expect it to be
2618   a PtrToArr or PtrToBoxedArr.  T is the type of the base array.
2620 | ElemMixedArrayK<pos>, D(PtrToElemGen), S(AK(Mixed)) S(Int,Str), NF
2622   Like ElemArray, but the element for S1 is at a known position `pos' in S0.
2624 | ElemVecD<T>, D(PtrToElemCell), S(PtrToGen) S(Int), MElem|Er
2626 | ElemVecU<T>, D(PtrToMembCell), S(PtrToGen) S(Int), MElem|Er
2628   Similar to ElemX, but the base S0 is a vec and the key S1 is an int. ElemVecD
2629   is for Define member instrs and ElemVecU is for Unset. (Other variations can
2630   be implemented without special IR instructions).
2632   ElemVec{D,U} both take a PtrToGen for the base operand, but expect it to be a
2633   PtrToVec or PtrToBoxedVec. T is the type of the base vec.
2635 | ElemDict,  D(PtrToMembCell), S(Dict) S(Int,Str), Er
2637 | ElemDictW, D(PtrToMembCell), S(Dict) S(Int,Str), Er
2639 | ElemDictD<T>, D(PtrToElemCell), S(PtrToGen) S(Int,Str), MElem|Er
2641 | ElemDictU<T>, D(PtrToMembCell), S(PtrToGen) S(Int,Str), MElem|Er
2643   Similar to ElemX, but the base S0 is a dict and the key S1 is an int/str.
2644   ElemDictW is for Warn member instrs, ElemDictD is for Define member instrs,
2645   and ElemDictU is for Unset.
2647   ElemDict{D,U} both take a PtrToGen for the base operand, but expect it to be
2648   a PtrToDict or PtrToBoxedDict.  T is the type of the base array.
2650 | ElemDictK<pos>, D(PtrToElemCell), S(Dict) S(Int,Str), NF
2652   Like ElemDict, but the element for S1 is at a known position `pos' in S0.
2654 | ElemKeyset,  D(PtrToMembCell), S(Keyset) S(Int,Str), Er
2656 | ElemKeysetW, D(PtrToMembCell), S(Keyset) S(Int,Str), Er
2658 | ElemKeysetU<T>, D(PtrToMembCell), S(PtrToGen) S(Int,Str), MElem|Er
2660   Similar to ElemX, but the base S0 is a keyset and the key S1 is an int/str.
2661   ElemKeysetW is for Warn member instrs and ElemKeysetU is for Unset.
2663   ElemKeysetU both take a PtrToGen for the base operand, but expect it to be
2664   a PtrToKeyset or PtrToBoxedKeyset.  T is the type of the base array.
2666 | ElemKeysetK<pos>, D(PtrToElemCell), S(Keyset) S(Int,Str), NF
2668   Like ElemKeyset, but the element for S1 is at a known position `pos' in S0.
2670 | ElemDX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|Er
2672   Like ElemX, but used for intermediate element lookups that may modify the
2673   base.
2675 | ElemUX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|Er
2677   Like ElemX, but used for intermediate element lookups that may modify the
2678   base as part of an unset operation.
2680 | ArrayGet, DArrElem, S(Arr) S(Int,Str), Er
2682   Get element with key S1 from base S0.
2684 | MixedArrayGetK<pos>, DArrElem, S(AK(Mixed)) S(Int,Str), NF
2686   Like ArrayGet, but the element for S1 is at a known position `pos' in S0.
2688 | DictGet, DDictElem, S(Dict) S(Int,Str), Er
2690   Get element with key S1 from base S0, throwing if the element is not present.
2692 | DictGetQuiet, DDictElem, S(Dict) S(Int,Str), NF
2694   Get element with key S1 from base S0, returning null if the element is not
2695   present.
2697 | DictGetK<pos>, DDictElem, S(Dict) S(Int,Str), NF
2699   Like DictGet, but the element for S1 is at a known position `pos' in S0.
2701 | KeysetGet, DKeysetElem, S(Keyset) S(Int,Str), Er
2703   Get element with key S1 from base S0, throwing if the element is not present.
2705 | KeysetGetQuiet, DKeysetElem, S(Keyset) S(Int,Str), NF
2707   Get element with key S1 from base S0, returning null if the element is not
2708   present.
2710 | KeysetGetK<pos>, DKeysetElem, S(Keyset) S(Int,Str), NF
2712   Like KeysetGet, but the element for S1 is at a known position `pos' in S0.
2714 | StringGet, D(StaticStr), S(Str) S(Int), PRc|Er
2716   Get string representing character at position S1 from base string S0.  Raises
2717   a notice if the position is out of bounds.
2719 | MapGet, D(Cell), S(Obj) S(Int,Str), PRc|Er
2721   Get element with key S1 from base S0.
2723 | CGetElem, D(Cell), S(PtrToGen) S(Cell), PRc|Er
2725   Get element with key S1 from S0.
2727 | VGetElem, D(BoxedInitCell), S(PtrToGen) S(Cell), MElem|PRc|Er
2729   Get element with key S1 from base S0 as a reference.
2731 | MemoGet<loc-begin, loc-count>, D(Cell), S(FramePtr) S(PtrToGen), PRc
2733   Perform a memoize cache lookup using S1. S1 must point to a dict serving as a
2734   memoize cache, or point to a RefData containing such a dict. The keys used
2735   are read from the exclusive local range [loc_begin, loc_begin+loc_count]
2736   (where S0 is the pointer to the frame containing the locals). If the lookup
2737   is successful, the element is returned (already inc-refd). If the element
2738   is not found, Uninit is returned. This op can only be used inside a function
2739   marked as a memoize wrapper.
2741 | MemoSet<loc-begin, loc-count>, ND, S(FramePtr) S(PtrToGen) S(Cell), MElem
2743   Store S2 in the memoize cache given by S1. S1 must point to a dict serving as
2744   a memoize cache or point to a RefData containing such a dict. They keys used
2745   as read from the exclusive local range [loc_begin, loc_begin+loc_count]
2746   (where S0 is the pointer to the frame containing the locals). S2 must not be
2747   Uninit and will be inc-refd by the operation internally. This op can only be
2748   used inside a function marked as a memoize wrapper.
2750 | BindElem, ND, S(PtrToGen) S(Cell) S(BoxedCell), MElem|Er
2752   Bind element with key S1 in base S0 to the reference S2.
2754 | ArraySet, D(Arr), S(Arr) S(Int,Str) S(Cell), PRc|CRc|Er
2756   Set element with key S1 in S0 to S2. The dest will be a new Array that should
2757   replace S0.
2759 | ArraySetRef, ND, S(Arr) S(Int,Str) S(Cell) S(BoxedCell), CRc|Er
2761   Like ArraySet, but for binding operations on the array. S3 must point to a
2762   RefData with an array type when this instruction is executed, and it must be
2763   the same array that is in S0.
2765 | VecSet, D(Vec), S(Vec) S(Int) S(Cell), PRc|CRc|Er
2767   Set element with key S1 in S0 to S2. The dest will be a new Vec that should
2768   replace S0.
2770 | VecSetRef, ND, S(Vec) S(Int) S(Cell) S(BoxedCell), CRc|Er
2772   Like VecSet, but for binding operations on the vec. S3 must point to a
2773   RefData with a vec type when this instruction is executed, and it must be the
2774   same vec that is in S0.
2776 | DictSet, D(Dict), S(Dict) S(Int,Str) S(Cell), PRc|CRc|Er
2778   Set element with key S1 in S0 to S2. The dest will be a new Dict that should
2779   replace S0.
2781 | DictSetRef, ND, S(Dict) S(Int,Str) S(Cell) S(BoxedCell), CRc|Er
2783   Like DictSet, but for binding operations on the dict. S3 must point to a
2784   RefData with a vec type when this instruction is executed, and it must be the
2785   same dict that is in S0.
2787 | MapSet, ND, S(Obj) S(Int,Str) S(Cell), Er
2789   Set element with key S1 in S0 to S2.
2791 | SetElem, DSetElem, S(PtrToGen) S(Cell) S(Cell), MElem|PRc|Er
2793   Set element with key S1 in S0 to S2. SetElem returns a Nullptr in the common
2794   case, where the logical result of the hhbc SetM is its right hand side. In
2795   the case of string bases, the SetM returns a new string containing the newly
2796   inserted character. So the return value of this instruction is Nullptr unless
2797   SetM needed to create a new counted string.
2799   Furthermore, in the case of "invalid offsets", SetElem may throw an
2800   InvalidSetMException (see discussion above).
2802 | SetWithRefElem, ND, S(PtrToGen) S(Gen) S(Gen), MElem|Er
2804   Set element with key S1 in S0 to S2.
2806 | UnsetElem, ND, S(PtrToGen) S(Cell), MElem|Er
2808   Unsets the element at key S1 in the base S0.
2810 | SetOpElem<op>, D(Cell),
2811 |                S(PtrToGen) S(Cell) S(Cell),
2812 |                MElem|PRc|Er
2814   Set op elem with key S1 in base S0, using S2 as the right hand side.
2816 | IncDecElem, D(Cell), S(PtrToGen) S(Cell), MElem|PRc|Er
2818   Increment/decrement element with key S1 in base S0.
2820 | SetNewElem, ND, S(PtrToGen) S(Cell), MElem|Er
2822   Append the value in S1 to S0.
2824 | SetNewElemArray, ND, S(PtrToGen) S(Cell), MElem|Er
2826   Append the value in S1 to S0, where S0 must be a pointer to a array.
2828 | SetNewElemVec, ND, S(PtrToGen) S(Cell), MElem|Er
2830   Append the value in S1 to S0, where S0 must be a pointer to a vec.
2832 | SetNewElemKeyset, ND, S(PtrToGen) S(Int,Str), MElem|Er
2834   Append the value in S1 to S0, where S0 must be a pointer to a keyset.
2836 | BindNewElem, ND, S(PtrToGen) S(BoxedCell), MElem|Er
2838   Append the reference in S1 to S0.
2840 | ArrayIsset, D(Bool), S(Arr) S(Int,Str), NF
2842   Returns true iff the element at key S1 in the base S0 is set.
2844 | DictIsset, D(Bool), S(Dict) S(Int,Str), NF
2846   Returns true iff the element at key S1 in the base S0 is set.
2848 | KeysetIsset, D(Bool), S(Keyset) S(Int,Str), NF
2850   Returns true iff the element at key S1 in the base S0 is set.
2852 | StringIsset, D(Bool), S(Str) S(Int), NF
2854   Returns true iff the string S0 has a character at position S1.
2856 | VectorIsset, D(Bool), S(Obj) S(Int), NF
2858   Returns true iff the element at key S1 in the base S0 is set.
2860 | PairIsset, D(Bool), S(Obj) S(Int), NF
2862   Returns true iff the element at key S1 in the base S0 is set.
2864 | MapIsset, D(Bool), S(Obj) S(Int,Str), NF
2866   Returns true iff the element at key S1 in the base S0 is set.
2868 | IssetElem, D(Bool), S(PtrToGen) S(Cell), Er
2870   Returns true iff the element at key S1 in S0 is set.
2872 | EmptyElem, D(Bool), S(PtrToGen) S(Cell), Er
2874   Returns true iff the element at key S1 in S0 is set and not equal (as defined
2875   by the hhbc Eq instruction) to false.
2877 | DictEmptyElem, D(Bool), S(Dict) S(Int,Str), NF
2879   Like EmptyElem, but specialized for dicts.
2881 | KeysetEmptyElem, D(Bool), S(Keyset) S(Int,Str), NF
2883   Like EmptyElem, but specialized for dicts.
2885 | CheckRange, D(Bool), S(Int) S(Int), NF
2887   Returns true iff S0 is in the range [0, S1).
2889 | ThrowOutOfBounds, ND, S(ArrLike|Obj) S(Gen), Er|T
2891   Throws an OutOfBoundsException corresponding to an access of S0 with the key
2892   S1.
2894 | ThrowInvalidArrayKey, ND, S(ArrLike) S(Gen), Er|T
2896   Throws an InvalidArgumentException corresponding to an access of S0 with the
2897   key S1, which has a type invalid for that array.
2899 | ThrowInvalidOperation, ND, S(Str), Er|T
2901   Throws an InvalidOperationException with a message indicating S0.
2903 | ThrowArithmeticError, ND, S(Str), Er|T
2905   Throws an ArithmeticError with a message indicating S0.
2907 | ThrowDivisionByZeroError, ND, S(Str), Er|T
2909   Throws a DivisionByZeroError with a message indicating S0.
2911 | ProfileArrayKind, ND, S(Arr), NF
2913   Profile the array kind of S0.
2915 | ProfileType, ND, S(Gen), NF
2917   Profile the type of S0.
2919 | ProfileMethod<rdsHandle,spOff>, ND, S(StkPtr) S(Cls,Nullptr), NF
2921   Profile the Func in the ActRec that was just pushed onto the stack.
2923 | CheckPackedArrayDataBounds, ND, S(AK(Packed),Vec) S(Int), B
2925   Checks that the index in S1 is within the bounds of the packed array or
2926   vector array in S0. Branches to B if the index is out of bounds.
2928 | LdPackedArrayDataElemAddr<T>, DParamPtr(Elem), S(AK(Packed),Vec) S(Int), NF
2930   Loads the address of the element at index S1 of the packed array or vec array
2931   in S0. This instruction assumes the array actually contains an element at
2932   that offset (IE, the array has the proper length).
2934 | ReservePackedArrayDataNewElem, D(Int), S(AK(Packed),Vec), B
2936   If there is room in the packed or vec array (which is assumed to be mutable),
2937   increments the array size and returns the index of the new last element
2938   (which you must initialize); else jumps to the taken branch.
2940 | LdVecElem, DVecElem, S(Vec) S(Int), NF
2942   Loads the element of the vec array in S0 at offset S1. This instruction
2943   assumes that the vec actually contains an element at that offset (IE, the vec
2944   has the proper length).
2946 | LdVectorSize, D(Int), S(Obj), NF
2948   Returns the size of the given Vector collection in S0.
2950 | VectorDoCow, ND, S(Obj), NF
2952   Triggers a copy on write for a Vector that has a live ImmVector sharing
2953   the same copy of the elements.
2955 | VectorHasImmCopy, ND, S(Obj), B
2957   Given a vector, check if it has a immutable copy and jump to the taken branch
2958   if so.
2960 | ColAddNewElemC, DofS(0), S(Obj) S(Cell), Er|CRc|P
2962   Adds item S0 to the end of collection S0. Throws a fatal error if S0 is not a
2963   collection. Returns S0.
2965 | MapAddElemC, DofS(0), S(Obj) S(Cell) S(Cell), Er|CRc|P
2967   Adds item to a Map or ImmMap. Inserts item S2 into collection S0 at key S1.
2968   Throws a fatal error if S0 is not a collection. Returns S0.
2970 | ColIsEmpty, D(Bool), S(Obj), NF
2972 | ColIsNEmpty, D(Bool), S(Obj), NF
2974   Returns whether a collection instance is empty or not.  S0 must be known to
2975   be an instance of a collection class at compile time.
2978 19. Exception/unwinding support
2980 | BeginCatch, ND, NA, NF
2982   Marks the beginning of a catch region. Exact behavior is implementation and
2983   architecture specific.
2985 | EndCatch<spOffset>, ND, S(FramePtr) S(StkPtr), T
2987   Marks the end of a catch region and returns control to the unwinder.  The
2988   `spOffset' field represents a logical adjustment to S1 (in cells) to yield
2989   the vm stack pointer, however the stack pointer is not actually adjusted
2990   before this instruction returns control to the unwinder.  The unwinder
2991   instead relies on fixup map information to find the appropriate stack
2992   pointers.  Instead it's part of this instruction to facilitate assertions and
2993   memory effect analysis.
2995 | UnwindCheckSideExit, ND, S(FramePtr) S(StkPtr), B
2997   Branches to B if the currently executing catch region should return control
2998   to the unwinder rather than side exiting.  Used to control behavior in catch
2999   traces for the InvalidSetMException and TVCoercionException situations.
3001 | LdUnwinderValue<T>, DParam(Cell), NA, PRc
3003   Loads the value contained by the current unwinder exception.
3006 20. Function prologues
3008 | EnterFrame, ND, S(FramePtr), NF
3010   Stash the return address of the call in m_savedRip.
3012 | CheckStackOverflow, ND, S(FramePtr), Er
3014   Check if the stack depth has exceeded its limit.  If it has, jump to the
3015   stack overflow helper stub, which will throw.
3017 | InitExtraArgs<func,argc>, ND, S(FramePtr), NF
3019   Set up the ExtraArgs struct on the live ActRec.  If extra args are present
3020   and need to be discarded, they will be decref'd and may re-enter to run
3021   destructors.
3023 | InitCtx, ND, S(FramePtr) S(Ctx,Nullptr), CRc
3025   Store S1 to the m_this/m_cls field in the frame pointer S0.
3027   If InitCtx appears in an IR unit, it must dominate all occurrences of LdCtx
3028   and LdCctx with the same FramePtr.
3030 | CheckSurpriseFlagsEnter<func,argc>, ND, S(FramePtr), Er
3032   Test the implementation-specific surprise flags.  If they're nonzero, call
3033   the function enter helper.
3035 | CheckSurpriseAndStack<func,args>, ND, S(FramePtr), Er
3037   Test surprise flags and stack overflow at the same time.
3039 | CheckARMagicFlag, ND, S(FramePtr), B
3041   If the MagicDispatch flags on the ActRec pointed to by the frame pointer S0
3042   are not set, branch to block B.
3044 | LdARNumArgsAndFlags, D(Int), S(FramePtr), NF
3046   Load the value of m_numArgsAndFlags on the ActRec pointed to by the frame
3047   pointer S0.
3049 | StARNumArgsAndFlags, ND, S(FramePtr) S(Int), CRc
3051   Store S1 to m_numArgsAndFlags on the ActRec pointed to by the frame pointer
3052   S0.
3054 | LdARInvName, D(Str), S(FramePtr), NF
3056   Load the value of m_invName off the ActRec pointed to by the frame pointer S0.
3057   The compiler should generate this only if it knows that m_invName is a
3058   StringData* (rather than, e.g., a VarEnv*).
3060 | StARInvName, ND, S(FramePtr) S(Str,Nullptr), CRc
3062   Store S1 to m_invName on the ActRec pointed to by the frame pointer S0.
3064 | PackMagicArgs, D(Arr), S(FramePtr), PRc
3066   Call PackedArray::MakePacked() with the value of numArgs() on the ActRec
3067   pointed to by the frame pointer S0 as the first argument, and the pointer to
3068   the first parameter in the frame as the second argument.
3070 | LdTVAux<ValidBits>, D(Int), S(Gen), NF
3072   Load the value of m_aux from the TypedValue S0.  ValidBits is a mask
3073   specifying which bits are allowed to be set.  The runtime may ignore it.
3075   Note that when we pass TypedValues around in registers, we usually use a byte
3076   register for the m_type member, and thus ignore m_aux.  LdTVAux is only valid
3077   when we know that S0's m_type and m_aux were both materialized into the same
3078   64-bit register.
3080 /* Local Variables: */
3081 /* fill-column: 79 */
3082 /* End: */
3083 vim:textwidth=80