Add JIT support for vec/dict/keyset minstrs and related ops
[hiphop-php.git] / hphp / doc / ir.specification
blobce95e9dd1497a51c3a4934920185ee4264e5914b
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   r:Bool = IsType<T> s:Gen
107 By convention we use infix; destinations on the left, = represents assignment,
108 then the opcode name, and source parameters. Types are to the right of the
109 entities they modify, separated by : for results, sources, and variables, or
110 delimited by <> for instruction modifiers.
112 Instruction flags further describe their behavior:
114 HasDest
115 NaryDest
117   The instruction defines exactly one destination variable (HasDest) or a
118   varying number of destination variables (NaryDest). These flags are mutually
119   exclusive. An instruction with neither of these flags set has zero
120   destination variables.
122   Note that an instruction's destination variable may sometimes be a copy of
123   one of the input variables. (For example, AddElem returns the array it took
124   as an input.)
126 CallsNative
128   Indicates that the instruction will call a native helper.
130   The register allocator uses this to optimize register spills around native
131   calls and to bias register allocation toward arguments and return values.
133 ConsumesRC
135   The instruction consumes a reference to one or more of its sources, either by
136   decreasing its refcount or storing the reference to memory.
138 ProducesRC
140   The instruction produces a value with an unconsumed reference that must be
141   consumed, either by DecRefing it or storing it somewhere in memory.
143 MayRaiseError
145   The instruction may raise an error, and must have an edge to a catch block.
147 Terminal
149   The instruction has no next instruction; it either jumps, returns, or throws.
151 Branch
153   The instruction has a (sometimes optional) taken edge. Instructions that are
154   conditional branches (i.e. a Branch that is not Terminal) will also have a
155   next edge.
157 Passthrough
159   The value of the instruction's dest is the same as one of its inputs; it
160   differs only in the refcount of the underlying object, the type of the
161   variable, or some other property that doesn't affect the value of the
162   variable itself.
164 MInstrProp
166   The instruction may affect the type and/or value of its base operand,
167   operating on object properties.
169 MInstrElem
171   The instruction may affect the type and/or value of its base operand,
172   operating on array elements.
175 Instruction set
176 ---------------
178 1. Checks and Asserts
180 Note: Instructions that check boxed types only check that the operand is boxed,
181 and they ignore the type of the value inside the box (the inner type). The
182 inner type is normally checked when the value within the box is about to be
183 loaded, using a separate CheckRefInner instruction.
185 | CheckType<T>, DRefineS(0), S(Gen,Cls), B|P
187   Check that the type of the src S0 is T, and if so copy it to D, and
188   fallthrough. If S0 cannot be proven to be T, branch to block B. Note that
189   this means S0 still /may/ be a subtype of T in block B in some circumstances.
191   Specifically, subtypes of Type::Static may not be checked precisely,
192   depending on the type of the source.  This means the instruction may take the
193   branch in some circumstances even when S0 is a subtype of T, if T has a
194   non-empty intersection with Type::Static.
196   Also note that many types are not supported as the typeParam right now.
198 | CheckNullptr, ND, S(CountedStr,Nullptr), B|CRc
200   If S0 is not a null pointer, branch to block B. This is used to check the
201   return value of a native helper that returns a potentially null StringData*.
203 | AssertType, DRefineS(0), S(Gen,Cls,Ctx), P
205   Assert that the type of S0 is T, copying it to D.
207 | CheckTypeMem<T>, ND, S(PtrToGen), B
209   If the value pointed to by S0 is not type T, branch to the block B.
211 | HintLocInner<T,localId>, ND, S(FramePtr), NF
213   Hint that the inner type of a BoxedCell in localId is likely type T, where T
214   is a subtype of BoxedCell. The type must be guarded on before it is known to
215   be true (via LdRef).
217 | HintStkInner<T,offset>, ND, S(StkPtr), NF
219   Hint that the inner type of the BoxedInitCell on the stack pointed to by S0
220   at offset (in cells) is T. The type must be guarded on before it is known to
221   be true (via LdRef).
223 | CheckLoc<T,localId>, ND, S(FramePtr), B
225   Check that type of the given localId on the frame S0 is T; if not, branch to
226   block B.
228 | CheckStk<T,offset>, ND, S(StkPtr), B
230   Check that the type of the cell on the stack pointed to by S0 at offset (in
231   cells) is T; if not, branch to block B.
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   Returns a new frame pointer representing the same frame as S0 but with the
241   knowledge that the asserted local has type T.
243 | AssertStk<T,offset>, ND, S(StkPtr), NF
245   Assert that stack element at `offset' (in cells) from S0 has type T. This is
246   similar to a CheckStk except that it does not imply a runtime check and
247   cannot cause control flow.
249 | CastStk<T,offset>, ND, S(StkPtr), Er
251   Cast the stack element at `offset' (in cells) from S0 to type T.
253 | CastMem<T>, ND, S(PtrToGen), Er
255   Cast the TypedValue at S0 to type T.
257 The following instructions deal with parameter coercion (the standard type
258 conversion for arguments to HNI functions). If parameter coercion fails these
259 functions will throw a TVCoercion exception. They may throw other types of
260 exceptions depending on how coercion is implemented.
262 | CoerceStk<T,offset,fn,argNum>, ND, S(StkPtr), Er
264   Converts the stack slot at offset (in cells) to type T, with the semantics
265   needed for calling a builtin function. May throw a TVCoercionException in the
266   case of failed parameter coercion. The callee is f, and the position of the
267   argument being coerced is argNum.
269 | CoerceMem<T,fn,argNum>, ND, S(PtrToGen), Er
271   Coerces the TypedValue at S0 to type T, with the semantics
272   needed for calling a builtin function. May throw a TVCoercionException in the
273   case of failed parameter coercion. The callee is fn, and the position of the
274   argument being coerced is argNum.
276 | CoerceCellToBool<fn,argNum>, D(Bool), S(Cell), Er
278 | CoerceCellToInt<fn,argNum>,  D(Int), S(Cell), Er
280 | CoerceStrToInt<fn,argNum>,   D(Int), S(Str), Er
282 | CoerceCellToDbl<fn,argNum>,  D(Dbl), S(Cell), Er
284 | CoerceStrToDbl<fn,argNum>,   D(Dbl), S(Str), Er
286   These instructions convert either a Cell or a Str to a primitive type (Bool,
287   Int, Dbl) and return the resulting value. They may throw an exception upon
288   failed type coercion. They are encoded along with callee Func, fn, and the
289   integer position of the argument, argNum, being coerced.
291 | CheckInit, ND, S(Gen), B
293   If S0's type is Uninit, branch to block B.
295 | CheckInitMem, ND, S(PtrToGen), B
297   If the value pointed to by S0 has type Uninit, branch to block B.
299 | CheckCold<TransID>, ND, NA, B
301   Check if the counter associated with translation TransID is cold (i.e. within
302   a fixed threshold). If it's not (i.e. such translation has reached the
303   "hotness threshold"), then branch to block B.
305 | CheckRefs, ND, S(Func) S(Int) C(Int) S(Int) S(Int), B
307   Perform reffiness guard checks. Operands:
309     S0 - function pointer for the frame
310     S1 - num params expected in the func
311     S2 - first bit to check, must be a multiple of 64
312     S3 - mask to check (RefDeps::Record::m_mask entries)
313     S4 - values to check (RefDeps::Record::m_vals entries)
315   If any of the checks fail, branch to block B.
317 | EndGuards, ND, NA, NF
319   A no-op at runtime, this instruction serves to mark the end of the initial
320   sequence of guards in a trace.
322 | CheckNonNull, DSubtract(0, Nullptr), S(Nullptr,Func,PtrToGen,TCA,Cls), B
324   If the value in S0 is Nullptr, branch to block B.
326 | AssertNonNull, DSubtract(0, Nullptr), S(Nullptr,CountedStr,Func), P
328   Returns S0, with Nullptr removed from its type. This instruction currently
329   supports a very limited range of types but can be expanded if needed.
331 | CheckClosureStaticLocInit, ND, S(BoxedCell), B
333   Check if the closure static local represented by S0 is initialized, and if
334   not branch to block B.
336 2. Arithmetic
338 | AddInt, D(Int), S(Int) S(Int), NF
340 | SubInt, D(Int), S(Int) S(Int), NF
342 | MulInt, D(Int), S(Int) S(Int), NF
344 | AddIntO, D(Int), S(Int) S(Int), B
346 | SubIntO, D(Int), S(Int) S(Int), B
348 | MulIntO, D(Int), S(Int) S(Int), B
350 | AddDbl, D(Dbl), S(Dbl) S(Dbl), NF
352 | SubDbl, D(Dbl), S(Dbl) S(Dbl), NF
354 | MulDbl, D(Dbl), S(Dbl) S(Dbl), NF
356 | DivDbl, D(Dbl), S(Dbl) S(Dbl), NF
358 | DivInt, D(Int), S(Int) S(Int), NF
360 | Floor, D(Dbl), S(Dbl), NF
362 | Ceil, D(Dbl), S(Dbl), NF
364 | AbsDbl, D(Dbl), S(Dbl), NF
366 | Sqrt, D(Dbl), S(Dbl), NF
368 | AndInt, D(Int), S(Int) S(Int), NF
370 | OrInt, D(Int), S(Int) S(Int), NF
372 | XorInt, D(Int), S(Int) S(Int), NF
374 | Shl, D(Int), S(Int) S(Int), NF
376 | Shr, D(Int), S(Int) S(Int), NF
378   Double arithmetic, integer arithmetic, and integer bitwise operations.
379   Performs the operation described by the opcode name on S0 and S1, and puts
380   the result in D.
382   Undefined behavior occurs if Mod is given a divisor of zero, or if the
383   divisor is -1 and the dividend is the minimum representable integer.
385   AbsDbl computes the absolute value of a double-precision value.
387   DivDbl conforms to IEEE 754. In particular, division by zero returns +/- INF
388   or NAN depending on the dividend; and should the result of a division be zero
389   the sign will follow the normal sign rules for division.
391   DivInt will perform integer division of S1 by S0. S0 should not be zero and
392   must divide S1.
394   Note that Shr is an arithmetic right shift: The MSB is sign-extended.
396   Floor and Ceil will return an integral value not greater, or not less
397   than their input respectively. Their use requires SSE 4.1, availability
398   should be checked before they are emitted.
400   AddIntO, SubIntO, MulIntO perform integer arithmetic on S0 and S1, but will
401   branch to block B on integer overflow.
403 | XorBool, D(Bool), S(Bool) S(Bool), NF
405   Logical XOR of the two sources. (Note that && and || do not have
406   corresponding opcodes because they're handled at the bytecode level, to
407   implement short-circuiting.)
409 | Mod, D(Int), S(Int) S(Int), NF
411   Compute S0 mod S1. If S1 is -1 or 0 the results are undefined.
414 3. Type conversions
416 To array conversions:
418 | ConvBoolToArr,                D(Arr), S(Bool),                         PRc
420 | ConvDblToArr,                 D(Arr), S(Dbl),                          PRc
422 | ConvIntToArr,                 D(Arr), S(Int),                          PRc
424 | ConvObjToArr,                 D(Arr), S(Obj),                   Er|PRc|CRc
426 | ConvStrToArr,                 D(Arr), S(Str),                      PRc|CRc
428 | ConvVecToArr,                 D(Arr), S(Vec),                      PRc|CRc
430 | ConvDictToArr,                D(Arr), S(Dict),                     PRc|CRc
432 | ConvKeysetToArr,              D(Arr), S(Keyset),                   PRc|CRc
434 | ConvCellToArr,                D(Arr), S(Cell),                  Er|PRc|CRc
437 To vec conversions:
439 | ConvArrToVec,                 D(Vec), S(Arr),                   Er|PRc|CRc
441 | ConvDictToVec,                D(Vec), S(Dict),                     PRc|CRc
443 | ConvKeysetToVec,              D(Vec), S(Keyset),                   PRc|CRc
445 | ConvObjToVec,                 D(Vec), S(Obj),                   Er|PRc|CRc
448 To dict conversions:
450 | ConvArrToDict,                D(Dict), S(Arr),                  Er|PRc|CRc
452 | ConvVecToDict,                D(Dict), S(Vec),                     PRc|CRc
454 | ConvKeysetToDict,             D(Dict), S(Keyset),                  PRc|CRc
456 | ConvObjToDict,                D(Dict), S(Obj),                  Er|PRc|CRc
459 To keyset conversions:
461 | ConvArrToKeyset,              D(Keyset), S(Arr),                   PRc|CRc
463 | ConvVecToKeyset,              D(Keyset), S(Vec),                   PRc|CRc
465 | ConvDictToKeyset,             D(Keyset), S(Dict),                  PRc|CRc
467 | ConvObjToKeyset,              D(Keyset), S(Obj),                Er|PRc|CRc
470 To bool conversions:
472 | ConvArrToBool,               D(Bool), S(Arr),                           NF
474 | ConvDblToBool,               D(Bool), S(Dbl),                           NF
476 | ConvIntToBool,               D(Bool), S(Int),                           NF
478 | ConvStrToBool,               D(Bool), S(Str),                           NF
480 | ConvObjToBool,               D(Bool), S(Obj),                           NF
482 | ConvCellToBool,              D(Bool), S(Cell),                          NF
485 To double conversions:
487 | ConvArrToDbl,                 D(Dbl), S(Arr),                           NF
489 | ConvBoolToDbl,                D(Dbl), S(Bool),                          NF
491 | ConvIntToDbl,                 D(Dbl), S(Int),                           NF
493 | ConvObjToDbl,                 D(Dbl), S(Obj),                           Er
495 | ConvStrToDbl,                 D(Dbl), S(Str),                           NF
497 | ConvResToDbl,                 D(Dbl), S(Res),                           NF
499 | ConvCellToDbl,                D(Dbl), S(Cell),                          Er
502 To int conversions:
504 | ConvArrToInt,                 D(Int), S(Arr),                           NF
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 | ConvBoolToStr,          D(StaticStr), S(Bool),                          NF
528 | ConvDblToStr,                 D(Str), S(Dbl),                          PRc
530 | ConvIntToStr,                 D(Str), S(Int),                          PRc
532 | ConvObjToStr,                 D(Str), S(Obj),                       PRc|Er
534 | ConvResToStr,                 D(Str), S(Res),                       PRc|Er
536 | ConvCellToStr,                D(Str), S(Cell),                      PRc|Er
539   All the above opcodes convert S0 from its current type to the destination
540   type, according to the PHP semantics of such a conversion.
542 | ConvClsToCctx, D(Cctx), S(Cls), NF
544   Convert a class to a class context (i.e. the class with a 1 or'd into the low
545   bit).
547 | OrdStr,                       D(Int), S(Str),                           NF
549   Convert the first byte in a string to an unsigned integer.
550   Intended as an optimization for ord($str)
552 | OrdStrIdx,                    D(Int), S(Str) S(Int),                    Er
554   Convert the character at position S1 in base string S0 to an unsigned
555   integer.  Raises a notice if the position is out of bounds.
556   Intended as an optimization for ord($str[$idx]).
558 4. Boolean predicates
560 | GtInt,                       D(Bool), S(Int) S(Int),                    NF
562 | GteInt,                      D(Bool), S(Int) S(Int),                    NF
564 | LtInt,                       D(Bool), S(Int) S(Int),                    NF
566 | LteInt,                      D(Bool), S(Int) S(Int),                    NF
568 | EqInt,                       D(Bool), S(Int) S(Int),                    NF
570 | NeqInt,                      D(Bool), S(Int) S(Int),                    NF
572 | CmpInt,                      D(Int),  S(Int) S(Int),                    NF
574   Perform 64-bit integer comparisons.
576 | GtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
578 | GteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
580 | LtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
582 | LteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
584 | EqDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
586 | NeqDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
588 | CmpDbl,                      D(Int),  S(Dbl) S(Dbl),                    NF
590   Perform comparisons of doubles. Comparisons that are unordered according to
591   IEEE 754 (such as when at least one operand is NaN) result in false.
593 | GtStr,                       D(Bool), S(Str) S(Str),                    NF
595 | GteStr,                      D(Bool), S(Str) S(Str),                    NF
597 | LtStr,                       D(Bool), S(Str) S(Str),                    NF
599 | LteStr,                      D(Bool), S(Str) S(Str),                    NF
601 | EqStr,                       D(Bool), S(Str) S(Str),                    NF
603 | NeqStr,                      D(Bool), S(Str) S(Str),                    NF
605 | SameStr,                     D(Bool), S(Str) S(Str),                    NF
607 | NSameStr,                    D(Bool), S(Str) S(Str),                    NF
609 | CmpStr,                      D(Int),  S(Str) S(Str),                    NF
611   Performs comparison of strings using PHP semantics.
613 | GtStrInt,                    D(Bool), S(Str) S(Int),                    NF
615 | GteStrInt,                   D(Bool), S(Str) S(Int),                    NF
617 | LtStrInt,                    D(Bool), S(Str) S(Int),                    NF
619 | LteStrInt,                   D(Bool), S(Str) S(Int),                    NF
621 | EqStrInt,                    D(Bool), S(Str) S(Int),                    NF
623 | NeqStrInt,                   D(Bool), S(Str) S(Int),                    NF
625 | CmpStrInt,                   D(Int),  S(Str) S(Int),                    NF
627   Performs comparison of strings with integers using PHP semantics.
629 | GtBool,                      D(Bool), S(Bool) S(Bool),                  NF
631 | GteBool,                     D(Bool), S(Bool) S(Bool),                  NF
633 | LtBool,                      D(Bool), S(Bool) S(Bool),                  NF
635 | LteBool,                     D(Bool), S(Bool) S(Bool),                  NF
637 | EqBool,                      D(Bool), S(Bool) S(Bool),                  NF
639 | NeqBool,                     D(Bool), S(Bool) S(Bool),                  NF
641 | CmpBool,                     D(Int),  S(Bool) S(Bool),                  NF
643   Performs comparison of booleans.
645 | GtObj,                       D(Bool), S(Obj) S(Obj),                    Er
647 | GteObj,                      D(Bool), S(Obj) S(Obj),                    Er
649 | LtObj,                       D(Bool), S(Obj) S(Obj),                    Er
651 | LteObj,                      D(Bool), S(Obj) S(Obj),                    Er
653 | EqObj,                       D(Bool), S(Obj) S(Obj),                    Er
655 | NeqObj,                      D(Bool), S(Obj) S(Obj),                    Er
657 | SameObj,                     D(Bool), S(Obj) S(Obj),                    NF
659 | NSameObj,                    D(Bool), S(Obj) S(Obj),                    NF
661 | CmpObj,                      D(Int),  S(Obj) S(Obj),                    Er
663   Perform comparison of objects using PHP semantics. All versions except for
664   SameObj and NSameObj may re-enter the VM and therefore may throw
665   exceptions. SameObj and NSameObj never re-enter or throw.
667 | GtArr,                       D(Bool), S(Arr) S(Arr),                    Er
669 | GteArr,                      D(Bool), S(Arr) S(Arr),                    Er
671 | LtArr,                       D(Bool), S(Arr) S(Arr),                    Er
673 | LteArr,                      D(Bool), S(Arr) S(Arr),                    Er
675 | EqArr,                       D(Bool), S(Arr) S(Arr),                    Er
677 | NeqArr,                      D(Bool), S(Arr) S(Arr),                    Er
679 | SameArr,                     D(Bool), S(Arr) S(Arr),                    NF
681 | NSameArr,                    D(Bool), S(Arr) S(Arr),                    NF
683 | CmpArr,                      D(Int),  S(Arr) S(Arr),                    Er
685   Perform comparison of arrays using PHP semantics. All versions except for
686   SameArr and NSameArr may re-enter the VM and therefore may throw
687   exceptions. SameArr and NSameArr never re-enter or throw.
689 | GtVec,                       D(Bool), S(Vec) S(Vec),                    Er
691 | GteVec,                      D(Bool), S(Vec) S(Vec),                    Er
693 | LtVec,                       D(Bool), S(Vec) S(Vec),                    Er
695 | LteVec,                      D(Bool), S(Vec) S(Vec),                    Er
697 | EqVec,                       D(Bool), S(Vec) S(Vec),                    Er
699 | NeqVec,                      D(Bool), S(Vec) S(Vec),                    Er
701 | SameVec,                     D(Bool), S(Vec) S(Vec),                    NF
703 | NSameVec,                    D(Bool), S(Vec) S(Vec),                    NF
705 | CmpVec,                      D(Int),  S(Vec) S(Vec),                    Er
707   Perform comparison of vecs. All versions except for SameVec and NSameVec may
708   re-enter the VM and therefore may throw exceptions. SameVec and NSameVec
709   never re-enter or throw.
711 | EqDict,                      D(Bool), S(Dict) S(Dict),                  Er
713 | NeqDict,                     D(Bool), S(Dict) S(Dict),                  Er
715 | SameDict,                    D(Bool), S(Dict) S(Dict),                  NF
717 | NSameDict,                   D(Bool), S(Dict) S(Dict),                  NF
719   Perform comparison of dicts. EqDict and NeqDict may re-enter the VM and
720   therefore may throw exceptions. SameDict and NSameDict never re-enter or
721   throw. Relational comparisons for dicts are not supported.
723 | EqKeyset,                    D(Bool), S(Keyset) S(Keyset),              NF
725 | NeqKeyset,                   D(Bool), S(Keyset) S(Keyset),              NF
727   Perform comparison of keysets. As keysets can only contain ints and strings,
728   comparisons never re-enter or throw. Relational comparisons for keysets are
729   not supported.
731 | GtRes,                       D(Bool), S(Res) S(Res),                    NF
733 | GteRes,                      D(Bool), S(Res) S(Res),                    NF
735 | LtRes,                       D(Bool), S(Res) S(Res),                    NF
737 | LteRes,                      D(Bool), S(Res) S(Res),                    NF
739 | EqRes,                       D(Bool), S(Res) S(Res),                    NF
741 | NeqRes,                      D(Bool), S(Res) S(Res),                    NF
743 | CmpRes,                      D(Int),  S(Res) S(Res),                    NF
745   Perform comparison of resources using PHP semantics. Resource comparisons
746   never re-enter or throw.
748 | EqCls,                       D(Bool), S(Cls) S(Cls),                    NF
750   Checks if two Class values are equal.
752 | EqFunc,                      D(Bool), S(Func) S(Func),                  NF
754   Checks if two Func values are equal.
756 | InstanceOf, D(Bool), S(Cls) S(Cls|Nullptr), NF
758   Sets D based on whether S0 is a descendant of the class, interface, or trait
759   in S1. (Note that this is always false for a trait). S1 may be null at
760   runtime if the class is not defined.
762 | InstanceOfIface, D(Bool), S(Cls) CStr, NF
764   Fast path for interface checks. Sets D based on whether S0 implements S1, but
765   S1 must be a unique interface. This should only be used in repo-authoritative
766   mode.
768 | InstanceOfIfaceVtable<iface>, D(Bool), S(Cls), NF
770   Faster path for interface checks. Sets D based on whether S0 implements
771   iface, which must be a unique interface with an assigned vtable slot.
773 | ExtendsClass<cls,strictLikely>, D(Bool), S(Cls), NF
775   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
776   of cls, where cls must be a unique class that is not an interface or a trait.
778   If strictLikely is true, optimize for the case where S0 is not equal to S1.
780 | InstanceOfBitmask,           D(Bool), S(Cls) CStr,                      NF
782 | NInstanceOfBitmask,          D(Bool), S(Cls) CStr,                      NF
784   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
785   of the class named by S1, where S1 must have a bit allocated for it in the
786   fast instance check bitvector (see class.h).
788 | InterfaceSupportsArr,        D(Bool), S(Str), NF
790 | InterfaceSupportsVec,        D(Bool), S(Str), NF
792 | InterfaceSupportsDict,       D(Bool), S(Str), NF
794 | InterfaceSupportsKeyset,     D(Bool), S(Str), NF
796 | InterfaceSupportsStr,        D(Bool), S(Str), NF
798 | InterfaceSupportsInt,        D(Bool), S(Str), NF
800 | InterfaceSupportsDbl,        D(Bool), S(Str), NF
802   Returns whether t instanceof S0 returns true when t is of the given type.
804 | HasToString, D(Bool), S(Obj), NF
806   Returns whether the object S0 has a toString method.
808 | IsType<T>, D(Bool), S(Cell), NF
810   Sets D to true iff S0 holds a value that is of type T. T must not be a
811   specialized type.
813 | IsNType<T>, D(Bool), S(Cell), NF
815   Sets D to true iff S0 holds a value that is not of type T. T must not be a
816   specialized type.
818 | IsTypeMem<T>, D(Bool), S(PtrToGen), NF
820   Sets D to true iff the value referenced by S0 is of type T. T must not be a
821   specialized type.
823   The value in S0 must not be a pointer into the evaluation stack or frame
824   locals.
826 | IsNTypeMem<T>, D(Bool), S(PtrToGen), NF
828   Sets D to true iff the value referenced by S0 is not of type T. T must not be
829   a specialized type.
831 | IsScalarType, D(Bool), S(Cell), NF
833   Returns true if S0 is of type Int, Bool, Dbl or Str. Returns false otherwise.
835 | IsWaitHandle, D(Bool), S(Obj), NF
837   Sets D to true iff S0 is a subclass of WaitHandle.
839 | IsCol, D(Bool), S(Obj), NF
841   Sets D to true iff S0 is a collection.
844 5. Branches
846 | JmpZero,                          ND, S(Int,Bool),                     B
848 | JmpNZero,                         ND, S(Int,Bool),                     B
850   Conditionally jump to based on S0.
852 | JmpSSwitchDest, ND, S(TCA) S(StkPtr) S(FramePtr), T
854   Jump to the target of a sswitch statement, leaving the region, where the
855   target TCA is S0.
857 | JmpSwitchDest, ND, S(Int) S(StkPtr) S(FramePtr), T
859   Jump to the target of a switch statement, leaving the region, using table
860   metadata <JmpSwitchData> and index S0, which must be a valid index in the
861   jump table.
863 | ProfileSwitchDest<handle,nCases>, ND, S(Int), NF
865   Profile a switch statement target.
867 | CheckSurpriseFlags, ND, S(FramePtr,StkPtr), B
869   Tests the implementation-specific surprise flags. If they're true, branches
870   to block B. This is done by comparing an evaluation stack pointer to the RDS
871   stackLimitAndSurprise word. Note that in a resumed, the frame pointer is not
872   pointing into the eval stack, so S0 should be a StkPtr in that case.
874 | ReturnHook, ND, S(FramePtr) S(Gen), Er
876   Surprise flag hook for function returns.
878 | SuspendHookE, ND, S(FramePtr) S(FramePtr) S(Obj), Er
880   Surprise flag hook for suspending eagerly executing async functions or
881   generators.  Decrefs S2 if it throws an exception.
883 | SuspendHookR, ND, S(FramePtr) S(Obj|Nullptr), Er
885   Surprise flag hook for suspending resumed async functions or generators.  For
886   generators, the second parameter should be Nullptr.
888 | Halt, ND, NA, T
890   Halt execution. Used only in tests or unreachable code.
892 | Jmp, ND, SVar(Top), B|T
894   Unconditional jump to block B. In the second form, the target block must
895   start with a DefLabel with the same number of destinations as Jmp's number of
896   sources. Jmp parallel-copies its sources to the DefLabel destinations.
898 | DefLabel, DMulti, NA, NF
900   DefLabel defines variables received from a previous Jmp. A DefLabel with zero
901   destinations is a no-op, and the predecessor blocks may not necessarily end
902   in Jmp. A DefLabel with one or more destinations may only be reached by a Jmp
903   instruction with the same number of sources. Ordinary branch instructions may
904   not pass values to a DefLabel.
907 6. Reference manipulation
909 | Box, D(BoxedInitCell), S(Cell), CRc|PRc
911   Box S0 and put the resulting BoxedInitCell in D. If S0 is Uninit, then
912   InitNull will be boxed instead.
914 | UnboxPtr, DUnboxPtr, S(PtrToGen), NF
916   If S0 points to a cell that is KindOfRef, dereference the pointer in the
917   TypedValue and return a pointer to the inner-cell in D.
919 | BoxPtr, DBoxPtr, S(PtrToGen), NF
921   Boxes the TypeValue that S0 points to if it is not boxed. The result D points
922   to the same TypedValue as S0 but has a more refined type.
924   S0 may not already point into a RefData (due to VM invariants), although the
925   IR type system does not enforce it.
928 7. Loads
930 | LdStk<T,offset>, DParamMayRelax, S(StkPtr), NF
932   Loads from S0 at offset (in cells), and puts the value in D as type T.
934 | LdLoc<T,localId>, DParamMayRelax, S(FramePtr), NF
936   Loads local slot localId from the frame S0 and puts the value in D as type T.
938 | LdLocPseudoMain<T,localId>, DParam, S(FramePtr), B
940   Loads local number localId from frame S0 and puts the value in D if the
941   local's type is a subtype of T. If the local's type is not a subtype of T,
942   then the load does not happen, and this instruction branches to B. This
943   instruction is used for loading locals in pseudo-mains, where they can alias
944   globals.
946 | LdStkAddr<T,offset>, D(PtrToStkGen), S(StkPtr), NF
948   Loads the address of the stack slot given by the pointer in S0 at the offset
949   (in cells). T must be a subtype of PtrToStkGen.
951 | LdLocAddr<localId>, D(PtrToFrameGen), S(FramePtr), NF
953   Loads the address of the local slot localId from the frame S0 into D.
955 | LdRDSAddr<T,RDSHandle>, DParam, NA, NF
957   Load the address of a Gen that lives at the specified RDS handle. The type
958   param must be a subtype of PtrToGen.
960 | LdVectorBase, D(PtrToMembCell), S(Obj), NF
962 | LdPairBase, D(PtrToMembCell), S(Obj), NF
964   Loads the base pointer to an array of Cells from the given collection
965   instance in S0.
967 | LdMem<T>, DParam, S(PtrToGen), NF
969   Loads from S0 and puts the value in D.
971 | LdContField<T>, DParam, S(Obj) C(Int), NF
973   Loads a property from the object referenced by S0 at the offset given by S1
974   and puts the value in D. S0 must be a Generator.
976 | LdElem, D(Cell), S(PtrToCell) S(Int), NF
978   Loads the element at index S1 from the base pointer in S0. The index in S1 is
979   the number of bytes from the base in S0.
981 | LdColArray, D(Arr), S(Obj), NF
983   Load the array backing a collection instance in S0, which must be a Vector,
984   Map, Set, ImmVector, ImmMap, or ImmSet, and that specific object type must be
985   known at compile time.
987 | CheckRefInner<T>, ND, S(BoxedCell), B
989   TODO(#2939547): this should take BoxedInitCell
991   Check that the inner type of the boxed cell in S0 is T, and if not take the
992   branch to B.
994 | LdRef<T>, DParam, S(BoxedCell), NF
996   TODO(#2939547): this should take BoxedInitCell
998   Loads the value held in the box referenced by S0 and puts the value in D. The
999   inner type of S0 must be a subtype of T (usually ensured with a previous
1000   CheckRefInner).
1002 | LdCtx, DCtx, S(FramePtr), NF
1004   Loads into D the value of the m_this/m_cls field out of the frame pointer S0,
1005   which must be a frame for the function in the LdCtx's marker. The result
1006   could be either an object representing the this pointer or a class context.
1008 | LdCctx, DCtx, S(FramePtr), NF
1010   Loads into D the value of the m_cls field out of the frame pointer S0. The
1011   compiler should generate this only if it can prove that the frame does not
1012   contain a nullptr or $this pointer.
1014 | LdClosure<T>, DParam, S(FramePtr), NF
1016   Loads into D the value of the m_this/m_cls field out of the frame pointer S0.
1017   The compiler should generate this only if it can prove that the frame context
1018   is a closure object of type T.  Unlike LdCtx and LdCctx, there are no special
1019   rules about the relative positions of LdClosure and InitCtx instructions.
1021 | CheckCtxThis, ND, S(Ctx), B
1023   Check that the context (m_this or m_cls) in S0 is a non-null $this
1024   pointer. If not, branch to B.
1026 | CastCtxThis, DThis, S(Ctx), P
1028   Convert a Ctx known to contain a $this pointer to a specific object type,
1029   based on the marker func for this instruction.
1031 | LdClsCtx, D(Cls), S(Ctx), NF
1033   Loads into D the class representing the current context. Extracts the class
1034   from S0, which can be either the this pointer or the context class.
1036 | LdClsCctx, D(Cls), S(Cctx), NF
1038   Loads into D the class representing the current context. Extracts the class
1039   from the S0, which is a context class.
1041 | LdClsCtor, D(Func), S(Cls) S(FramePtr), Er
1043   Loads into D the constructor of class S0. If the constructor cannot be called
1044   from the context in S1, raise an error.
1046 | DefConst<T>, DParam, NA, NF
1048   Define a constant value of type T. D is presumed to be globally available and
1049   the DefConst instruction will not actually appear in the IR instruction
1050   stream.
1052 | Conjure<T>, DParam, NA, NF
1054   Define a value of type T. This instruction aborts at runtime; it is meant to
1055   be used in tests or code that is known to be unreachable.
1057 | ConjureUse, ND, S(Gen), NF
1059   Define a "use" of S0 effectively keeping the value alive. As with Conjure it
1060   should not appear in reachable code.
1062 | LdCls, D(Cls), S(Str) C(Cls), Er
1064   Loads the class named S0 in the context of the class S1. Invokes autoload and
1065   may raise an error if the class is not defined. The explicit context
1066   parameter allows the compiler to simplify this instruction to a DefConst in
1067   some cases. If S0 is constant, this instruction may be simplified to a
1068   LdClsCached.
1070 | LdClsCached, D(Cls), CStr, Er
1072   Loads the class named S0 via the RDS. Invokes autoload and may raise an error
1073   if the class is not defined.
1075 | LdClsCachedSafe, D(Cls), CStr, B
1077   Loads the class whose name is S0 out of the RDS. If the class is not defined,
1078   branch to B.
1080 | LdClsInitData, D(PtrToClsInitCell), S(Cls), NF
1082   Loads the pointer to the property initializer array for class S0.
1084 | LookupClsRDS, D(Cls|Nullptr), S(Str), NF
1086   Lookup the cached-class RDS handle for a given class name. Dereference that
1087   handle and return the associated Class, or null if not present.
1089 | LdCns, DCns, CStr, B|PRc
1091   Load the constant named S0, branching to B if isn't present.
1093 | LookupCns<T,constName>,   DCns, CStr, Er|PRc
1095 | LookupCnsE<T,constName>,  DCns, CStr, Er|PRc
1097   Load a constant via the RDS. Raises an undefined constant notice if the
1098   constant cannot be defined.  The E variant will instead throw a fatal error if
1099   it cannot define the constant.  These should only be executed if LdCns on the
1100   same constant has failed.
1102 | LookupCnsU<T,constName,fallbackName>, DCns, CStr CStr, Er|PRc
1104   Load an unqualified constant via the RDS, first by trying constName, then by
1105   trying fallbackName.  Raises a notice if neither can be found.  Should only
1106   be executed if LdCns on the same constant has failed.
1108 | LdClsCns<className,constantName>, D(PtrToGen), NA, B
1110   Load the address of the constant 'constantName' for the class 'className' in
1111   RDS. If not initialized, branch to B.
1113 | LdClsMethodFCacheFunc<clsName,methodName>, D(Func), NA, B
1115   Loads the target cache entry for a forwarding call to clsName::methodName.
1116   If the method does not exist, or the cache hasn't been filled yet, branch to
1117   B.
1119 | LookupClsMethodFCache<clsName,methodName>,
1120 |    D(Func|Nullptr), C(Cls) S(FramePtr),
1121 |    Er
1123   Lookup clsName::methodName in the forwarding class method cache. S0 should be
1124   the Class named by clsName and S1 should be the current vm frame pointer. May
1125   return Nullptr if lookup fails using a subset of the required lookup paths,
1126   indicating that a more complete lookup path should be taken. May throw if the
1127   method does not exist.
1129 | GetCtxFwdCallDyn<clsName,methodName>, D(Ctx), S(Ctx), PRc
1131   If S0 is a Cctx, return S0. If S0 is an object, check if clsName::methodName
1132   is a static method. If it is, return S0's class as a Ctx pointer. If not,
1133   return S0. If S0 is a Ctx, dynamically check if it is a non-null object
1134   pointer or Cctx at runtime and perform the operations described above. This
1135   instruction must only be used when the value is known to not be empty.
1137 | GetCtxFwdCall, D(Ctx), S(Ctx) C(Func), PRc
1139   If S0 is an object and S1 is static, this opcode returns S0's class with the
1140   low bit set (i.e., as a Cctx). If S0 is an object and S1 is not static, this
1141   opcode increfs S0 and returns it. If S0 is a Cctx, this opcode returns S0.
1143 | LdClsMethodCacheFunc<clsName,methodName>, D(Func), NA, B
1145   Loads the target cache entry for the method clsName::methodName. If the
1146   method does not exist or the cache hasn't been filled yet, branch to B.
1148 | LdClsMethodCacheCls<clsName,methodName>, D(Cctx), NA, NF
1150   Loads the target cache class context entry for a call to clsName::methodName
1151   from the current context. This instruction must only be used when the value
1152   is known to not be empty (i.e., LdClsMethodCacheFunc must have succeeded, or
1153   LookupClsMethodCache returned a non-null value).
1155 | LookupClsMethodCache<clsName,methodName>, D(Func|Nullptr),
1156 |                                           S(FramePtr),
1157 |                                           Er
1159   Lookup a function in the class method targetcache. The class name and method
1160   name are clsName and methodName, respectively. S0 is the current vm frame
1161   pointer. Returns Nullptr if the method cannot be found using a subset of the
1162   required lookup paths, indicating that a more complete lookup path should be
1163   taken. May throw if the method does not exist.
1165 | LdIfaceMethod<vtableIdx,methodIdx>, D(Func), S(Cls), NF
1167   Load the Func* at methodIdx from the vtable at vtableIdx in S0.
1169 | LdFuncVecLen, D(Int), S(Cls,Cctx), NF
1171   Load the funcVecLen field from S0.
1173 | LdClsMethod, D(Func), S(Cls,Cctx) C(Int), NF
1175   Load a Func* off of the class method table for S0, at offset S1 (in method
1176   slots).
1178 | LookupClsMethod<offset>, ND, S(Cls) S(Str) S(StkPtr) S(FramePtr), Er
1180   Store a pointer to a class method into an activation record. S0 points to the
1181   class, S1 is the method name, S2 is a stack pointer that has an activation
1182   record to modify at `offset', and S3 is a pointer to the current frame (used
1183   to get the context). May throw or fatal if method is not accessible.
1185 | LdPropAddr<T,offset>, DParamPtr(Prop), S(Obj), NF
1187   Load the address of the object property for S0 + `offset' (in bytes).  T must
1188   be a subtype of PtrToPropGen.
1190 | LdGblAddr, D(PtrToGblGen), S(Str), B
1192   Loads a pointer to a global. S0 is the global's name. Branches to B if the
1193   global is not defined.
1195 | LdGblAddrDef, D(PtrToGblGen), S(Str), NF
1197   Loads a pointer to a global. S0 is the global's name. Defines the global if
1198   it is not already defined.
1200 | LdClsPropAddrOrNull, D(PtrToSPropGen|Nullptr),
1201 |                      S(Cls) S(Str) C(Cls),
1202 |                      Er
1204   Loads a pointer to a static class property. S0 points to the class, S1 is the
1205   property name, and S2 is the class representing the context of the code
1206   accessing the property. If class S0 does not have a visible and accessible
1207   static property named S1, then nullptr is returned.
1209 | LdClsPropAddrOrRaise, D(PtrToSPropGen), S(Cls) S(Str) C(Cls), Er
1211   Loads a pointer to a static class property. S0 points to the class, S1 is the
1212   property name, and S2 is the class representing the context of the code
1213   accessing the property. If class S0 does not have a visible and accessible
1214   static property named S1, throw a fatal error.
1216 | LdObjMethod<offset,methodName,fatal>, ND, S(Cls) S(StkPtr), Er
1218   Stores a pointer to an object's method into an activation record. S0 points
1219   to the object's class, S1 has the pre-live activation record at `offset'.
1220   Caches the mapping in the target cache. If `fatal' is true, raises a fatal if
1221   the class does not have an accessible method with the given name and does not
1222   have a __call method; otherwise (if `fatal' is false), raises a warning and
1223   puts func that does nothing and returns null (SystemLib::s_nullFunc) on the
1224   activation record.
1226 | LdObjInvoke, D(Func), S(Cls), B
1228   Try to load a cached non-static __invoke Func from the Class in S0, or branch
1229   to block B if it is not present.
1231 | LdArrFuncCtx<offset>, ND, S(Arr) S(StkPtr) S(FramePtr), Er
1233   Try to load an array as a function context. This is for use translating
1234   FPushFunc when the callee is an array. This instruction attempts to populate
1235   a partially created ActRec pointed to by S1 + `offset' (in cells).
1237 | LdArrFPushCuf<offset>, ND, S(Arr) S(StkPtr) S(FramePtr), Er
1239 | LdStrFPushCuf<offset>, ND, S(Str) S(StkPtr) S(FramePtr), Er
1241   Try to resolve a method target for FPushCuf when the callee is an Arr or Str,
1242   respectively. These instructions mutate a partially created ActRec pointed to
1243   by S1 + `offset' (in cells).
1245 | LdObjClass, DLdObjCls, S(Obj), NF
1247   Load the class out of the object in S0 and put it in D.
1249 | LdClsName, D(StaticStr), S(Cls), NF
1251   Load the name of the Class* in S0.
1253 | LdFunc, D(Func), S(Str), CRc|Er
1255   Loads the Func whose name is S0. Fatal if the named function is not defined,
1256   and the function autoloader fails to define it.
1258 | LdFuncCached<funcName>, D(Func), NA, Er
1260   Loads the Func whose name is funcName from the RDS, invoking autoload if it
1261   not defined yet. Fatal if function autoloader fails to define it.
1263 | LdFuncCachedU<funcName,fallbackName>, D(Func), NA, Er
1265   Try to load a Func named funcName from the RDS, if it isn't defined, try to
1266   load a Func named fallbackName. If that also isn't defined, invoke autoload.
1267   If this still doesn't result in a Func, raise a fatal error.
1269 | LdFuncCachedSafe<funcName>, D(Func), NA, B
1271   Try to load the Func named funcName from the RDS. If the function is not
1272   defined, branch to B.
1274 | LdARFuncPtr<offset>, D(Func), S(StkPtr), NF
1276   Loads the m_func member of an ActRec. S0 is the base address, with `offset'
1277   cells to the ActRec.
1279 | LdARNumParams, D(Int), S(FramePtr), NF
1281   Loads the number of params from an ActRec. S0 is the address of the ActRec
1283 | LdFuncNumParams, D(Int), S(Func), NF
1285   Returns the value of func->numParams().
1287 | LdStrLen, D(Int), S(Str), NF
1289   Load the length of the string in S0.
1291 | LdClosureStaticLoc, D(BoxedCell), CStr S(FramePtr), NF
1293   Get boxed value to initialize static local named S0 in frame S1, where S1
1294   must be either a closure or generatorFromClosure function.
1296 | LdStaticLoc<func,staticLocalName>, D(BoxedInitCell), NA, B
1298   Load the address of the static local variable named 'staticLocalName' for
1299   function 'func' in RDS. If the variable isn't initialized, branch to B.
1301 8. Allocation
1303 | AllocObj, DAllocObj, S(Cls), PRc|Er
1305   Allocates a new object of class S1.
1307 | RegisterLiveObj, ND, S(Obj), NF
1309   When EnableObjDestructCall is on, we need to keep track of objects to be able
1310   to call their destructors when a request exists.  This instruction is
1311   conditionally emitted to implement that.
1313 | CheckInitProps<class>, ND, NA, B
1315   Check if the properties for class are initialized and branches if not.
1317 | InitProps<class>, ND, NA, Er
1319   Calls the property initializer function (86pinit) for class.  May throw.
1321 | CheckInitSProps<class>, ND, NA, B
1323   Check if static properties for class are initialized and branches if not.
1325 | InitSProps<class>, ND, NA, Er
1327   Calls the static property initializer function (86sinit) for class. May
1328   throw.
1330 | DebugBacktrace, D(Arr), S(Int), PRc
1332   Obtain stack trace by calling the debug_backtrace() method.
1334 | InitThrowableFileAndLine, ND, S(Obj), NF
1336   Initialize Throwable's file name and line number assuming the stack trace
1337   was already initialized and the current vmfp() is a built-in.
1339 | NewInstanceRaw<class>, DAllocObj, NA, PRc
1341   Allocates an instance of class.
1343 | InitObjProps<class>, ND, S(Obj), NF
1345   Initializes properties of object S0.
1347 | ConstructInstance<class>, DAllocObj, NA, Er
1349   Call the custom instance constructor of an extension class.
1351 | NewArray, D(Arr), C(Int), PRc
1353   Allocate a new array with the expected capacity S0.
1355 | NewMixedArray, D(Arr), C(Int), PRc
1357   Allocate a new array in mixed mode with the expected capacity S0.
1359 | NewDictArray, D(Dict), C(Int), PRc
1361   Allocate a new dict with the expected capacity S0.
1363 | NewKeysetArray<offset,keys>, D(Keyset), S(StkPtr), PRc|CRc|Er
1365   Allocate a new keyset containing N elements off the stack given by S0, at
1366   `offset'. This instruction moves the elements off the stack without
1367   manipulating their reference counts.
1369 | NewLikeArray, D(Arr), S(Arr) C(Int), PRc
1371   Allocate a new array in the same mode as S0 and with expected capacity S1,
1372   unless S1 == 0, in which case the capacity is set to S0's size.
1374 | AllocPackedArray<size>, DArrPacked, NA, PRc
1376   Allocate a new uninitialized packed array with space for size elements in it.
1377   The array will be initialized with values using either InitPackedLayoutArray
1378   or InitPackedLayoutArrayLoop.
1380 | AllocVecArray<size>, D(Vec), NA, PRc
1382   Allocate a new uninitialized vector array with space for size elements in it.
1383   The array will be initialized with values using either InitPackedLayoutArray
1384   or InitPackedLayoutArrayLoop.
1386 | InitPackedLayoutArray<index>, ND, S(Arr,Vec) S(Cell), CRc
1388   Store the S1 into the slot at index in array S0. This instruction assumes
1389   that it doesn't have to incref the value being stored. Used to initialize an
1390   array allocated with AllocPackedArray or AllocVecArray.
1392 | InitPackedLayoutArrayLoop<offset,size>, ND, S(Arr,Vec) S(StkPtr), CRc
1394   Move `size' elements from the stack given by S1, at `offset', into the array
1395   S0.  Assumes that the first element on the stack is the last element in the
1396   array.  Used to initialize an array allocated with AllocPackedArray or
1397   AllocVecArray that was too big to use a series of InitPackedLayoutArray
1398   instructions.
1400 | NewStructArray<offset,keys...>, D(Arr), S(StkPtr), PRc|CRc
1402   Allocate a new key/value array, given N immediate keys and taking N elements
1403   off the stack given by S0, at `offset'. This instruction assumes it can take
1404   the values from the stack without increfing them.
1406 | NewCol<type>, DCol, NA, PRc
1408   Create an empty new collection of `type'.
1410 | NewColFromArray<type>, DCol, S(Arr), PRc|CRc
1412   Create a collection of `type` from an array. `type` cannot be Pair. The array
1413   will be used to back the new collection without duplication or conversion.
1414   Thus it should not contain references. In addition, the array must be in
1415   packed mode when `type` is Vector or ImmVector, and must be in mixed mode
1416   otherwise. Ownership of the array is transferred from $1 to the collection,
1417   without manipulating the refcount.
1419 | Clone, DofS(0), S(Obj), PRc|Er
1421   Allocate an object by cloning S0.
1424 9. Call & Return
1426 | SpillFrame<offset,numArgs,invName>,
1427 |   ND,
1428 |   S(StkPtr) S(Func,Nullptr) S(Ctx,Cls,Nullptr),
1429 |   CRc
1431   Operands:
1433      S0 - caller stack pointer
1434      S1 - callee Func or nullptr
1435      S2 - object (for FPushObjMethod*), class (for FPushClsMethod*), context
1436           (for FPushClsMethodF), or nullptr (for FPushFunc*).
1438   Defines the fields for an activation record and writes them to the stack
1439   pointed to by S0, at `offset'.
1441 | CufIterSpillFrame<offset,numArgs,iterId>, ND,
1442 |                                           S(StkPtr) S(FramePtr),
1443 |                                           NF
1445   Operands:
1447      S0 - caller stack pointer
1448      S1 - caller frame pointer
1450   Defines the fields for an activation record using data from the iterator
1451   iterId, and writes them to the stack pointed to by S1, at offset.
1453 | FreeActRec, D(FramePtr), S(FramePtr), NF
1455   Load the saved frame pointer from the activation record pointed to by S0 into
1456   D.
1458 | BeginInlining<offset>, ND, S(StkPtr), NF
1460   Marks the start of an inlined function whose stack resides offset cells below
1461   the SP. It has no effect other than to hint to optimization passes that at the
1462   start of the inlined function its stack is dead.
1464 | DefInlineFP<func,retBCOff,retSPOff>, D(FramePtr),
1465 |                                      S(StkPtr) S(FramePtr),
1466 |                                      NF
1468   Defines a frame pointer for an inlined function.
1470   `func' is the function being inlined. `retBCOff' and `retSPOff' represent
1471   what the bytecode and stack offsets should be after the FCall instruction in
1472   ther caller.
1474   This instruction is primarily used to represent a frame in the IR in a way
1475   that allows us to eliminate it entirely. When it cannot be eliminated (or if
1476   it is pushed into an unlikely path) it performs callee-side responsibilities
1477   for setting up an activation record (i.e. setting the return ip and m_soff,
1478   storing the frame pointer into D).
1480   The caller frame pointer is passed as S1. This is used to keep track of the
1481   call chain of inlined functions for simplification and dead code elimination.
1483 | InlineReturn, ND, S(FramePtr), NF
1485   Unlinks a frame constructed by DefInlineFP.
1487 | InlineReturnNoFrame<InlineFrameStart>, ND, NA, NF
1489   Mark the end of an inlined function for which no DefInlineFP was required. The
1490   primary purpose of this instruction is to mark the result of a SpillFrame as
1491   dead. InlineFrameStart is the caller FP-relative offset of the start of the
1492   callee frame. Everything below InlineFrameStart is dead.
1494 | CallArray<spOffset,numParams,callOff,after,destroyLocals>,
1495 |                       D(Gen),
1496 |                       S(StkPtr) S(FramePtr),
1497 |                       Er
1499   Invoke function corresponding to the current FPI with numParams arguments,
1500   the last of which is an array of the remaining args. Used for FCallArray (in
1501   which case numParams == 1), and FCallUnpack. S0+spOffset points to the stack
1502   resulting after the ActRec for the function and numParams arguments have been
1503   pushed. CallArray pops the array off the stack, pushes the elements of the
1504   array as arguments, and invokes the function in the ActRec.
1506 | SyncReturnBC<spOffset,bcOffset>, ND, S(StkPtr) S(FramePtr), NF
1508   Stores bcOffset into the frame at spOffset from S0 as the return bytecode
1509   address and the frame S1 as the return frame.
1511 | Call<offset,numParams,returnOff,funcd,destroyLocals>, D(Gen),
1512 |                                                       S(StkPtr) S(FramePtr),
1513 |                                                       Er
1515   Transfer control to a callee, based on the pre-live activation record and set
1516   of args on the stack pointed to by S0 at `offset'. S1 is the current caller
1517   frame pointer. The `funcd' in the extra data is a Func* for the callee if we
1518   know the callee statically.
1520 | NativeImpl<func>, ND, S(FramePtr) S(StkPtr), Er
1522   Execute a call to the native builtin specified by the current function. S0
1523   and S1 should be the current vmfp and vmsp, respectively.
1525 | CallBuiltin<T>, DBuiltin, S(FramePtr) S(StkPtr) SVar(PtrToGen,Gen,Cls,Nullptr), Er|PRc
1527   Call builtin function with N arguments. S0 and S1 should be the current vmfp
1528   and vmsp, respectively.
1530   The source and destination types correspond to C++ parameter and return types
1531   as follows:
1533     C++ type            HHIR type         Position
1534     -----------------   ---------         --------
1535     bool                Bool              source, destination
1536     int64_t             Int               source, destination
1537     double              Dbl               source, destination
1538     const String&       PtrToStr          source
1539     const Array&        PtrToArr          source
1540     const Object&       PtrToObj          source
1541     const Variant&      PtrToGen          source
1542     Variant&            PtrToGen          source (ref param)
1543     String              {Str|InitNull}    destination
1544     Array               {Arr|InitNull}    destination
1545     Object              {Obj|InitNull}    destination
1546     Variant             {Gen-UninitNull}  destination
1548 | RetCtrl<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Gen), T
1550   Ensure that S0 + `spOff' (in cells) is stored in rvmsp and that S1's saved
1551   frame pointer is stored in rvmfp, then return to the saved return address in
1552   S1.  The return value is S2, which is passed via the rret_*() registers to
1553   the caller.  The `suspendingResumed' flag indicates when this instruction is
1554   suspending a resumable rather than performing a normal function return.
1556 | AsyncRetCtrl<spOff,suspendingResumed>, ND,
1557 |                                        S(StkPtr) S(FramePtr) S(InitNull),
1558 |                                        T
1560   Ensure that S0 + `spOff` (in cells) is stored in rvmsp and that S1 is stored
1561   in rvmfp.  The `suspendingResumed' flag indicates when this instruction is
1562   suspending a resumable rather than performing an async function return.
1563   Returns by leaving the TC to enterTCHelper.
1565   The return value is S2, which is passed via the rret_*() registers, and must
1566   be null---it is only used for enterTCHelper and ignored by everything else;
1567   resumed functions store their real return value into the Resumable object.
1569 | AsyncRetFast<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1571   Packs retVal (S2) into registers, sync stack (S0) and calls the asyncRetCtrl
1572   unique stub. The stub unblocks parents of the async function (represented by
1573   the frame pointer S1) and determines if it's possible to resume parent
1574   directly (fast path).
1576 | AsyncSwitchFast<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1578   Pass control to any pending fast resumable wait handles, bypassing the
1579   scheduler.  If no fast resumables are pending, behave like AsyncRetCtrl.
1581 | LdRetVal, D(Gen), S(FramePtr), NF
1583   Load the return value from the already-returned-from ActRec pointed to by S0
1584   into the dest.  This is used by NativeImpl.  TODO(#7150575): We want to make
1585   NativeImpl return a TypedValue in the C++ ABI registers.
1587 | DbgTrashRetVal, ND, S(FramePtr), NF
1589   For debugging purposes.  Store kTVTrashJITRetVal to the return value slot on
1590   the activation record pointed to by S0.
1592 | ReleaseVVAndSkip, ND, S(FramePtr), B
1594   Loads the VarEnv slot off the ActRec pointed to by S0. If it is null, does
1595   nothing. If it is an ExtraArgs, deallocates the ExtraArgs structure.
1596   Otherwise it frees the VarEnv and jumps to block B. This instruction may not
1597   occur in an inlined call.
1599 | GenericRetDecRefs, ND, S(FramePtr), NF
1601   Does decrefs of all the current function's locals, where S0 is a pointer to
1602   the relevant activation record. This instruction may not occur in an inlined
1603   call.
1606 10. Stores
1608 | StMem, ND, S(PtrToGen) S(Gen), CRc
1610   Store S2 into the location pointed to by S0.
1612 | StElem, ND, S(PtrToCell) S(Int) S(Cell), CRc
1614   Store S2 into the location given by the index S1 from base pointer S0. The
1615   index in S1 is the number of bytes from the base in S0.
1617 | StLoc<localId>, ND, S(FramePtr) S(Gen), CRc
1619   Store S1 to local number localId on the frame pointed to by S0.
1621 | StLocPseudoMain<localId>, ND, S(FramePtr) S(Gen), CRc
1623   Behaves just like StLoc, except the hard requirement that it is only emitted
1624   for pseudo-mains. We don't optimize StGbl the same way as StLoc, as we need
1625   intraprocedural analysis to know whether the store is truly dead.
1627 | StLocRange<localIds>, ND, S(FramePtr) S(Gen), CRc
1629   Store S1 to the local variables corresponding to localIds, on the frame
1630   pointed to by S0.
1632 | StRef, ND, S(BoxedCell) S(Cell), CRc
1634   Store the value in S1 into the RefData pointed to by S0. Stores the
1635   RefData::m_type also.
1637 | StStk<offset>, ND, S(StkPtr) S(StkElem), CRc
1639   Store S1 to the stack pointed to by S0, at a given offset (in cells).
1641 | DbgTrashStk<offset>, ND, S(StkPtr), NF
1643   For debugging purposes.  Store kTVTrashJITStk to the stack slot pointed to
1644   by S0, at a given offset (in cells).
1646 | DbgTrashFrame<offset>, ND, S(StkPtr), NF
1648   For debugging purposes.  Store kTVTrashJITFrame to kNumActRecCells stack
1649   slots starting at the offset (in cells), and going toward higher memory
1650   addresses.
1652 | DbgTrashMem, ND, S(PtrToGen), NF
1654   For debugging purposes.  Store kTVTrashJITHeap to a heap slot pointed to by
1655   S0.
1658 11. Trace exits
1660 | EagerSyncVMRegs, ND, S(FramePtr) S(StkPtr), NF
1662   Sync the given vmfp and vmsp to their in-memory locations.
1664 | ReqBindJmp<bcOff,transFlags>, ND, S(StkPtr) S(FramePtr), T
1666   Emit a jump to a REQ_BIND_JMP service request to the target offset bcOff.
1668 | ReqRetranslate<transFlags>, ND, S(StkPtr) S(FramePtr), T
1670   Emit a jump to a service request that will chain to a retranslation of this
1671   tracelet.
1673   This instruction is used in exit traces for a type prediction that occurs at
1674   the first bytecode offset of a tracelet.
1676 | ReqRetranslateOpt<transId,bcOff>, ND, S(StkPtr) S(FramePtr), T
1678   Emit a service request to retranslate, with a higher optimization gear,
1679   translation transID, which starts at bcOff. This instruction is used in exit
1680   traces that trigger profile-guided optimizations.
1683 12. Refcounting and copies
1685 | Mov, DofS(0), S(Top), P
1687   Defines D as S0. May imply register-to-register moves at code generation
1688   time. Does not imply an incref or any other manipulation of S0.
1690 | IncRef, ND, S(Gen,Ctx), NF
1692   If S0 is a refcounted type, increment its refcount.
1694 | DecRef<locId>, ND, S(Gen,Ctx), CRc
1696   Decrease the reference count of S0 by one, and call a destructor for types
1697   that require it if it goes to zero.
1699   Note that although DecRef takes a Gen, we don't allow it to use information
1700   about the inner types of a BoxedCell. This is because we don't guard on the
1701   inner types of a BoxedCell except when doing LdRef. For any S0 that is a
1702   strict subtype of BoxedCell, the DecRef must just decref it as if it were a
1703   BoxedCell.
1705   The locId is just a hint to the runtime indicating which local variable is
1706   being DecRef'd, if any.
1708 | DecRefNZ, ND, S(Gen,Ctx), CRc
1710   Decrease the reference count of S0 by one, do not check if it goes to zero.
1711   This instruction can be used for more efficient code when it is provable that
1712   the reference count cannot go to zero.
1715 13. Misc
1717 | DefFP, D(FramePtr), NA, NF
1719   Creates a temporary D representing the current vm frame pointer.
1721 | DefSP<stackOff>, D(StkPtr), S(FramePtr), NF
1723   Creates a temporary D representing the current vm stack pointer. S0 is a
1724   pointer to the current frame. The 'stackOff' is the logical offset between S0
1725   and the stack pointer, but in the case of generators this is not the
1726   physical offset at runtime.
1728   This instruction is used at the beginning of tracelets to represent the state
1729   of the stack on entry and does not emit code.
1731 | Count, D(Int), S(Cell), Er
1733   Computes the number of elements in S0. The count of an array is the number of
1734   elements it contains, without recursing into containers in the array.
1735   Subtypes of Bool|Int|Dbl|Str|Res have a count of 1, subtypes of Null have a
1736   count of 0. The count of objects that implement the Countable interface is
1737   computed by returning the value of their count method. Objects that do not
1738   implement Countable have a count of 1.
1740 | CountArray,      D(Int), S(Arr), NF
1742 | CountArrayFast,  D(Int), S(Arr), NF
1744 | CountVec, D(Int), S(Vec), NF
1746 | CountCollection, D(Int), S(Obj), NF
1748   Computes the number of elements in S0 using the same definition as Count, but
1749   with a restriction on the input type.
1751   CountArray expects any array. CountArrayFast expects an array whose kind is
1752   not kGlobalsKind or kProxyKind. CountVec expects a vec. CountCollection
1753   expects a collection object.
1755 | Nop, ND, NA, NF
1757   Does nothing. It's sometimes useful for the simplifier to insert one of these
1758   in the instruction stream.
1760 | ExitPlaceholder, ND, NA, B
1762   Does nothing if executed. Semantically, this instruction carries a taken edge
1763   to a block that was a pure side-exit during initial IR generation.  This
1764   allows later passes to test conditions and create new exits from the region
1765   at this point in the program.
1767 14. Runtime helpers
1769 | VerifyParamCls, ND, S(Cls) S(Cls|Nullptr) C(Int) C(Int), Er
1771   Verify parameter type for classes or traits. If S0 does not extend (if S1 is
1772   a class) or implement (if S1 is an interface) S1, this instruction will raise
1773   a recoverable fatal error describing the type mismatch.
1775 | VerifyParamCallable, ND, S(Gen) C(Int), Er
1777   If S0 is not callable, as defined by the php function is_callable, this
1778   instruction will raise a recoverable fatal error describing the type
1779   mismatch.
1781 | VerifyParamFail, ND, C(Int), Er
1783   Assumes that parameter number S0 in the current function has failed a its
1784   type check. Depending on the typehint being verified and a number of runtime
1785   options, may coerce the parameter to the correct type or raise a recoverable
1786   fatal error describing the type mismatch.
1788 | VerifyParamFailHard, ND, C(Int), Er|T
1790   A terminal version of VerifyParamFail, to be used when the compiler can
1791   statically prove that this failure will result in a fatal error rather than a
1792   type coercion.
1794 | VerifyRetCallable, ND, S(Gen), Er
1796   Verify a return type hint.
1798 | VerifyRetCls, ND, S(Cls) S(Cls|Nullptr) C(Int) S(Cell), Er
1800   Verify a return type hint.
1802 | VerifyRetFail, ND, S(PtrToGen), Er
1804   Failure to verify a return type hint.
1806 | RaiseUninitLoc<localId>, ND, S(Str), Er
1808   Raise a notice for an uninitialized local variable.
1810 | RaiseUndefProp, ND, S(Obj) CStr, Er
1812   Raise a notice for an undefined property named S1 on the class of S0.
1814 | RaiseMissingArg<func,argc>, ND, NA, Er
1816   Raise a missing argument warning because only S1 arguments were passed to
1817   function S0.
1819 | RaiseError, ND, S(Str), T|Er
1821   Raises a fatal error with the text in S0 as its message.
1823 | RaiseWarning, ND, S(Str), Er
1825   Raises a warning with the text in S0 as its message.
1827 | RaiseNotice, ND, S(Str), Er
1829   Raises a notice with the text in S0 as its message.
1831 | RaiseArrayIndexNotice, ND, S(Int), Er
1833   Raises a notice that S0 is an undefined index for an array.
1835 | RaiseArrayKeyNotice, ND, S(StaticStr), Er
1837   Raises a notice that S0 is an undefined key for an array.
1839 | InitClosureStaticLoc, ND, S(BoxedCell) S(Cell), NF
1841   Assuming S0 is an uninitialized closure static local, initialize it by
1842   setting it to the value in S1.
1844 | InitStaticLoc<func,staticLocalName>, D(BoxedInitCell), S(Cell), NF
1846   Initialize the static local variable named 'staticLocalName' for
1847   function 'func' with S0 and return it.
1849 | InitClsCns<className,constName>, DCns, NA, Er|PRc
1851   Initialize the RDS entry for a constant for a class, invoking autoload if it
1852   is not defined. The initialized value is returned. This instruction may raise
1853   an undefined constant error if autoload cannot define the constant.
1855 | PrintStr,  ND, S(Str),  Er|CRc
1857 | PrintInt,  ND, S(Int),  Er|CRc
1859 | PrintBool, ND, S(Bool), Er|CRc
1861   Print for various types.
1863 | ConcatIntStr, D(Str), S(Int) S(Str), Er|PRc
1865   Concatenate S0 and S1 after converting S0 to String.
1867 | ConcatStrInt, D(Str), S(Str) S(Int), Er|CRc|PRc
1869   Concatenate S0 and S1 after converting S1 to String.
1871 | ConcatStrStr, D(Str), S(Str) S(Str), Er|CRc|PRc
1873   Concatenate S0 and S1.
1875 | ConcatStr3, D(Str), S(Str) S(Str) S(Str), Er|CRc|PRc
1877   Concatenate S0, S1, and S2.
1879 | ConcatStr4, D(Str), S(Str) S(Str) S(Str) S(Str), Er|CRc|PRc
1881   Concatenate S0, S1, S2, and S3.
1883 | AddElemStrKey, D(Arr), S(Arr) S(Str) S(Cell), Er|CRc|PRc
1885   Add S2 to the array S0 for the key S1, and return the resulting array.
1887 | AddElemIntKey, D(Arr), S(Arr) S(Int) S(Cell), Er|CRc|PRc
1889   Add S2 to the array S0 for the key S1, and return the resulting array.
1891 | AddNewElem, D(Arr), S(Arr) S(Cell), Er|CRc|PRc
1893   Add S1 as a new element to the array S0.  (Note: S1 must actually be a
1894   subtype of InitCell for array invariants, but we can't assert this yet in the
1895   IR because many eval stack slots are not entirely typed wrt initness right
1896   now.)
1898 | DictAddElemStrKey, D(Dict), S(Dict) S(Str) S(Cell), Er|CRc|PRc
1900   Add S2 to the dict S0 for the key S1, and return the resulting dict.
1902 | DictAddElemIntKey, D(Dict), S(Dict) S(Int) S(Cell), Er|CRc|PRc
1904   Add S2 to the dict S0 for the key S1, and return the resulting dict.
1906 | ArrayAdd, D(Arr), S(Arr) S(Arr), Er|CRc|PRc
1908   Has the effects of the php + operator on the two source arrays.
1910 | AKExistsArr, D(Bool), S(Arr) S(Int,Str), NF
1912   Has the effects of array_key_exists(S0, S1).
1914 | AKExistsDict, D(Bool), S(Dict) S(Int,Str), NF
1916   Has the effects of array_key_exists(S0, S1).
1918 | AKExistsKeyset, D(Bool), S(Keyset) S(Int,Str), NF
1920   Has the effects of array_key_exists(S0, S1).
1922 | AKExistsObj, D(Bool), S(Obj) S(Int,Str), Er
1924   Has the effects of array_key_exists(S0, S1) on an object S0. This either does
1925   collection accesses, or uses the ArrayAccess API.
1927 | GetMemoKey, D(Cell), S(Cell), Er|PRc
1929   Given a cell, produces a cell that can be used as a cache key. Valid values
1930   for the input include all basic types, arrays and collections, and objects
1931   that implement IMemozieParam. Any other type will cause GetMemoKey to throw.
1933 | ArrayIdx, D(Gen), S(Arr) S(Int,Str) S(Cell), NF
1935   Checks if S0 contains the key S1, and returns the result if found. Otherwise
1936   S2 is returned.
1938 | DictIdx, DDictElem, S(Dict) S(Int,Str) S(Cell), NF
1940   Checks if S0 contains the key S1 and returns the result if found. Otherwise
1941   S2 is returned.
1943 | KeysetIdx, DKeysetElem, S(Keyset) S(Int,Str) S(Cell), NF
1945   Checks if S0 contains the key S1 and returns the result if found. Otherwise
1946   S2 is returned.
1948 | MapIdx, D(Gen), S(Obj) S(Str) S(Cell), NF
1950   Checks if S0, which must be an HH\Map or an HH\ImmMap, contains the key S1,
1951   and returns the result if found. Otherwise S2 is returned.
1953 | MethodExists, D(Bool), S(Cls) S(Str), NF
1955   Checks if the method named S1 exists on class S0.  S0 must be a normal class
1956   that is not abstract.
1958 | LdBindAddr<SrcKey,spOff>, D(TCA), NA, NF
1960   Creates a service request to bind the given target address. Returns a TCA
1961   pointing either to the service request (before the service request is
1962   satisfied) or to the native code for the given target address (once the
1963   service request is satisfied).
1965 | LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), NF
1967 | LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc
1969 | LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc|Er
1971   These instructions are used to determine the target of a switch statement
1972   with target range [S1:S1 + S2), when invoked with the value S0. They call
1973   helper functions to check whether S0 is an numeric integer in the range
1974   [S1:S1 + S2), and if so return the value S1 - (Int)S0. Else, they return the
1975   target of the default target, S2 + 1.
1977 | LdSSwitchDestFast, D(TCA), S(Gen), NF
1979 | LdSSwitchDestSlow, D(TCA), S(Gen), Er
1981   Load string switch destinations (two different compilation strategies).
1983 | InterpOne<T,spOff,bcOff,numPopped,numPushed>, ND,
1984 |                                               S(StkPtr) S(FramePtr),
1985 |                                               Er
1987   Call the interpreter implementation function for one opcode. S0 + `spOff' (in
1988   cells) and S1 are, respectively, the VM stack and frame pointers before this
1989   instruction. T is only present if the instruction pushes to the stack, in
1990   which case it is the type of the top stack element after the call. `bcOff' is
1991   the bytecode offset. `numPopped' is the number of stack cells consumed by the
1992   instruction, and `numPushed' is the number of stack cells produced by the
1993   instruction.
1995 | InterpOneCF<T,bcOff,numPopped,numPushed>, ND,
1996 |                                           S(StkPtr) S(FramePtr),
1997 |                                           T
1999   Similar to InterpOne, but for instructions that may modify vmpc. This is
2000   implemented as a tail call to a stub, so any exceptions thrown will be thrown
2001   in the context of the stub, not the InterpOneCF instruction.
2003 | OODeclExists<kind>, D(Bool), S(Str) S(Bool), Er
2005   Returns a bool indicating whether the class, interface, or trait named by S0
2006   exists. Invokes autoload if S1 is true.
2008 | SetOpCell<op>, ND, S(PtrToCell) S(Cell), Er
2010   Performs S0 <op>= S1.
2013 15. Generators & Closures
2015 | LdClosureCtx, DCtx, S(Obj), NF
2017   Load the context from the closure object S0 into D.
2018   May only be used in S0's closure Func.
2020 | StClosureCtx, ND, S(Obj) S(Ctx,Nullptr), CRc
2022   Store the context represented by S1 into the closure object S0. S1 may be a
2023   Nullptr when there is no context (i.e. the closure is being used in a
2024   non-method).
2026 | StClosureArg<offsetBytes>, ND, S(Obj) S(Gen), CRc
2028   Store one of the closure environment arguments (i.e. from the closure's use
2029   clause) from S1 into the closure object S0.
2031 | CreateCont, D(Obj), S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2033   Create a Generator object and suspend the ActRec provided by S0 into its
2034   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2035   resume address to S2 and resume offset to S3.
2037 | CreateAFWH, DAllocObj,
2038 |             S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2039 |             CRc|PRc
2041   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2042   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2043   the native resume address to S2, resume offset to S3, and mark it blocked on
2044   non-finished child S4.
2046 | CreateAFWHNoVV, DAllocObj,
2047 |                 S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2048 |                 CRc|PRc
2050   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2051   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2052   the native resume address to S2, resume offset to S3, and mark it blocked on
2053   non-finished child S4.  This version of the instruction guarantees that the
2054   VarEnv is unused.
2056 | CreateSSWH, DAllocObj, S(Cell), CRc|PRc
2058   Call c_StaticWaitHandle::CreateSucceeded.
2060 | AFWHPrepareChild, ND, S(FramePtr) S(Obj), Er
2062   Prepare unfinished WaitableWaitHandle object specified by S1 for getting
2063   awaited by an AsyncFunctionWaitHandle object specified by its ActRec
2064   provided by S0.
2066   Injects S1 into the currently running scheduler instance and performs
2067   cross-scheduler and intra-scheduler cycle detection. Throws if the
2068   dependency cannot be established.
2070 | ContEnter<spOffset,returnBCOffset>, ND,
2071 |                                     S(StkPtr) S(FramePtr) S(FramePtr) S(TCA),
2072 |                                     Er
2074   Enters a generator body. S0 + `spOffset' (in cells) is a pointer to the
2075   stack, S1 is the current frame pointer, S2 is the generator frame pointer
2076   embedded in the Generator object, and S3 is the address to jump to. The
2077   `returnBCOffset' will be stored to the m_soff field of the pre-live ActRec on
2078   the stack.
2080 | ContPreNext, ND, S(Obj) C(Bool), B
2082   Performs operations needed for the next() method of Generator object S0.
2083   If the generator is already running or finished, or it was not started yet
2084   and the S1 check-started flag is set, the branch B is taken. Otherwise,
2085   the generator is marked as running.
2087 | ContStartedCheck, ND, S(Obj), B
2089   Checks if the Generator object S0 has started, and if not branches to
2090   block B.
2092 | ContValid, D(Bool), S(Obj), NF
2094   Return true if a generator is not done, false otherwise.
2096 | ContStarted, D(Bool), S(Obj), NF
2098   Return true if a generator has been run at least once, i.e. is not in the
2099   Created state, false otherwise.
2101 | ContArIncKey, ND, S(FramePtr), NF
2103   Special-case key update for generator, ActRec of which is S0, which
2104   increments the key of a generator if that generator's key is an Int.
2105   This will cause undefined behavior if the generator's key is not an Int.
2107 | ContArIncIdx, D(Int), S(FramePtr), NF
2109   Increment the internal index in the Generator in S0, and return the new index
2110   value.
2112 | ContArUpdateIdx, ND, S(FramePtr) S(Int), NF
2114   Updates the internal index of generator with S1 if necessary, i.e. if S1
2115   is larger than the index. S0 is the pointer to the embedded ActRec.
2117 | LdContActRec, D(FramePtr), S(Obj), NF
2119   Loads the Generator object's ActRec, given a pointer to the generator
2120   object in S0.
2122 | LdContResumeAddr, D(TCA), S(Obj), NF
2124   Load the resume addr from the Generator in S0.
2126 | StContArState<state>, ND, S(FramePtr), NF
2128   Change the state of the Generator object which has frame pointer S0.
2130 | StContArResume<offset>, ND, S(FramePtr) S(TCA), NF
2132   Store the resume address S1 into the Generator whose ActRec is given by S0,
2133   marking the offset to resume at as `offset'.
2135 | LdContArValue, DParam, S(FramePtr), PRc
2137   Loads 'value' from the Generator object ActRec of which is S0.
2139 | StContArValue, ND, S(FramePtr) S(Cell), CRc
2141   Stores 'value' into the Generator object ActRec of which is S0. S1 is the
2142   new value.
2144 | LdContArKey, DParam, S(FramePtr), PRc
2146   Loads 'key' from the Generator object ActRec of which is S0.
2148 | StContArKey, ND, S(FramePtr) S(Gen), CRc
2150   Stores 'key' into the Generator object ActRec of which is S0. S1 is the
2151   new value.
2153 | StAsyncArSucceeded, ND, S(FramePtr), NF
2155   Mark the AsyncFunctionWaitHandle object whose ActRec is given by S0 as
2156   STATE_SUCCEEDED.
2158 | StAsyncArResume<offset>, ND, S(FramePtr) S(TCA), NF
2160   Store the resume address S1 into the AsyncFunctionWaitHandle whose ActRec is
2161   given by S0, marking the offset to resume at as `offset'.
2163 | StAsyncArResult, ND, S(FramePtr) S(Cell), CRc
2165   Stores result into the AsyncFunctionWaitHandle object ActRec of which is S0.
2166   S1 is the value.
2168 | LdAsyncArParentChain, D(ABC), S(FramePtr), NF
2170   Loads the first parent of the AsyncFunctionWaitHandle object ActRec of which
2171   is S0.
2173 | AFWHBlockOn, ND, S(FramePtr) S(Obj), CRc
2175   Establish dependency between parent AsyncFunctionWaitHandle object, whose
2176   ActRec is given by S0, and child WaitableWaitHandle object referenced by S1.
2178 | ABCUnblock, ND, S(ABC), NF
2180   Calls AsioBlockableChain::Unblock. This instruction may not occur in an
2181   inlined function.
2183 | LdWHState, D(Int), S(Obj), NF
2185   Loads the state of the WaitHandle in S0, which is a value from the wait
2186   handle states in ext_asio.h. This instruction has undefined behavior if S0 is
2187   not a WaitHandle.
2189 | LdWHResult, DParam, S(Obj), NF
2191   Loads the result of the WaitHandle in S0. This instruction has undefined
2192   behavior if S0 is not a WaitHandle, or if S0 is not finished.
2194 | LdAFWHActRec, D(FramePtr), S(Obj), NF
2196   Loads the AsyncFunctionWaitHandle object's ActRec, given a pointer to the
2197   AsyncFunctionWaitHandle object in S0.
2199 | LdResumableArObj, D(Obj), S(FramePtr), NF
2201   Loads the Resumable object, given a Resumable's frame pointer in S0.
2204 16. Debugging, instrumentation, and profiling
2206 | IncStat, ND, C(Int) C(Int) C(Bool), NF
2208   Increment stat counter. S0 is the implementation defined stat counter index,
2209   S1 is the amount to increment the counter (may be negative), and S2 is a
2210   'force' flag. This opcode becomes a noop iff (force == false and runtime
2211   stats are not enabled) at translation time.
2213 | IncTransCounter, ND, NA, NF
2215   Increment a translation counter.  This is probably something related to TC
2216   print.
2218 | IncStatGrouped, ND, CStr CStr C(Int), NF
2220   Adds the value S2 to the counter named S1, in the category S0.
2222 | IncProfCounter<TransID>, ND, NA, NF
2224   Increment the profiling counter associated with translation TransID.
2226 | DbgAssertRefCount, ND, S(Gen,TCtx), NF
2228   Assert that S0 has a valid refcount. If S0 has a reference counted type and
2229   its count is implausible then execute a hardware trap instruction.
2231 | DbgTraceCall<spOffset>, ND, S(FramePtr) S(StkPtr), NF
2233   When EvalHHIRGenerateAsserts is on, this instruction is inserted at the
2234   start of each region, to emit some sanity checking code.
2236 | DbgAssertFunc, ND, S(Func) S(Func), NF
2238   Assert that S0 and S1 are the same function at runtime. If the assertion
2239   fails, execution is aborted via a hardware exception.
2241 | RBTraceEntry, ND, NA, NF
2243 | RBTraceMsg, ND, NA, NF
2245   Ring buffer tracing.
2247 | ZeroErrorLevel, D(Int), NA, NF
2249 | RestoreErrorLevel, ND, S(Int), NF
2251   Helper instructions for fast implementation of the PHP error silencing
2252   operator (@foo()).
2255 17. Iterators
2257 | IterInit<IterData>,   D(Bool), S(Arr,Obj) S(FramePtr), Er|CRc
2259 | IterInitK<IterData>,  D(Bool), S(Arr,Obj) S(FramePtr), Er|CRc
2261 | WIterInit<IterData>,  D(Bool), S(Arr,Obj) S(FramePtr), Er|CRc
2263 | WIterInitK<IterData>, D(Bool), S(Arr,Obj) S(FramePtr), Er|CRc
2265 | MIterInit<T,IterData>,  D(Bool), S(BoxedCell) S(FramePtr), Er
2267 | MIterInitK<T,IterData>, D(Bool), S(BoxedCell) S(FramePtr), Er
2269   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2270   the index of the iterator variable, keyId and valId are indices of local
2271   variables.
2273   Initializes the iterator variable whose index is given by iterId.
2274   This instruction creates the appropriate iterator for the array or object that
2275   S0 references, and rewinds the new iterator to its start. S0 points to the
2276   stack frame containing the iterator and local variables with the indices
2277   iterId, keyId and valId.
2279   If the new iterator is at its end (i.e., has no elements to iterate over),
2280   this instruction decrements the refcount of S0 and returns false; otheriwse,
2281   it stores a reference to S0 in the new iterator and returns true. If the
2282   iterator is not at its end, then this instruction stores the iterator's first
2283   value (and key) into the local variable with index valId (and keyId,
2284   respectively).
2286   The IterInit and IterInitK instructions always copy the array element by
2287   value.
2289   The WIterInit and WIterInitK instructions copy referenced array elements by
2290   reference, and non-referenced array elements by value.
2292   The MIterInit and MIterInitK instructions always copy the array element by
2293   reference, and take a type parameter indicating the inner type of S0.  (This
2294   must have been proven via guards prior to running this opcode.)  Right now T
2295   must be Obj or Arr.
2297   This instruction has the ConsumesRC property because it either decrements the
2298   reference count of S0 or stores a reference to S0 into the new iterator.
2300 | IterNext<IterData>,   D(Bool), S(FramePtr), Er
2302 | IterNextK<IterData>,  D(Bool), S(FramePtr), Er
2304 | WIterNext<IterData>,  D(Bool), S(FramePtr), Er
2306 | WIterNextK<IterData>, D(Bool), S(FramePtr), Er
2308 | MIterNext<IterData>,  D(Bool), S(FramePtr), NF
2310 | MIterNextK<IterData>, D(Bool), S(FramePtr), NF
2312   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2313   the index of the iterator variable, keyId and valId are indices of local
2314   variables.  S0 points to the stack frame containing the iterator and local
2315   variables with the indices iterId, keyId and valId.
2317   Advances the iterator variable whose index is given by iterId.
2319   If the iterator has reached the end, this instruction frees the iterator
2320   variable and returns false; otherwise, it returns true. If the iterator has
2321   not reached its end, then this instruction stores the iterator's next value
2322   (and key) into the local variable with index valId (and keyId, respectively).
2324   The IterInit and IterInitK instructions always copy the array element by
2325   value. The WIterInit and WIterInitK instructions copy referenced array
2326   elements by reference, and non-referenced array elements by value. The
2327   MIterNext and MIterNextK instructions always copy the array element by
2328   reference.
2330 | IterFree,  ND, S(FramePtr), NF
2332 | MIterFree, ND, S(FramePtr), NF
2334   Free the iterator variable whose index is given by S1 in the stack frame
2335   pointed to by S0.
2337 | DecodeCufIter<iterId>, D(Bool), S(Arr,Obj,Str)  S(FramePtr), Er
2339   Decode S0 as a callable, and write the decoded values to the iterator
2340   specified by IterId. Returns true iff it successfully decoded the callable.
2341   Does not raise warnings, or throw exceptions.
2343 | CIterFree<iterId>, ND, S(FramePtr), NF
2345   Free the iterator variable whose index is given by IterId in the stack frame
2346   pointed to by S0.
2349 18. Member instruction support
2351 | LdMIStateAddr, D(PtrToMISGen), C(Int), NF
2353   Load an MInstrState address. Returns a pointer to offset S0 within the
2354   current MInstrState.
2356 | LdMBase, DParam, NA, NF
2358   Load the current value of the member base register.
2360 | StMBase, ND, S(PtrToGen), NF
2362   Store a new value to the member base register. It is illegal for any
2363   instruction other than StMBase or InterpOne (when interpreting a member
2364   instruction) to modify the member base register.
2366 | FinishMemberOp, ND, NA, NF
2368   Mark the end of a member operation. This has no effect at runtime but exists
2369   to provide information for certain optimizations.
2371 All of the remaining opcodes in this section are simple wrappers around helper
2372 functions (specified in S0) to perform the corresponding vector operation. If
2373 S1 is a ConstCls it represents the context class for the operation.
2375 SetElem, SetProp, and SetNewElem are used to implement part of the SetM hhbc
2376 opcode, which almost always pushes its first stack input or a CountedStr as its
2377 stack result. The combinations of input types that cause SetM to push anything
2378 other than those two values are vanishingly rare in correct PHP programs, so
2379 these three instructions have been optimized for the common cases. SetNewElem
2380 and SetProp have no destination, allowing the compiler to predict that the
2381 SetM's output will be the same as its input (and optimize accordingly). If that
2382 turns out to not be the case at runtime, the instruction will throw an
2383 InvalidSetMException. The exception will hold a Cell containing the value the
2384 SetM should push on the stack instead of its input value. The runtime is
2385 responsible for catching this exception, finishing execution of the SetM
2386 instruction, pushing the value from the exception on the stack, and proceeding
2387 as appropriate (most likely with a side exit to the next bytecode instruction,
2388 since it has pushed an unexpected type onto the stack).
2390 SetElem is similar to SetProp and SetNewElem but can also be used for setting
2391 characters within strings. When given a string base and a valid offset, SetElem
2392 returns a string representation of the newly inserted character. In all other
2393 cases it returns nullptr or throws an InvalidSetMException. It will throw this
2394 exception when it detects invalid input types, or when trying to set a string
2395 offset that would grow the string beyond the maximum supported size.
2397 The input types that will cause the errors described above are listed here:
2399 SetNewElem will fail if the base is not a subtype of {Null|Str|Arr|Obj} and not
2400            Bool<false>.
2401 SetElem has the same base constraint as SetNewElem. In addition, the key must
2402         not be a subtype of {Arr|Obj}.
2403 SetProp will fail if the base is not a subtype of {Obj|Null}.
2405 Any instructions that take a pointer to an MInstrState struct use the various
2406 fields of that struct for holding intermediate values.
2408 | BaseG, D(PtrToRMembCell), S(Str), Er
2410   Get a base from global named S0.
2412   NB: BaseG returns either a PtrToGblGen, OR a pointer to a ref that is rooted
2413   in a GblGen.  (I.e. the unbox happens in the C++ helper that this instruction
2414   calls.)  If it is not a defining BaseG it can also return the
2415   init_null_variant, so for now it returns a PtrToRMembCell.
2417 | PropX, D(PtrToMembGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), Er
2419   Lookup intermediate property in S0, with key S1.
2421 | PropQ, D(PtrToMembGen), S(Obj,PtrToGen) S(StaticStr) S(PtrToMISGen), Er
2423   A nullsafe version of PropX, returns null if the base S0 is null.
2425 | PropDX, D(PtrToMembGen), S(Obj,PtrToGen) S(Cell) S(PtrToMISGen), MProp|Er
2427   Like PropX, but used for intermediate element lookups that may modify the
2428   base.
2430 | CGetProp, D(Cell), S(Obj,PtrToGen) S(Cell), PRc|Er
2432   Get property with key S1 from S0.
2434 | CGetPropQ, D(Cell), S(Obj,PtrToGen) S(StaticStr), PRc|Er
2436   A nullsafe version of CGetProp, returns null if the base S0 is null.
2438 | VGetProp, D(BoxedInitCell), S(Obj,PtrToGen) S(Cell), MProp|PRc|Er
2440   Get property with key S1 from base S0 as a reference.
2442 | BindProp, ND,
2443 |           S(Obj,PtrToGen) S(Cell) S(BoxedCell),
2444 |           MProp|Er
2446   Bind property with key S1 in base S0 to the reference in S2.
2448 | SetProp, ND, S(Obj,PtrToGen) S(Cell) S(Cell), MProp|Er
2450   Set property with key S1 in S0 to S2.
2452 | UnsetProp, ND, S(Obj,PtrToGen) S(Cell), Er
2454   Unset an object property.
2456 | SetOpProp<op>, D(Cell),
2457 |                S(Obj,PtrToGen) S(Cell) S(Cell),
2458 |                MProp|PRc|Er
2460   Set op propery with key S1 in base S0, using S2 as the right hand side.
2462 | IncDecProp<op>, D(Cell),
2463 |                 S(Obj,PtrToGen) S(Cell),
2464 |                 MProp|PRc|Er
2466   Increment/decrement property with key S1 in base S0.
2468 | EmptyProp, D(Bool), S(Obj,PtrToGen) S(Cell), Er
2470   Returns true iff the property with key S1 in base S0 is empty.
2472 | IssetProp, D(Bool), S(Obj,PtrToGen) S(Cell), Er
2474   Returns true iff the property with key S1 in base S0 is set.
2476 | ElemX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), Er
2478   Get intermediate element with key S1 from base S0. The base will not be
2479   modified.
2481 | ProfileMixedArrayOffset, ND, S(Arr) S(Int,Str), NF
2483   Profile the offset of the element keyed by S1 in S0.
2485 | CheckMixedArrayOffset<pos>, ND, AK(Mixed) S(Int,Str), B
2487   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2488   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2489   fail, branch to B.  This check is allowed to have false negatives, in the
2490   case of int-like strings.
2492 | CheckArrayCOW, ND, S(ArrLike), B
2494   Check that S0 has a refcount of exactly 1; if not, branch to B.
2496 | ProfileDictOffset, ND, S(Dict) S(Int,Str), NF
2498   Profile the offset of the element keyed by S1 in S0.
2500 | CheckDictOffset<pos>, ND, S(Dict) S(Int,Str), B
2502   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2503   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2504   fail, branch to B.  This check is allowed to have false negatives.
2506 | ProfileKeysetOffset, ND, S(Keyset) S(Int,Str), NF
2508   Profile the offset of the element keyed by S1 in S0.
2510 | CheckKeysetOffset<pos>, ND, S(Keyset) S(Int,Str), B
2512   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2513   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2514   fail, branch to B.  This check is allowed to have false negatives.
2516 | ElemArray,  D(PtrToMembGen), S(Arr) S(Int,Str), Er
2518 | ElemArrayW, D(PtrToMembGen), S(Arr) S(Int,Str), Er
2520 | ElemArrayD<T>, D(PtrToElemGen), S(PtrToGen) S(Int,Str), MElem|Er
2522 | ElemArrayU<T>, D(PtrToMembGen), S(PtrToGen) S(Int,Str), MElem|Er
2524   Similar to ElemX, but the base S0 is an array and the key S1 is an int/str.
2525   ElemArrayW is for Warn member instrs, ElemArrayD is for Define member instrs,
2526   and ElemArrayU is for Unset.
2528   ElemArray{D,U} both take a PtrToGen for the base operand, but expect it to be
2529   a PtrToArr or PtrToBoxedArr.  T is the type of the base array.
2531 | ElemMixedArrayK<pos>, D(PtrToElemGen), AK(Mixed) S(Int,Str), NF
2533   Like ElemArray, but the element for S1 is at a known position `pos' in S0.
2535 | ElemVecD<T>, D(PtrToElemCell), S(PtrToGen) S(Int), MElem|Er
2537 | ElemVecU<T>, D(PtrToMembCell), S(PtrToGen) S(Int), MElem|Er
2539   Similar to ElemX, but the base S0 is a vec and the key S1 is an int. ElemVecD
2540   is for Define member instrs and ElemVecU is for Unset. (Other variations can
2541   be implemented without special IR instructions).
2543   ElemVec{D,U} both take a PtrToGen for the base operand, but expect it to be a
2544   PtrToVec or PtrToBoxedVec. T is the type of the base vec.
2546 | ElemDict,  D(PtrToMembCell), S(Dict) S(Int,Str), Er
2548 | ElemDictW, D(PtrToMembCell), S(Dict) S(Int,Str), Er
2550 | ElemDictD<T>, D(PtrToElemCell), S(PtrToGen) S(Int,Str), MElem|Er
2552 | ElemDictU<T>, D(PtrToMembCell), S(PtrToGen) S(Int,Str), MElem|Er
2554   Similar to ElemX, but the base S0 is a dict and the key S1 is an int/str.
2555   ElemDictW is for Warn member instrs, ElemDictD is for Define member instrs,
2556   and ElemDictU is for Unset.
2558   ElemDict{D,U} both take a PtrToGen for the base operand, but expect it to be
2559   a PtrToDict or PtrToBoxedDict.  T is the type of the base array.
2561 | ElemDictK<pos>, D(PtrToElemCell), S(Dict) S(Int,Str), NF
2563   Like ElemDict, but the element for S1 is at a known position `pos' in S0.
2565 | ElemKeyset,  D(PtrToMembCell), S(Keyset) S(Int,Str), Er
2567 | ElemKeysetW, D(PtrToMembCell), S(Keyset) S(Int,Str), Er
2569 | ElemKeysetU<T>, D(PtrToMembCell), S(PtrToGen) S(Int,Str), MElem|Er
2571   Similar to ElemX, but the base S0 is a keyset and the key S1 is an int/str.
2572   ElemKeysetW is for Warn member instrs and ElemKeysetU is for Unset.
2574   ElemKeysetU both take a PtrToGen for the base operand, but expect it to be
2575   a PtrToKeyset or PtrToBoxedKeyset.  T is the type of the base array.
2577 | ElemKeysetK<pos>, D(PtrToElemCell), S(Keyset) S(Int,Str), NF
2579   Like ElemKeyset, but the element for S1 is at a known position `pos' in S0.
2581 | ElemDX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|Er
2583   Like ElemX, but used for intermediate element lookups that may modify the
2584   base.
2586 | ElemUX, D(PtrToMembGen), S(PtrToGen) S(Cell) S(PtrToMISGen), MElem|Er
2588   Like ElemX, but used for intermediate element lookups that may modify the
2589   base as part of an unset operation.
2591 | ArrayGet, DArrElem, S(Arr) S(Int,Str), Er
2593   Get element with key S1 from base S0.
2595 | MixedArrayGetK<pos>, DArrElem, AK(Mixed) S(Int,Str), NF
2597   Like ArrayGet, but the element for S1 is at a known position `pos' in S0.
2599 | DictGet, DDictElem, S(Dict) S(Int,Str), Er
2601   Get element with key S1 from base S0, throwing if the element is not present.
2603 | DictGetQuiet, DDictElem, S(Dict) S(Int,Str), NF
2605   Get element with key S1 from base S0, returning null if the element is not
2606   present.
2608 | DictGetK<pos>, DDictElem, S(Dict) S(Int,Str), NF
2610   Like DictGet, but the element for S1 is at a known position `pos' in S0.
2612 | KeysetGet, DKeysetElem, S(Keyset) S(Int,Str), Er
2614   Get element with key S1 from base S0, throwing if the element is not present.
2616 | KeysetGetQuiet, DKeysetElem, S(Keyset) S(Int,Str), NF
2618   Get element with key S1 from base S0, returning null if the element is not
2619   present.
2621 | KeysetGetK<pos>, DKeysetElem, S(Keyset) S(Int,Str), NF
2623   Like KeysetGet, but the element for S1 is at a known position `pos' in S0.
2625 | StringGet, D(StaticStr), S(Str) S(Int), PRc|Er
2627   Get string representing character at position S1 from base string S0.  Raises
2628   a notice if the position is out of bounds.
2630 | MapGet, D(Cell), S(Obj) S(Int,Str), PRc|Er
2632   Get element with key S1 from base S0.
2634 | CGetElem, D(Cell), S(PtrToGen) S(Cell), PRc|Er
2636   Get element with key S1 from S0.
2638 | VGetElem, D(BoxedInitCell), S(PtrToGen) S(Cell), MElem|PRc|Er
2640   Get element with key S1 from base S0 as a reference.
2642 | BindElem, ND, S(PtrToGen) S(Cell) S(BoxedCell), MElem|Er
2644   Bind element with key S1 in base S0 to the reference S2.
2646 | ArraySet, D(Arr), S(Arr) S(Int,Str) S(Cell), PRc|CRc|Er
2648   Set element with key S1 in S0 to S2. The dest will be a new Array that should
2649   replace S0.
2651 | ArraySetRef, ND, S(Arr) S(Int,Str) S(Cell) S(BoxedCell), CRc|Er
2653   Like ArraySet, but for binding operations on the array. S3 must point to a
2654   RefData with an array type when this instruction is executed, and it must be
2655   the same array that is in S0.
2657 | VecSet, D(Vec), S(Vec) S(Int) S(Cell), PRc|CRc|Er
2659   Set element with key S1 in S0 to S2. The dest will be a new Vec that should
2660   replace S0.
2662 | VecSetRef, ND, S(Vec) S(Int) S(Cell) S(BoxedCell), CRc|Er
2664   Like VecSet, but for binding operations on the vec. S3 must point to a
2665   RefData with a vec type when this instruction is executed, and it must be the
2666   same vec that is in S0.
2668 | DictSet, D(Dict), S(Dict) S(Int,Str) S(Cell), PRc|CRc|Er
2670   Set element with key S1 in S0 to S2. The dest will be a new Dict that should
2671   replace S0.
2673 | DictSetRef, ND, S(Dict) S(Int,Str) S(Cell) S(BoxedCell), CRc|Er
2675   Like DictSet, but for binding operations on the dict. S3 must point to a
2676   RefData with a vec type when this instruction is executed, and it must be the
2677   same dict that is in S0.
2679 | MapSet, ND, S(Obj) S(Int,Str) S(Cell), Er
2681   Set element with key S1 in S0 to S2.
2683 | SetElem, DSetElem, S(PtrToGen) S(Cell) S(Cell), MElem|PRc|Er
2685   Set element with key S1 in S0 to S2. SetElem returns a Nullptr in the common
2686   case, where the logical result of the hhbc SetM is its right hand side. In
2687   the case of string bases, the SetM returns a new string containing the newly
2688   inserted character. So the return value of this instruction is Nullptr unless
2689   SetM needed to create a new counted string.
2691   Furthermore, in the case of "invalid offsets", SetElem may throw an
2692   InvalidSetMException (see discussion above).
2694 | SetWithRefElem, ND, S(PtrToGen) S(Gen) S(Gen), MElem|Er
2696   Set element with key S1 in S0 to S2.
2698 | UnsetElem, ND, S(PtrToGen) S(Cell), MElem|Er
2700   Unsets the element at key S1 in the base S0.
2702 | SetOpElem<op>, D(Cell),
2703 |                S(PtrToGen) S(Cell) S(Cell),
2704 |                MElem|PRc|Er
2706   Set op elem with key S1 in base S0, using S2 as the right hand side.
2708 | IncDecElem, D(Cell), S(PtrToGen) S(Cell), MElem|PRc|Er
2710   Increment/decrement element with key S1 in base S0.
2712 | SetNewElem, ND, S(PtrToGen) S(Cell), MElem|Er
2714   Append the value in S1 to S0.
2716 | SetNewElemArray, ND, S(PtrToGen) S(Cell), MElem|Er
2718   Append the value in S1 to S0, where S0 must be a pointer to a array.
2720 | SetNewElemVec, ND, S(PtrToGen) S(Cell), MElem|Er
2722   Append the value in S1 to S0, where S0 must be a pointer to a vec.
2724 | SetNewElemKeyset, ND, S(PtrToGen) S(Int,Str), MElem|Er
2726   Append the value in S1 to S0, where S0 must be a pointer to a keyset.
2728 | BindNewElem, ND, S(PtrToGen) S(BoxedCell), MElem|Er
2730   Append the reference in S1 to S0.
2732 | ArrayIsset, D(Bool), S(Arr) S(Int,Str), NF
2734   Returns true iff the element at key S1 in the base S0 is set.
2736 | DictIsset, D(Bool), S(Dict) S(Int,Str), NF
2738   Returns true iff the element at key S1 in the base S0 is set.
2740 | KeysetIsset, D(Bool), S(Keyset) S(Int,Str), NF
2742   Returns true iff the element at key S1 in the base S0 is set.
2744 | StringIsset, D(Bool), S(Str) S(Int), NF
2746   Returns true iff the string S0 has a character at position S1.
2748 | VectorIsset, D(Bool), S(Obj) S(Int), NF
2750   Returns true iff the element at key S1 in the base S0 is set.
2752 | PairIsset, D(Bool), S(Obj) S(Int), NF
2754   Returns true iff the element at key S1 in the base S0 is set.
2756 | MapIsset, D(Bool), S(Obj) S(Int,Str), NF
2758   Returns true iff the element at key S1 in the base S0 is set.
2760 | IssetElem, D(Bool), S(PtrToGen) S(Cell), Er
2762   Returns true iff the element at key S1 in S0 is set.
2764 | EmptyElem, D(Bool), S(PtrToGen) S(Cell), Er
2766   Returns true iff the element at key S1 in S0 is set and not equal (as defined
2767   by the hhbc Eq instruction) to false.
2769 | DictEmptyElem, D(Bool), S(Dict) S(Int,Str), NF
2771   Like EmptyElem, but specialized for dicts.
2773 | KeysetEmptyElem, D(Bool), S(Keyset) S(Int,Str), NF
2775   Like EmptyElem, but specialized for dicts.
2777 | CheckRange, D(Bool), S(Int) S(Int), NF
2779   Returns true iff S0 is in the range [0, S1).
2781 | ThrowOutOfBounds, ND, S(ArrLike|Obj) S(Gen), Er|T
2783   Throws an OutOfBoundsException corresponding to an access of S0 with the key
2784   S1.
2786 | ThrowInvalidArrayKey, ND, S(ArrLike) S(Gen), Er|T
2788   Throws an InvalidArgumentException corresponding to an access of S0 with the
2789   key S1, which has a type invalid for that array.
2791 | ThrowInvalidOperation, ND, S(Str), Er|T
2793   Throws an InvalidOperationException with a message indicating S0.
2795 | ThrowArithmeticError, ND, S(Str), Er|T
2797   Throws an ArithmeticError with a message indicating S0.
2799 | ThrowDivisionByZeroError, ND, S(Str), Er|T
2801   Throws a DivisionByZeroError with a message indicating S0.
2803 | ProfileArrayKind, ND, S(Arr), NF
2805   Profile the array kind of S0.
2807 | ProfileType, ND, S(Gen), NF
2809   Profile the type of S0.
2811 | ProfileMethod<rdsHandle,spOff>, ND, S(StkPtr) S(Cls,Nullptr), NF
2813   Profile the Func in the ActRec that was just pushed onto the stack.
2815 | CheckPackedArrayBounds, ND, AK(Packed) S(Int), B
2817   Checks that the index in S1 is within the bounds of the packed array in S0.
2818   Branches to B if the index is out of bounds.
2820 | LdPackedArrayElemAddr<T>, DParamPtr(Elem), AK(Packed) S(Int), NF
2822   Load the address of the element at index S1 of the packed array in S0.
2824 | LdVecElem, DVecElem, S(Vec) S(Int), NF
2826   Loads the element of the vec array in S0 at offset S1. This instruction
2827   assumes that the vec actually contains an element at that offset (IE, the vec
2828   has the proper length).
2830 | LdVecElemAddr<T>, DParamPtr(Elem), S(Vec) S(Int), NF
2832   Loads the address of the element at index S1 of the vec array in S0. This
2833   instruction assumes the vec actually contains an element at that offset (IE,
2834   the vec has the proper length).
2836 | LdVectorSize, D(Int), S(Obj), NF
2838   Returns the size of the given Vector collection in S0.
2840 | VectorDoCow, ND, S(Obj), NF
2842   Triggers a copy on write for a Vector that has a live ImmVector sharing
2843   the same copy of the elements.
2845 | VectorHasImmCopy, ND, S(Obj), B
2847   Given a vector, check if it has a immutable copy and jump to the taken branch
2848   if so.
2850 | ColAddNewElemC, DofS(0), S(Obj) S(Cell), Er|CRc|P
2852   Adds item S0 to the end of collection S0. Throws a fatal error if S0 is not a
2853   collection. Returns S0.
2855 | MapAddElemC, DofS(0), S(Obj) S(Cell) S(Cell), Er|CRc|P
2857   Adds item to a Map or ImmMap. Inserts item S2 into collection S0 at key S1.
2858   Throws a fatal error if S0 is not a collection. Returns S0.
2860 | ColIsEmpty, D(Bool), S(Obj), NF
2862 | ColIsNEmpty, D(Bool), S(Obj), NF
2864   Returns whether a collection instance is empty or not.  S0 must be known to
2865   be an instance of a collection class at compile time.
2868 19. Exception/unwinding support
2870 | BeginCatch, ND, NA, NF
2872   Marks the beginning of a catch region. Exact behavior is implementation and
2873   architecture specific.
2875 | EndCatch<spOffset>, ND, S(FramePtr) S(StkPtr), T
2877   Marks the end of a catch region and returns control to the unwinder.  The
2878   `spOffset' field represents a logical adjustment to S1 (in cells) to yield
2879   the vm stack pointer, however the stack pointer is not actually adjusted
2880   before this instruction returns control to the unwinder.  The unwinder
2881   instead relies on fixup map information to find the appropriate stack
2882   pointers.  Instead it's part of this instruction to facilitate assertions and
2883   memory effect analysis.
2885 | UnwindCheckSideExit, ND, S(FramePtr) S(StkPtr), B
2887   Branches to B if the currently executing catch region should return control
2888   to the unwinder rather than side exiting.  Used to control behavior in catch
2889   traces for the InvalidSetMException and TVCoercionException situations.
2891 | LdUnwinderValue<T>, DParam, NA, PRc
2893   Loads the value contained by the current unwinder exception.
2896 20. Function prologues
2898 | EnterFrame, ND, S(FramePtr), NF
2900   Stash the return address of the call in m_savedRip.
2902 | CheckStackOverflow, ND, S(FramePtr), Er
2904   Check if the stack depth has exceeded its limit.  If it has, jump to the
2905   stack overflow helper stub, which will throw.
2907 | InitExtraArgs<func,argc>, ND, S(FramePtr), NF
2909   Set up the ExtraArgs struct on the live ActRec.  If extra args are present
2910   and need to be discarded, they will be decref'd and may re-enter to run
2911   destructors.
2913 | InitCtx, ND, S(FramePtr) S(Ctx,Nullptr), CRc
2915   Store S1 to the m_this/m_cls field in the frame pointer S0.
2917   If InitCtx appears in an IR unit, it must dominate all occurrences of LdCtx
2918   and LdCctx with the same FramePtr.
2920 | CheckSurpriseFlagsEnter<func,argc>, ND, S(FramePtr), Er
2922   Test the implementation-specific surprise flags.  If they're nonzero, call
2923   the function enter helper.
2925 | CheckSurpriseAndStack<func,args>, ND, S(FramePtr), Er
2927   Test surprise flags and stack overflow at the same time.
2929 | CheckARMagicFlag, ND, S(FramePtr), B
2931   If the MagicDispatch flags on the ActRec pointed to by the frame pointer S0
2932   are not set, branch to block B.
2934 | LdARNumArgsAndFlags, D(Int), S(FramePtr), NF
2936   Load the value of m_numArgsAndFlags on the ActRec pointed to by the frame
2937   pointer S0.
2939 | StARNumArgsAndFlags, ND, S(FramePtr) S(Int), CRc
2941   Store S1 to m_numArgsAndFlags on the ActRec pointed to by the frame pointer
2942   S0.
2944 | LdARInvName, D(Str), S(FramePtr), NF
2946   Load the value of m_invName off the ActRec pointed to by the frame pointer S0.
2947   The compiler should generate this only if it knows that m_invName is a
2948   StringData* (rather than, e.g., a VarEnv*).
2950 | StARInvName, ND, S(FramePtr) S(Str,Nullptr), CRc
2952   Store S1 to m_invName on the ActRec pointed to by the frame pointer S0.
2954 | PackMagicArgs, D(Arr), S(FramePtr), PRc
2956   Call PackedArray::MakePacked() with the value of numArgs() on the ActRec
2957   pointed to by the frame pointer S0 as the first argument, and the pointer to
2958   the first parameter in the frame as the second argument.
2960 | LdTVAux<ValidBits>, D(Int), S(Gen), NF
2962   Load the value of m_aux from the TypedValue S0.  ValidBits is a mask
2963   specifying which bits are allowed to be set.  The runtime may ignore it.
2965   Note that when we pass TypedValues around in registers, we usually use a byte
2966   register for the m_type member, and thus ignore m_aux.  LdTVAux is only valid
2967   when we know that S0's m_type and m_aux were both materialized into the same
2968   64-bit register.
2970 /* Local Variables: */
2971 /* fill-column: 79 */
2972 /* End: */
2973 vim:textwidth=80