Optimize unaligned vanilla vec iteration
[hiphop-php.git] / hphp / doc / ir.specification
blob18e95e3f16469dc3836f58beb28a17f3da968f06
1 *******************************************
2 * HipHop Intermediate Representation (HHIR)
3 *******************************************
7 Introduction
8 ------------
10 The HipHop Intermediate Representation (IR) is a typed, in-memory,
11 static-single-assignment, intermediate-level representation of HHBC programs
12 used for just in time compilation, with these goals:
14   1. Complete. The IR represents a program or program fragment entirely,
15      without reference to HHBC or other upstream forms of the program.
17   2. Type-Safe. Since the IR deals directly with refined types and internal VM
18      types, all operations are typesafe. All instruction parameters have a
19      parameter type P, and all variables have a type S. Given an instruction
20      with source parameter type P and variable type S, S must be equal to or
21      more refined than P (S == P or S <: P).
23   3. Machine Independent. Since this IR is intended to be used in a JIT
24      compiler, it will always be used in a machine specific context.
25      Nevertheless, we rely on machine independence in order to separate
26      concerns and increase portability of the VM. Passes which manipulate IR
27      based on PHP or HHBC semantics should be portable. Passes which deal with
28      machine specifics (such as register allocation) should be done in the
29      lower level IR (vasm). Types are machine independent.
31 The unit of compilation is the IRUnit, which is a collection of Blocks
32 containing IRInstructions that produce and consume SSATmp values. Blocks are
33 single-entry, single-exit sequences of instructions (i.e. basic
34 blocks). Instructions may be annotated with Type parameter which modifies the
35 instruction's behavior, or with additional compile-time constant data (see
36 extra-data.h). Each SSATmp has a Type which describes the set of values it may
37 hold, over its entire live range. Instructions may have side effects, which
38 occur in execution order.
40 The static single assignment form guarantees the following two invariants for a
41 well-formed compilation unit:
43   1. Each SSATmp is assigned to by exactly one IRInstruction.
45   2. Definitions dominate uses. Every path to an IRInstruction using an SSATmp
46      first executes the IRInstruction defining the SSATmp.
48 Any pass that generates or manipulates IR must preserve these invariants,
49 however it is possible and expected for the invariants to be temporarily broken
50 during IR generation or during an optimization pass.
53 Control Flow
54 ------------
56 IRUnits have one entry block, zero or more exit blocks, and zero or more catch
57 blocks. Exit blocks leave the compilation unit in the middle of the same PHP
58 function using one of several instructions that exit a compilation unit
59 (e.g. ReqBindJmp). Catch blocks are blocks that are reachable from exceptional
60 control flow edges, and are executed during unwinding if an exception
61 propagates through the instruction that had it as a `taken' edge.
63 No SSATmps are defined on entry to the main Block.
65 Blocks which are join points may start with a DefLabel with destination
66 SSATmps. In that case, each predecessor must be a Jmp passing a matching number
67 of sources. In this case the Jmp acts as a tail-call, passing arguments the
68 same way a plain call would.
70 Together, the sources of the Jmp instructions and the destinations of the
71 DefLabel instructions act as traditional SSA Phi pseudo-functions; The type of
72 the DefLabel's destination is the type-union of the corresponding sources.
73 Because the Jmp sources are at the ends of blocks, they do not violate the SSA
74 dominator rule (rule 2, above).
77 Types
78 -----
80 For an overview of the HHIR type system, see the "Type System" section in
81 hackers-guide/jit-core.md.
84 SSATmps
85 -------
87 An SSATmp represents a virtual register. Since HHIR uses SSA, an SSATmp may
88 only be assigned to by one instruction. The type of an SSATmp represents the
89 set of values it may hold at the point it is defined, which is invariant over
90 the lifetime of the variable (from the definition point to the last use).
93 IRInstructions
94 --------------
96 An instruction is an executable operation with zero or more inputs (sources),
97 zero or one result (destination), and possible side effects such as accessing
98 memory, doing I/O, and which may branch or throw an exception. Some
99 instructions have a Type parameter which modifies its behavior, or other "extra
100 data" in an arbitrary C++ struct (see extra-data.h).
102 Each instruction has a signature which describes its effect, parameter types,
103 and return type, for example:
105   IsType<T>, D(Bool), S(Cell), NF
107 The first column is the instruction name (and optional Type parameter in <>).
109 The second column describes the result (destination) using one of the D*
110 macros documented in hphp/runtime/vm/jit/ir-opcode.h, or ND for no destination.
112 The third column describes the sources, separated by whitespace, using macros
113 documented in hphp/runtime/vm/jit/ir-opcode.h, or NA if there are no sources.
115 The fourth column contains the flags, described below. The short name of the
116 flag (used in this file) is given first, with the long name that it expands to
117 in hphp/runtime/vm/jit/ir-opcode.cpp in parentheses after it.
121   The instruction has no flags.
123 PRc (ProducesRC)
125   The instruction produces a value with an unconsumed reference that must be
126   consumed, either by DecRefing it or storing it somewhere in memory.
128 CRc (ConsumesRC)
130   The instruction consumes a reference to one or more of its sources, either by
131   decreasing its refcount or storing the reference to memory.
133 T (Terminal)
135   The instruction has no next instruction; it either jumps, returns, or throws.
137 B (Branch)
139   The instruction has a (sometimes optional) taken edge. Instructions that are
140   conditional branches (i.e. a Branch that is not Terminal) will also have a
141   next edge.
143 P (Passthrough)
145   The value of the instruction's dest is the same as one of its inputs; it
146   differs only in the type of the variable, or some other property that doesn't
147   affect the value of the variable itself.
149 LA (Layout-Agnostic)
151   The instruction is generic over array-like inputs and outputs. Most ops that
152   deal with array-like types can only handle their default ("Vanilla") layouts.
153   We whitelist those ops that are generic over layout.
155 LP (Layout-preserving)
157   The instruction is closed under vanilla array layouts: if the first argument
158   is vanilla, so too is the destination. The first argument must be an
159   array-like type. Layout-preserving implies layout-agnostic.
162 Instruction set
163 ---------------
165 1. Checks and Asserts
167 | CheckType<T>, DRefineS(0), S(Cell), B|P
169   Check that the type of the src S0 is T, and if so copy it to D, and
170   fallthrough. If S0 cannot be proven to be T, branch to block B. Note that
171   this means S0 still /may/ be a subtype of T in block B in some circumstances.
173   Specifically, subtypes of Type::Static may not be checked precisely,
174   depending on the type of the source.  This means the instruction may take the
175   branch in some circumstances even when S0 is a subtype of T, if T has a
176   non-empty intersection with Type::Static.
178   Also note that many types are not supported as the typeParam right now.
180 | CheckNullptr, ND, S(Cls|StaticStr|Nullptr), B
182   If S0 is not a null pointer, branch to block B. This is used to check the
183   return value of a native helper that returns a potentially null StringData*.
185 | AssertType<T>, DRefineS(0), S(Cell,Mem), P
187   Assert that the type of S0 is T, copying it to D.
189 | CheckTypeMem<T>, ND, S(Mem), B
191   If the value pointed to by S0 is not type T, branch to the block B.
193 | CheckIter<iterId,iterType>, ND, S(FramePtr), B
195   Check that specialization type of the given iterator `iterId` on the frame S0
196   is `iterType`; if it is not, branch to block B.
198 | CheckLoc<T,localId>, ND, S(FramePtr), B
200   Check that type of the given localId on the frame S0 is T; if not, branch to
201   block B.
203 | CheckStk<T,offset>, ND, S(StkPtr), B
205   Check that the type of the cell on the stack pointed to by S0 at offset (in
206   cells) is T; if not, branch to block B.
208 | CheckMBase<T>, ND, S(Lval), B
210   Check that the value pointed to by the member base register S0 has type T; if
211   not, branch to block B.  This is functionally the same as CheckTypeMem.
213 | AssertLoc<T,localId>, ND, S(FramePtr), NF
215   Asserts that type of the supplied local on the frame S0 is T. This is used
216   for local type information, and is similar to CheckLoc except it doesn't
217   imply a runtime check (the assertion must've already been proven to be true)
218   and cannot cause control flow.
220 | AssertStk<T,offset>, ND, S(StkPtr), NF
222   Assert that stack element at `offset' (in cells) from S0 has type T. This is
223   similar to a CheckStk except that it does not imply a runtime check and
224   cannot cause control flow.
226 | AssertMBase<T>, ND, NA, NF
228   Assert that the value pointed to by the member base register has type T.
229   This is similar to a CheckMBase except that it does not imply a runtime check
230   and cannot cause control flow.
232 | CheckInit, ND, S(Cell), B
234   If S0's type is Uninit, branch to block B.
236 | CheckInitMem, ND, S(Mem), B
238   If the value pointed to by S0 has type Uninit, branch to block B.
240 | CheckCold<TransID>, ND, NA, B
242   Check if the counter associated with translation TransID is cold (i.e. within
243   a fixed threshold). If it's not (i.e. such translation has reached the
244   "hotness threshold"), then branch to block B.
246 | EndGuards, ND, NA, NF
248   A no-op at runtime, this instruction serves to mark the end of the initial
249   sequence of guards in a trace.
251 | CheckNonNull, DSubtract(0, Nullptr), S(Cls|Func|Obj|Str|Mem|TCA|Nullptr), B
253   If the value in S0 is Nullptr, branch to block B. If S0 cannot be Nullptr, or
254   always is Nullptr, this check may be optimized away.
256 | AssertNonNull, DSubtract(0, Nullptr), S(StaticStr|Nullptr), P
258   Returns S0, with Nullptr removed from its type. This instruction currently
259   supports a very limited range of types but can be expanded if needed.
261 | CheckSmashableClass, ND, S(Smashable) S(Cls), B
263   If the lower 32 bits of S0 does not match class pointer S1, branch to block B.
265 2. Arithmetic
267 | AddInt, D(Int), S(Int) S(Int), NF
269 | AddOffset, D(VoidPtr), S(VoidPtr) C(Int), NF
271 | SubInt, D(Int), S(Int) S(Int), NF
273 | MulInt, D(Int), S(Int) S(Int), NF
275 | AddIntO, D(Int), S(Int) S(Int), B
277 | SubIntO, D(Int), S(Int) S(Int), B
279 | MulIntO, D(Int), S(Int) S(Int), B
281 | AddDbl, D(Dbl), S(Dbl) S(Dbl), NF
283 | SubDbl, D(Dbl), S(Dbl) S(Dbl), NF
285 | MulDbl, D(Dbl), S(Dbl) S(Dbl), NF
287 | DivDbl, D(Dbl), S(Dbl) S(Dbl), NF
289 | DivInt, D(Int), S(Int) S(Int), NF
291 | Floor, D(Dbl), S(Dbl), NF
293 | Ceil, D(Dbl), S(Dbl), NF
295 | AbsDbl, D(Dbl), S(Dbl), NF
297 | Sqrt, D(Dbl), S(Dbl), NF
299 | AndInt, D(Int), S(Int) S(Int), NF
301 | OrInt, D(Int), S(Int) S(Int), NF
303 | XorInt, D(Int), S(Int) S(Int), NF
305 | Shl, D(Int), S(Int) S(Int), NF
307 | Shr, D(Int), S(Int) S(Int), NF
309 | Lshr, D(Int), S(Int) S(Int), NF
311   Double arithmetic, integer arithmetic, and integer bitwise operations.
312   Performs the operation described by the opcode name on S0 and S1, and puts
313   the result in D.
315   Undefined behavior occurs if Mod is given a divisor of zero, or if the
316   divisor is -1 and the dividend is the minimum representable integer.
318   AbsDbl computes the absolute value of a double-precision value.
320   DivDbl conforms to IEEE 754. In particular, division by zero returns +/- INF
321   or NAN depending on the dividend; and should the result of a division be zero
322   the sign will follow the normal sign rules for division.
324   DivInt will perform integer division of S1 by S0. S0 should not be zero and
325   must divide S1.
327   Note that Shr is an arithmetic right shift: The MSB is sign-extended.
329   Lshr is logical right shift.
331   Floor and Ceil will return an integral value not greater, or not less
332   than their input respectively. Their use requires SSE 4.1, availability
333   should be checked before they are emitted.
335   AddIntO, SubIntO, MulIntO perform integer arithmetic on S0 and S1, but will
336   branch to block B on integer overflow.
338 | XorBool, D(Bool), S(Bool) S(Bool), NF
340   Logical XOR of the two sources. (Note that && and || do not have
341   corresponding opcodes because they're handled at the bytecode level, to
342   implement short-circuiting.)
344 | Mod, D(Int), S(Int) S(Int), NF
346   Compute S0 mod S1. If S1 is -1 or 0 the results are undefined.
349 3. Type conversions
351 To vec conversions:
353 | ConvArrLikeToVec,             D(Vec), S(ArrLike),                  PRc|CRc|LP
355 | ConvObjToVec,                 D(Vec), S(Obj),                      PRc|CRc
358 To dict conversions:
360 | ConvArrLikeToDict,            D(Dict), S(ArrLike),                 PRc|CRc|LP
362 | ConvObjToDict,                D(Dict), S(Obj),                     PRc|CRc
365 To keyset conversions:
367 | ConvArrLikeToKeyset,          D(Keyset), S(ArrLike),               PRc|CRc|LP
369 | ConvObjToKeyset,              D(Keyset), S(Obj),                   PRc|CRc
372 To bool conversions:
374 | ConvDblToBool,               D(Bool), S(Dbl),                           NF
376 | ConvIntToBool,               D(Bool), S(Int),                           NF
378 | ConvStrToBool,               D(Bool), S(Str),                           NF
380 | ConvObjToBool,               D(Bool), S(Obj),                           NF
382 | ConvTVToBool,                D(Bool), S(Cell),                          NF
385 To double conversions:
387 | ConvBoolToDbl,                D(Dbl), S(Bool),                          NF
389 | ConvIntToDbl,                 D(Dbl), S(Int),                           NF
391 | ConvObjToDbl,                 D(Dbl), S(Obj),                           NF
393 | ConvStrToDbl,                 D(Dbl), S(Str),                           NF
395 | ConvResToDbl,                 D(Dbl), S(Res),                           NF
397 | ConvTVToDbl,                  D(Dbl), S(Cell),                          NF
400 To int conversions:
402 | ConvBoolToInt,                D(Int), S(Bool),                          NF
404 | ConvDblToInt,                 D(Int), S(Dbl),                           NF
406 | ConvObjToInt,                 D(Int), S(Obj),                           NF
408 | ConvStrToInt,                 D(Int), S(Str),                           NF
410 | ConvResToInt,                 D(Int), S(Res),                           NF
412 | ConvTVToInt,                  D(Int), S(Cell),                          NF
415 To string conversions:
417 | ConvDblToStr,                 D(Str), S(Dbl),                           PRc
419 | ConvIntToStr,                 D(Str), S(Int),                           PRc
421 | ConvObjToStr,                 D(Str), S(Obj),                           PRc
423 | ConvTVToStr,                  D(Str), S(Cell),                          PRc
426   All the above opcodes convert S0 from its current type to the destination
427   type, according to the PHP semantics of such a conversion.
429 | DblAsBits,                    D(Int), S(Dbl),                           NF
431   Reinterpret a double as an integer with the same bit pattern.
433 | OrdStr,                       D(Int), S(Str),                           NF
435   Convert the first byte in a string to an unsigned integer.
436   Intended as an optimization for ord($str)
438 | OrdStrIdx,                    D(Int), S(Str) S(Int),                    NF
440   Convert the character at position S1 in base string S0 to an unsigned
441   integer.  Raises a notice if the position is out of bounds.
442   Intended as an optimization for ord($str[$idx]).
444 | ChrInt,                      D(StaticStr), S(Int),                      NF
446   Convert the integer S0 to a the one character string with ascii code
447   S0 & 255.
449 | StrictlyIntegerConv,         D(Str|Int), S(Str),                        PRc
451   If S0 is a string representing an integer value (same criteria as array key
452   conversion), return that value as an integer. Otherwise return S0.
454 | ConvPtrToLval,               DLvalOfPtr, S(Ptr),                        NF
456   Convert S0 to an equivalent lval.
458 | VoidPtrAsDataType<T>,        DParam(Cell), S(VoidPtr),                  NF
460   Take VoidPtr S0 and convert it to heap type TParam.
462 4. Boolean predicates
464 | GtInt,                       D(Bool), S(Int) S(Int),                    NF
466 | GteInt,                      D(Bool), S(Int) S(Int),                    NF
468 | LtInt,                       D(Bool), S(Int) S(Int),                    NF
470 | LteInt,                      D(Bool), S(Int) S(Int),                    NF
472 | EqInt,                       D(Bool), S(Int) S(Int),                    NF
474 | NeqInt,                      D(Bool), S(Int) S(Int),                    NF
476 | CmpInt,                      D(Int),  S(Int) S(Int),                    NF
478   Perform 64-bit integer comparisons.
480 | GtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
482 | GteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
484 | LtDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
486 | LteDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
488 | EqDbl,                       D(Bool), S(Dbl) S(Dbl),                    NF
490 | NeqDbl,                      D(Bool), S(Dbl) S(Dbl),                    NF
492 | CmpDbl,                      D(Int),  S(Dbl) S(Dbl),                    NF
494   Perform comparisons of doubles. Comparisons that are unordered according to
495   IEEE 754 (such as when at least one operand is NaN) result in false.
497 | GtStr,                       D(Bool), S(Str) S(Str),                    NF
499 | GteStr,                      D(Bool), S(Str) S(Str),                    NF
501 | LtStr,                       D(Bool), S(Str) S(Str),                    NF
503 | LteStr,                      D(Bool), S(Str) S(Str),                    NF
505 | EqStr,                       D(Bool), S(Str) S(Str),                    NF
507 | NeqStr,                      D(Bool), S(Str) S(Str),                    NF
509 | SameStr,                     D(Bool), S(Str) S(Str),                    NF
511 | NSameStr,                    D(Bool), S(Str) S(Str),                    NF
513 | CmpStr,                      D(Int),  S(Str) S(Str),                    NF
515   Performs comparison of strings
517 | GtBool,                      D(Bool), S(Bool) S(Bool),                  NF
519 | GteBool,                     D(Bool), S(Bool) S(Bool),                  NF
521 | LtBool,                      D(Bool), S(Bool) S(Bool),                  NF
523 | LteBool,                     D(Bool), S(Bool) S(Bool),                  NF
525 | EqBool,                      D(Bool), S(Bool) S(Bool),                  NF
527 | NeqBool,                     D(Bool), S(Bool) S(Bool),                  NF
529 | CmpBool,                     D(Int),  S(Bool) S(Bool),                  NF
531   Performs comparison of booleans.
533 | GtObj,                       D(Bool), S(Obj) S(Obj),                    NF
535 | GteObj,                      D(Bool), S(Obj) S(Obj),                    NF
537 | LtObj,                       D(Bool), S(Obj) S(Obj),                    NF
539 | LteObj,                      D(Bool), S(Obj) S(Obj),                    NF
541 | EqObj,                       D(Bool), S(Obj) S(Obj),                    NF
543 | NeqObj,                      D(Bool), S(Obj) S(Obj),                    NF
545 | SameObj,                     D(Bool), S(Obj) S(Obj),                    NF
547 | NSameObj,                    D(Bool), S(Obj) S(Obj),                    NF
549 | CmpObj,                      D(Int),  S(Obj) S(Obj),                    NF
551   Perform comparison of object. All versions except for SameObj and NSameObj may
552   re-enter the VM and therefore may throw exceptions. SameObj and NSameObj never
553   re-enter or throw.
555 | GtArrLike,                   D(Bool), S(ArrLike) S(ArrLike),            NF|LA
557 | GteArrLike,                  D(Bool), S(ArrLike) S(ArrLike),            NF|LA
559 | LtArrLike,                   D(Bool), S(ArrLike) S(ArrLike),            NF|LA
561 | LteArrLike,                  D(Bool), S(ArrLike) S(ArrLike),            NF|LA
563 | EqArrLike,                   D(Bool), S(ArrLike) S(ArrLike),            NF|LA
565 | NeqArrLike,                  D(Bool), S(ArrLike) S(ArrLike),            NF|LA
567 | SameArrLike,                 D(Bool), S(ArrLike) S(ArrLike),            NF|LA
569 | NSameArrLike,                D(Bool), S(ArrLike) S(ArrLike),            NF|LA
571 | CmpArrLike,                  D(Int),  S(ArrLike) S(ArrLike),            NF|LA
573   Perform comparison of array-likes. All versions except for SameArrLike and
574   NSameArrLike may re-enter the VM and therefore may throw exceptions.
575   SameArrLike and NSameArrLike never re-enter or throw. Relational comparisons
576   for dicts and keysets are not supported. As keysets only contain ints and
577   strings, comparisons never re-enter or throw.
579 | GtRes,                       D(Bool), S(Res) S(Res),                    NF
581 | GteRes,                      D(Bool), S(Res) S(Res),                    NF
583 | LtRes,                       D(Bool), S(Res) S(Res),                    NF
585 | LteRes,                      D(Bool), S(Res) S(Res),                    NF
587 | EqRes,                       D(Bool), S(Res) S(Res),                    NF
589 | NeqRes,                      D(Bool), S(Res) S(Res),                    NF
591 | CmpRes,                      D(Int),  S(Res) S(Res),                    NF
593   Perform comparison of resources using PHP semantics. Resource comparisons
594   never re-enter or throw.
596 | EqCls,                       D(Bool), S(Cls) S(Cls),                    NF
598   Checks if two Class values are equal.
600 | EqLazyCls,                   D(Bool), S(LazyCls) S(LazyCls),            NF
602   Checks if two Lazy class values are equal.
604 | EqFunc,                      D(Bool), S(Func) S(Func),                  NF
606   Checks if two Func values are equal.
608 | EqStrPtr,                    D(Bool), S(Str) S(Str),                    NF
610   Checks if two string values represent the same underlying string. That is,
611   that they point at the same underlying storage.
613 | EqArrayDataPtr,              D(Bool), S(ArrLike) S(ArrLike),            LA
615   Checks if the two arguments represent the same underlying ArrayData. That is,
616   that they point at the same underlying storage.
618 | ProfileInstanceCheck, ND, C(StaticStr), NF
620   Profile that S0 has been used as the RHS of an instance check.
622 | InstanceOf, D(Bool), S(Cls) S(Cls|Nullptr), NF
624   Sets D based on whether S0 is a descendant of the class, interface, or trait
625   in S1. (Note that this is always false for a trait). S1 may be null at
626   runtime if the class is not defined.
628 | InstanceOfIface, D(Bool), S(Cls) CStr, NF
630   Fast path for interface checks. Sets D based on whether S0 implements S1, but
631   S1 must be a unique interface. This should only be used in repo-authoritative
632   mode.
634 | InstanceOfIfaceVtable<iface,canOptimize>, D(Bool), S(Cls), NF
636   Faster path for interface checks. Sets D based on whether S0 implements
637   iface, which must be a unique interface with an assigned vtable slot.  In
638   some circumstances, this instruction is ensuring the presence of the
639   vtableVec; in those cases, canOptimize is false to avoid eliminating the
640   guard.
642 | ExtendsClass<cls,strictLikely>, D(Bool), S(Cls), NF
644   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
645   of cls, where cls must be a unique class that is not an interface or a trait.
647   If strictLikely is true, optimize for the case where S0 is not equal to S1.
649 | InstanceOfBitmask,           D(Bool), S(Cls) CStr,                      NF
651 | NInstanceOfBitmask,          D(Bool), S(Cls) CStr,                      NF
653   A fast-path for instanceof checks. Sets D based on whether S0 is a descendant
654   of the class named by S1, where S1 must have a bit allocated for it in the
655   fast instance check bitvector (see class.h).
657 | InterfaceSupportsArrLike,    D(Bool), S(Str), NF
659 | InterfaceSupportsStr,        D(Bool), S(Str), NF
661 | InterfaceSupportsInt,        D(Bool), S(Str), NF
663 | InterfaceSupportsDbl,        D(Bool), S(Str), NF
665   Returns whether t instanceof S0 returns true when t is of the given type.
667 | ResolveTypeStruct<class,suppress,offset,size,isOrAsOp>,
668 |   D(Dict), S(StkPtr) S(Cls|Nullptr), NF
670   Applies class/alias resolution on the type structure that is at the stack
671   offset given by S0 and offset. If size > 1, combine the type structures on
672   the stack into the first one's denoted holes. Returns a copy.
673   S1 is the calling class, used to resolve the this typehint.
674   If isOrAsOp is set, raises an error if S0 contains traits, function types or
675   typevars.
676   If there is an error during type structure resolution, this instruction raises
677   an error. If suppress is set, this error is demoted to a warning.
679 | IsTypeStruct<handle>, D(Bool), S(Dict) S(Cell), LA
681   Returns whether S1 matches the type structure of a defined type in S0 and S1
682   is a subtype of S0. The input type structure (S0) must be resolved.
683   Handle is used for caching purposes.
685 | IsTypeStructCached, D(Bool), S(Dict) S(Cell), B|LA
687   Checks if S0 is cached in TSClassCache and if so, returns whehter S1 is a
688   subtype of S0. Otherwise, it branches.
690 | ProfileIsTypeStruct<handle>, ND, S(Dict), LA|ND
692   Profile S0 to determine whether S0 is a type structure holding a reference to
693   a Class*.
695 | ThrowAsTypeStructException, ND, S(Dict) S(Cell), LA|T
697   Throws an exception indicating why S1 does not match the type structure of a
698   defined type in S0 or why S1 is not a subtype of S0. The input type structure
699   (S0) must be resolved.
701 | RaiseErrorOnInvalidIsAsExpressionType, D(Dict), S(Dict), LA
703   Raises an error if the type hint for is/as expression contains an invalid
704   type such as callables, erased type variables and trait type hints.
705   The input type structure (S0) must be resolved.
707 | HasToString, D(Bool), S(Obj), NF
709   Returns whether the object S0 has a toString method.
711 | IsType<T>, D(Bool), S(Cell), NF
713   Sets D to true iff S0 holds a value that is of type T. T must not be a
714   specialized type.
716 | IsNType<T>, D(Bool), S(Cell), NF
718   Sets D to true iff S0 holds a value that is not of type T. T must not be a
719   specialized type.
721 | IsTypeMem<T>, D(Bool), S(Mem), NF
723   Sets D to true iff the value referenced by S0 is of type T. T must not be a
724   specialized type.
726   The value in S0 must not be a pointer into the evaluation stack or frame
727   locals.
729 | IsNTypeMem<T>, D(Bool), S(Mem), NF
731   Sets D to true iff the value referenced by S0 is not of type T. T must not be
732   a specialized type.
734 | IsWaitHandle, D(Bool), S(Obj), NF
736   Sets D to true iff S0 is a subclass of WaitHandle.
738 | IsCol, D(Bool), S(Obj), NF
740   Sets D to true iff S0 is a collection.
742 | HasReifiedGenerics, D(Bool), S(Func), NF
744   Set D to true iff S0 is a reified function.
746 5. Branches
748 | JmpZero,                          ND, S(Int,Bool),                     B
750 | JmpNZero,                         ND, S(Int,Bool),                     B
752   Conditionally jump to based on S0.
754 | JmpSSwitchDest, ND, S(TCA) S(StkPtr) S(FramePtr), T
756   Jump to the target of a sswitch statement, leaving the region, where the
757   target TCA is S0.
759 | JmpSwitchDest, ND, S(Int) S(StkPtr) S(FramePtr), T
761   Jump to the target of a switch statement, leaving the region, using table
762   metadata <JmpSwitchData> and index S0, which must be a valid index in the
763   jump table.
765 | ProfileSwitchDest<handle,nCases>, ND, S(Int), NF
767   Profile a switch statement target.
769 | CheckSurpriseFlags, ND, S(FramePtr,StkPtr), B
771   Tests the implementation-specific surprise flags. If they're true, branches
772   to block B. This is done by comparing an evaluation stack pointer to the RDS
773   stackLimitAndSurprise word. Note that in a resumed, the frame pointer is not
774   pointing into the eval stack, so S0 should be a StkPtr in that case.
776 | HandleRequestSurprise, ND, NA, NF
778   Generate exceptions based on surprise flags on a per request basis.
779   Make sure CheckSurpriseFlags is true before calling HandleRequestSurprise.
781 | ReturnHook, ND, S(FramePtr) S(Cell), NF
783   Surprise flag hook for function returns.
785 | SuspendHookAwaitEF, ND, S(FramePtr) S(FramePtr) S(Obj), NF
787   Surprise flag hook for suspending eagerly executing async functions. The S0
788   frame was already teleported into S1. Decrefs S2 if it throws an exception.
790 | SuspendHookAwaitEG, ND, S(FramePtr) S(Obj), NF
792   Surprise flag hook for suspending eagerly executing async generators. The S0
793   frame has an associated AG, which is already linked to the newly constructed
794   AGWH in the blocked state. Decrefs S1 if it throws an exception.
796 | SuspendHookAwaitR, ND, S(FramePtr) S(Obj), NF
798   Surprise flag hook for suspending async functions and async generators resumed
799   at Await. The S0 frame has an associated AFWH/AGWH still in the running state,
800   S1 points to the child WH we are going to block on.
802 | SuspendHookCreateCont, ND, S(FramePtr) S(FramePtr) S(Obj), NF
804   Surprise flag hook for suspending generators and async generators during their
805   invocation. The S0 frame was already teleported into S1. Decrefs S2 if it
806   throws an exception.
808 | SuspendHookYield, ND, S(FramePtr), NF
810   Surprise flag hook for suspending generators and async generators at Yield.
812 | Unreachable<AssertReason>, ND, NA, T
814   Indicates an unreachable code path. Any instructions that are post-dominated
815   by an Unreachable may be treated as unreachable by the optimizer, and the
816   behavior of a program that attempts to execute an Unreachable is undefined.
818 | EndBlock<AssertReason>, ND, NA, T
820   Halt execution, without implying anything about the reachability of
821   instructions preceding this. Intended for use in internal tests or other code
822   not meant to be executed.
824 | Jmp, ND, SVar(Top), B|T
826   Unconditional jump to block B. In the second form, the target block must
827   start with a DefLabel with the same number of destinations as Jmp's number of
828   sources. Jmp parallel-copies its sources to the DefLabel destinations.
830 | DefLabel, DMulti, NA, NF
832   DefLabel defines variables received from a previous Jmp. A DefLabel with zero
833   destinations is a no-op, and the predecessor blocks may not necessarily end
834   in Jmp. A DefLabel with one or more destinations may only be reached by a Jmp
835   instruction with the same number of sources. Ordinary branch instructions may
836   not pass values to a DefLabel.
838 | Select, DUnion(1,2), S(Bool,Int) S(Top) S(Top), NF
840   If S0 is true/non-zero, return S1, otherwise return S2.
843 6. Loads
845 | LdStk<T,offset>, DParam(Cell), S(StkPtr), NF
847   Loads from S0 at offset (in cells), and puts the value in D as type T.
849 | LdLoc<T,localId>, DParam(Cell), S(FramePtr), NF
851   Loads local slot localId from the frame S0 and puts the value in D as type T.
853 | LdLocForeign<T>, DParam(Cell), S(FramePtr) S(Int), NF
855   Loads local slot S1 from the frame S0 and puts the value in D as type T.
856   Note that it does not perform the local optimizations that LdLoc does.
857   Users of this opcode need to ensure that the local is not optimized away.
859 | LdStkAddr<offset>, D(PtrToStk), S(StkPtr), NF
861   Loads the address of the stack slot given by the pointer in S0 at the given
862   stack offset (measured in cells).
864 | LdLocAddr<localId>, D(PtrToFrame), S(FramePtr), NF
866   Loads the address of the local slot localId from the frame S0 into D.
868 | LdRDSAddr<T,RDSHandle>, DParam(Ptr), NA, NF
870   Load the address of a Cell that lives at the specified RDS handle.
872 | LdInitRDSAddr<T,RDSHandle>, DParam(Ptr), NA, B
874   Load the address of a Cell that lives at the specified RDS handle. Branch if
875   the value at that address is Uninit.
877 | LdPairElem, D(InitCell), S(Obj) S(Int), NF
879   Load the element at S1 out of the Pair collection at S0.
881 | LdMem<T>, DParam(Cell), S(Mem), NF
883   Loads from S0 and puts the value in D.
885 | LdTVFromRDS<T,RDSHandle,includeAux>, DParam(InitCell), NA, NF
887   Load the TypedValue from the specified RDS handle. Must load the aux bits if
888   `includeAux` is true.
890 | LdContField<T>, DParam(Cell), S(Obj) C(Int), NF
892   Loads a property from the object referenced by S0 at the offset given by S1
893   and puts the value in D. S0 must be a Generator.
895 | LdClsInitElem<idx>, D(Cell), S(PtrToClsInit), NF
897   Load the cell at index `idx` from the class init vector at S0 into D0.
899 | LdColVec, D(Vec), S(Obj), NF
901   Load the vec array backing a collection instance in S0, which must be a
902   Vector or ImmVector, and that specific object type must be known at compile
903   time.
905 | LdColDict, D(Dict), S(Obj), NF
907   Load the dict array backing a collection instance in S0, which must be a
908   Map, Set, ImmMap, or ImmSet, and that specific object type must be known at
909   compile time.
911 | LdIterBase<T,iterId>, DParam(ArrLike), S(FramePtr), LA
913   Load the base of the iterator with type `T` at `iterId`. `T` must be a valid,
914   DataTypeSpecific-or-better type for the iterator's base; for example, it may
915   be based on an earlier call to CheckIter.
917 | LdIterPos<T,iterId>, DParam(Int|PtrToElem), S(FramePtr), NF
919 | LdIterEnd<T,iterId>, DParam(Int|PtrToElem), S(FramePtr), NF
921   Load the specified field of the iterator at `iterId`. These ops should only
922   be generated for iterators known to have a specialized type (via CheckIter).
923   The type param `T` should be compatible with this type - i.e. `T` should be
924   either an int or a pointer based on whether it's an index or pointer iter.
926 | LdFrameThis, DParam(Obj), S(FramePtr), NF
928   Loads into D the value of m_this from S0.
930 | LdFrameCls, DParam(Cls), S(FramePtr), NF
932   Loads into D the value of m_cls from S0.
934 | LdClsCtor, D(Func), S(Cls) S(Cls|Nullptr), NF
936   Loads into D the constructor of class S0. If the constructor cannot be called
937   from the context S1, raise an error.
939 | LdSmashable, D(Smashable), NA, NF
941   Loads a smashable value. The initial value is set to (1 << addr) + 1, where
942   addr is a pointer pointing to the value in TC. The lowest bit is set for
943   convenience of checking whether the value was already smashed.
945 | LdSmashableFunc, D(Func), S(Smashable), NF
947   Loads into D the func pointer stored in the higher 32 bits of S0.
949 | DefConst<T>, DParam(Top), NA, NF
951   Define a constant value of type T. D is presumed to be globally available and
952   the DefConst instruction will not actually appear in the IR instruction
953   stream.
955 | Conjure<T>, DParam(Top), NA, NF
957   Define a value of type T. This instruction aborts at runtime; it is meant to
958   be used in tests or code that is known to be unreachable.
960 | ConjureUse, ND, S(Cell), NF
962   Define a "use" of S0 effectively keeping the value alive. As with Conjure it
963   should not appear in reachable code.
965 | LdCls, D(Cls), S(Str) C(Cls|Nullptr), NF
967   Loads the class named S0 in the context of the class S1. Invokes autoload and
968   may raise an error if the class is not defined. The explicit context
969   parameter allows the compiler to simplify this instruction to a DefConst in
970   some cases. If S0 is constant, this instruction may be simplified to a
971   LdClsCached.
973 | LdClsCached, D(Cls), CStr, NF
975   Loads the class named S0 via the RDS. Invokes autoload and may raise an error
976   if the class is not defined.
978 | LdClsCachedSafe, D(Cls), CStr, B
980   Loads the class whose name is S0 out of the RDS. If the class is not defined,
981   branch to B.
983 | LdClsInitData, D(PtrToClsInit), S(Cls), NF
985   Loads the pointer to the property initializer array for class S0.
987 | LookupClsRDS, D(Cls|Nullptr), S(Str), NF
989   Lookup the cached-class RDS handle for a given class name. Dereference that
990   handle and return the associated Class, or null if not present.
992 | LdCns, D(InitCell), CStr, B
994   Load the constant named S0, branching to B if isn't present.
996 | LookupCnsE<T,constName>,  D(InitCell), CStr, PRc
998   Load a constant via the RDS. Raises a fatal error if it cannot define the
999   constant.  This should only be executed if LdCns on the same constant has
1000   failed.
1002 | LdClsCns<className,constantName>, DParam(InitCell), NA, B
1004   Load the constant 'constantName' for the class 'className'. If not
1005   initialized, branch to B.
1007 | LookupClsCns, D(InitCell), S(Cls) S(Str), NF
1009   Lookup a class constant. May raise errors if either the class or constant are
1010   not defined.
1012 | LookupClsCtxCns, D(Int), S(Cls) S(Str), NF
1014   Lookup a class context constant. May raise errors if the context constant
1015   is not defined, is abstract or is a type/value constant.
1017 | LdSubClsCns<constantName,slot>, D(Uncounted), S(Cls), NF
1019   Load the constant 'constantName' for the class S0. The constant is known to
1020   be in the given slot. If the returned value is Uninit, the constant is not
1021   initialized and it must be loaded using InitSubClsCns. Counted constants will
1022   never have their slot be initialized and thus always take the slow path.
1024 | InitSubClsCns<constantName,slot>, D(InitCell), S(Cls), NF
1026   Slow path for LdSubClsCns. Used when LdSubClsCns indicates the slot is
1027   uninitialized.
1029 | CheckSubClsCns<constantName,slot>, ND, S(Cls), B
1031   Check that the constant 'constantName' lives in the given slot for the class
1032   S0, and branch if not. S0 must have at least slot+1 constants.
1034 | ProfileSubClsCns<constantName,handle>, D(Cell), S(Cls), NF
1036   Load the constant 'constantName' for the class S0, profiling the observed
1037   slots. If the returned value is Uninit, the constant does not exist or is
1038   abstract or is a type-constant.
1040 | LdClsCnsVecLen, D(Int), S(Cls), NF
1042   Load the size of S0's constant table.
1044 | LdResolvedTypeCns<slot>, D(StaticDict), S(Cls), B
1046   Loads the resolved type constant in the slot `slot' on S0 or branches to B if
1047   the type constant is not resolved.
1049 | LdResolvedTypeCnsNoCheck<slot>, D(StaticDict), S(Cls), NF
1051   Loads the resolved type constant in the slot `slot' on S0. The type constant
1052   is assumed to be present and resolved.
1054 | LdTypeCns, D(StaticDict), S(Cls) S(Str), NF
1056   Loads type constant with name S1 from class S0, performing any necessary
1057   resolution. Raises an error if no such constant could be found, if S0::S1 is
1058   not a type constant, if resolution fails, or if S0::S1 is abstract.
1060 | LdTypeCnsNoThrow, D(StaticDict), S(Cls) S(Str), NF
1062   Loads type constant with name S1 from class S0, performing any necessary
1063   resolution. If no such constant can be found, if S0::S1 is not a type
1064   constant, if resolution fails, or if S0::S1 is abstract, then a "fake"
1065   invalid type-structure is returned.
1067 | LdResolvedTypeCnsClsName<slot>, DTypeCnsClsName, S(Cls), NF
1069   Loads the cached 'classname' field from the resolved type constant in the
1070   slot `slot' on S0. If there is no cached field, returns nullptr.
1072 | LdTypeCnsClsName, D(StaticStr), S(Cls) S(Str), NF
1074   Loads and resolved type constant with name S1 from class S0, as if by
1075   LdTypeCns. Returns the 'classname' field from that type constant. Raises an
1076   error if the type constant loading fails, or if there is no 'classname' field
1077   present.
1079 | LdClsMethodFCacheFunc<clsName,methodName>, D(Func), NA, B
1081   Loads the target cache entry for a forwarding call to clsName::methodName.
1082   If the method does not exist, or the cache hasn't been filled yet, branch to
1083   B.
1085 | LookupClsMethodFCache<clsName,methodName>,
1086 |    D(Func|Nullptr), C(Cls) S(FramePtr),
1087 |    NF
1089   Lookup clsName::methodName in the forwarding class method cache. S0 should be
1090   the Class named by clsName and S1 should be the current vm frame pointer. May
1091   return Nullptr if lookup fails using a subset of the required lookup paths,
1092   indicating that a more complete lookup path should be taken. May throw if the
1093   method does not exist.
1095 | LdClsMethodCacheFunc<clsName,methodName>, D(Func), NA, B
1097   Loads the target cache entry for the method clsName::methodName. If the
1098   method does not exist or the cache hasn't been filled yet, branch to B.
1100 | LdClsMethodCacheCls<clsName,methodName>, D(Cls), NA, NF
1102   Loads the target cache class context entry for a call to clsName::methodName
1103   from the current context. This instruction must only be used when the value
1104   is known to not be empty (i.e., LdClsMethodCacheFunc must have succeeded, or
1105   LookupClsMethodCache returned a non-null value).
1107 | LookupClsMethodCache<clsName,methodName>, D(Func|Nullptr), S(FramePtr), NF
1109   Lookup a function in the class method targetcache. The class name and method
1110   name are clsName and methodName, respectively. S0 is the current vm frame
1111   pointer. Returns Nullptr if the method cannot be found using a subset of the
1112   required lookup paths, indicating that a more complete lookup path should be
1113   taken. May throw if the method does not exist.
1115 | LdIfaceMethod<vtableIdx,methodIdx>, D(Func), S(Cls), NF
1117   Load the Func* at methodIdx from the vtable at vtableIdx in S0.
1119   If methodIdx represents an instance method, S0 must be a non-abstract class.
1120   This requirement is naturally satisfied if S0 comes from LdObjClass.
1122 | LdFuncVecLen, D(Int), S(Cls), NF
1124   Load the funcVecLen field from S0.
1126 | LdClsMethod, D(Func), S(Cls) C(Int), NF
1128   Load the Func* in slot S1 of the class method table for class S0. (Note that
1129   this vector is located before the class in memory, so the non-negative slots
1130   will map to negative offset loads.)
1132 | LookupClsMethod, D(Func|Nullptr), S(Cls) S(Str) S(Obj|Nullptr) S(Cls|Nullptr),
1133 |                  NF
1135   Lookup a pointer to a class method for a given class S0 and method name S1,
1136   assuming caller's $this is S2 and caller is defined in a class S3. Throws or
1137   fatals if the method does not exist, is not accessible, or is not a static
1138   method. Returns nullptr if it is an instance method defined in S2's class
1139   hierarchy, indicating that this legacy call should be handled by interpreter.
1141 | LdPropAddr<T,index>, D(LvalToProp), S(Obj), NF
1143   Load the address of the object property at physical index `index`.
1145 | LdInitPropAddr<T,index>, D(LvalToProp), S(Obj), B
1147   Load the address of the object property at physical index `index`. Branch if
1148   the value at that address is Uninit.
1150 | LdGblAddr, D(LvalToGbl|Nullptr), S(Str), NF
1152   Loads a pointer to a global with name S0, or a null lval if that global is
1153   not already defined.
1155 | LdGblAddrDef, D(LvalToGbl), S(Str), NF
1157   Loads a pointer to a global with name S0, defining it to be InitNull if it
1158   is not already defined.
1160 | ProfileGlobal, ND, S(Str), NF
1162   Profile an (attempted) access of a global with name S0.
1164 | LdClsPropAddrOrNull<readonly op>, D(PtrToSProp|Nullptr), S(Cls) S(Str)
1165 |                     C(Cls|Nullptr) C(Bool) C(Bool), NF
1167   Loads a pointer to a static class property. S0 points to the class, S1 is the
1168   property name, and S2 is the class representing the context of the code
1169   accessing the property. If class S0 does not have a visible and accessible
1170   static property named S1, then nullptr is returned. An exception
1171   will be thrown if the property is marked LateInit and its value is
1172   Uninit, unless S3 is true. An exception is thrown if S4 is true,
1173   and the property is constant. An exception is also thrown if there is a
1174   readonly violation with the readonly op.
1176 | LdClsPropAddrOrRaise<readonly op>, D(PtrToSProp), S(Cls) S(Str)
1177 |                       C(Cls|Nullptr) C(Bool) C(Bool), NF
1179   Loads a pointer to a static class property. S0 points to the class, S1 is the
1180   property name, and S2 is the class representing the context of the code
1181   accessing the property. If class S0 does not have a visible and accessible
1182   static property named S1, then nullptr is returned. An exception
1183   will be thrown if the property is marked LateInit and its value is
1184   Uninit, unless S3 is true. An exception is thrown if S4 is true,
1185   and the property is constant. An exception is also thrown if there is a
1186   readonly violation with the readonly op.
1188 | LookupSPropSlot, D(Int), S(Cls) S(Str), NF
1190   Lookup the slot index of the static property with the name S1 on the class
1191   S0, returning -1 if not found.
1193 | LdObjMethodD, D(Func), S(Cls) S(Str), NF
1195   Loads a func pointer pointing to the instance method that would be called
1196   if a method named S1 is invoked on an instance of S0. Raises a fatal if the
1197   class does not have an accessible method with the given name.
1199 | LdObjMethodS<methodName>, D(Func), S(Cls) S(Smashable), NF
1201   Loads a func pointer pointing to the instance method that would be called
1202   if a `methodName` is invoked on an instance of S0. Caches the mapping in
1203   the TC cache (using S1) and target cache. Raises a fatal if the class does
1204   not have an accessible method with the given name.
1206 | LdObjInvoke, D(Func), S(Cls), B
1208   Try to load a cached non-static __invoke Func from the Class in S0, or branch
1209   to block B if it is not present.
1211 | LdObjClass, DLdObjCls, S(Obj), NF
1213   Load the class out of the object in S0 and put it in D.
1215 | LdClsName, D(StaticStr), S(Cls), NF
1217   Load the name of the Class* in S0.
1219 | LdLazyCls, D(LazyCls), S(Cls), NF
1221   Load a lazy class corresponding to the Class* in S0.
1223 | LdLazyClsName, D(StaticStr), S(LazyCls), NF
1225   Load the name of the LazyClass in S0.
1227 | LdFunc, D(Func|Nullptr), S(Str), NF
1229   Loads the Func whose name is S0, invoking autoloader if it is not defined yet.
1230   Fatals if the named function is not defined, and the autoloader fails to
1231   define it. Returns nullptr if S0 contained '::', indicating that this legacy
1232   call should be handled by interpreter.
1234 | LdFuncCached<funcName>, D(Func), NA, NF
1236   Loads the Func whose name is funcName from the RDS, invoking autoload if it
1237   not defined yet. Fatal if function autoloader fails to define it.
1239 | LookupFuncCached<funcName>, D(Func), NA, NF
1241   Loads the Func whose name is given from %1, invoking autoload if it is not
1242   defined yet. Fatal if the function autoload fails to define it. This
1243   instruction does not assume the loaded function will be called immediately,
1244   so it will raise a resolution failure error instead of a call failure error.
1246 | LdFuncNumParams, D(Int), S(Func), NF
1248   Returns the value of func->numParams().
1250 | LdFuncInOutBits, D(Int), S(Func), NF
1252   Loads the Func::m_inoutBits field.
1254 | LdARFunc, D(Func), S(FramePtr), NF
1256   Loads the result of ar->func() where ar is S0.
1257   Users of this opcode need to ensure that the writing of m_funcId to S0 is
1258   not optimized away.
1260 | LdFuncName, D(StaticStr), S(Func), NF
1262   Loads the full name of S0.
1264 | LdMethCallerName<isCls>, D(StaticStr), S(Func), NF
1266   Loads the meth_caller cls or func name.
1268 | LdFuncCls, D(Cls|Nullptr), S(Func), NF
1270   Loads the Class* of S0.
1272 | LdStrLen, D(Int), S(Str), NF
1274   Load the length of the string in S0.
1276 | FuncHasAttr<attr>, D(Bool), S(Func), NF
1278   Tests for Func::m_attrs & attr.
1280 | ClassHasAttr<attr>, D(Bool), S(Cls), NF
1282   Tests for Class::m_attrsCopy & attr.
1284 | LdFuncRequiredCoeffects, D(Int), S(Func), NF
1286   Returns the value of func->requiredCoeffects().
1288 | LdClsFromClsMeth, D(Cls), S(ClsMeth), NF
1290   Load the Class* of the ClsMethDataRef in S0.
1292 | LdFuncFromClsMeth, D(Func), S(ClsMeth), NF
1294   Load the Func* of the ClsMethDataRef in S0.
1296 | LdClsFromRClsMeth, D(Cls), S(RClsMeth), NF
1298   Load the Class* of the RClsMeth* in S0.
1300 | LdFuncFromRClsMeth, D(Func), S(RClsMeth), NF
1302   Load the Func* of the RClsMeth* in S0.
1304 | LdGenericsFromRClsMeth, D(Vec), S(RClsMeth), NF
1306   Load the ArrayData* containing the generics attached to the RClsMeth in S0
1308 | LdFuncFromRFunc, D(Func), S(RFunc), NF
1310   Load the Func* of the RFuncData in S0
1312 | LdGenericsFromRFunc, D(Vec), S(RFunc), NF
1314   Load the ArrayData* containing the generics attached to the RFuncData in S0
1316 | LdImplicitContext, D(Obj|InitNull), NA, NF
1318   Loads implicit context from RDS.
1320 7. Allocation
1322 | AllocInitROM<rom>, D(VoidPtr), NA, NF
1324   Allocate a block of memory for `rom`, and initialize it's contents with the
1325   ROM data.  Dest is the base of the newly allocated block.
1327 | AllocObj, DAllocObj, S(Cls), PRc
1329   Allocates a new object of class S1.
1331 | AllocObjReified, DAllocObj, S(Cls) S(Vec), LA|PRc
1333   Allocates a new object of class S1 and sets S2 as the reified generics of
1334   this class. If this class is not reified, this instruction raises an error.
1336 | InitProps<class>, ND, NA, NF
1338   Calls the property initializer function (86pinit) for class.  May throw.
1340 | InitSProps<class>, ND, NA, NF
1342   Calls the static property initializer functions (86sinit and/or 86linit)
1343   for class. May throw.
1345 | CheckRDSInitialized<RDSHandle>, ND, NA, B
1347   Check if the RDS entry at the specified handle is initialized, and branches
1348   if not.
1350 | MarkRDSInitialized<RDSHandle>, ND, NA, NF
1352   Mark the given RDS entry as being initialized.
1354 | MarkRDSAccess<RDSHandle>, ND, NA, NF
1356   Mark the given RDS entry as being accessed for profiling.
1358 | PropTypeRedefineCheck, ND, C(Cls) C(Int), NF
1360   Check that the specified property at the slot S1 on S0, which redeclares a
1361   property in the parent, has a declared type equivalent to the parent
1362   declaration.
1364 | DebugBacktrace, D(Vec), S(Int), PRc
1366   Obtain stack trace by calling the debug_backtrace() method.
1368 | InitThrowableFileAndLine, ND, S(Obj), NF
1370   Initialize Throwable's file name and line number assuming the stack trace
1371   was already initialized and the current vmfp() is a built-in.
1373 | NewInstanceRaw<class>, DAllocObj, NA, PRc
1375   Allocates an instance of class.
1377 | InitObjProps<class>, ND, S(Obj), NF
1379   Initializes properties of object S0.
1381 | ConstructInstance<class>, DAllocObj, NA, PRc
1383   Call the custom instance constructor of an extension class.
1385 | ConstructClosure<class>, DAllocObj, S(Cls|Obj|Nullptr), CRc|PRc
1387   Call the custom instance constructor of a Closure.
1389   Store the context represented by S0 into the newly constructed closure object.
1390   S0 may be a Nullptr when there is no context (i.e. the closure is being used
1391   in a non-method).
1393 | LockObj, ND, S(Obj), NF
1395   Clear the IsBeingConstructed flag on the object.
1397 | NewLoggingArray, DLoggingArrLike, S(Vec,Dict,Keyset), PRc|CRc|LA
1399   Maybe create a LoggingArray wrapping the vanilla array-like S0. The decision
1400   may be based on flags or sampling. If we don't create an array, we return S0
1401   unchanged. The result will match S0 in type. For static array constructors
1402   (including property initial values), the result will be static.
1404 | ProfileArrLikeProps, ND, S(Obj), NF
1406   Maybe create LoggingArrays wrapping each of the vanilla array-likes in the
1407   properties of the newly-initialized object S0. The decision may be based on
1408   flags or sampling. This op mutates the object's props in place.
1410 | LogArrayReach<TransSrcKey>, ND, S(ArrLike), LA
1412   If the supplied array is a LoggingArray, log the current tracelet and SrcKey
1413   for use during specialization.
1415 | LogGuardFailure<T>, ND, S(ArrLike), LA
1417   Log that we failed to guard input S0 to the given type. Useful for catching
1418   performance bugs in bespoke layout selection, but may have more general use.
1420 | NewDictArray, D(Dict), C(Int), PRc
1422   Allocate a new dict with the expected capacity S0.
1424 | NewKeysetArray<offset,keys>, D(Keyset), S(StkPtr), PRc|CRc
1426   Allocate a new keyset containing N elements off the stack given by S0, at
1427   `offset'. This instruction moves the elements off the stack without
1428   manipulating their reference counts.
1430 | AllocVec<size>, D(Vec), NA, PRc
1432   Allocate a new uninitialized vector array with space for size elements in it.
1433   The array will be initialized with values using either InitVecElem or
1434   InitVecElemLoop.
1436 | InitVecElem<index>, ND, S(Vec) S(Cell), CRc
1438   Store the S1 into the slot at index in array S0. This instruction assumes
1439   that it doesn't have to incref the value being stored. Used to initialize an
1440   array allocated with AllocVec.
1442 | InitVecElemLoop<offset,size>, ND, S(Vec) S(StkPtr), CRc
1444   Move `size' elements from the stack given by S1, at `offset', into the array
1445   S0.  Assumes that the first element on the stack is the last element in the
1446   array.  Used to initialize an array allocated with or AllocVec that was too
1447   big for us to use a series of InitVecElem ops.
1449 | AllocStructDict<keys...>,   D(Dict), NA, PRc
1451   Allocate a new key/value dict or mixed-layout array, given N string literal
1452   immediates for keys. This op initializes the header and hash table of the
1453   new array-like, but does not its elements; use InitDictElem for that.
1455 | InitDictElem<index,key>, ND, S(Dict) S(Cell), NF
1457   Initialize the element at position `index` in array S0 to have the string
1458   literal `key` as its key and S1 as its value. This instruction assumes that
1459   S1 has already been inc-reffed. Used with the result of AllocStructDict.
1461 | NewStructDict<offset,keys...>,   D(Dict), S(StkPtr), PRc|CRc
1463   Allocate a new key/value dict, given N string literal immediates for keys
1464   and N stack elements at `offset` on stack S0 for values.  This op assumes it
1465   can move values from the stack without inc-reffing them.
1467 | AllocBespokeStructDict<layout>, DStructDict, NA, PRc
1469   Allocate a new, empty dict with the bespoke StructLayout `layout`.
1471 | InitStructPositions<slots>, ND, SStructDict, NF
1473   Initialize the size and iterator positions of the bespoke StructDict S0 for
1474   the fields specified by `slots`. This instruction does not set the elements
1475   of the dict; use InitStructElem for that.
1477 | InitStructElem<slot,key>, ND, SStructDict S(InitCell), CRc
1479   Initialize the element at slot `slot` corresponding to `key` in StructDict S0
1480   with S1. This instruction assumes that S1 has already been inc-reffed.
1481   Used with the result of AllocUninitBespokeStructDict.
1483 | NewBespokeStructDict<offset,layout,slots...>, DStructDict, S(StkPtr), PRc|CRc
1485   Allocate a new dict with the bespoke StructLayout `layout`.  Then, init the
1486   N fields with the given `slots` with N stack elements starting at `offset`.
1487   This op moves stack values with no refcounting.
1489 | NewCol<type>, DCol, NA, PRc
1491   Create an empty new collection of `type'. `type' cannot be Pair.
1493 | NewPair<offset>, DCol, S(Cell) S(Cell), PRc|CRc
1495   Allocate a new Pair and fill it with the given cells. Ownership of the cells
1496   is transferred from $1 and $2 to the pair without manipulating the refcounts.
1498 | NewColFromArray<type>, DCol, S(Vec,Dict), PRc|CRc
1500   Create a collection of `type` from a Vec or Dict kind. `type` cannot be
1501   Pair. S0 must be vec kind when `type` is Vector or ImmVector, and must be
1502   dict kind otherwise. Ownership of S0 is transferred from $1 to the
1503   collection, without manipulating the refcount.
1505 | Clone, DofS(0), S(Obj), PRc
1507   Allocate an object by cloning S0.
1509 | NewClsMeth, D(ClsMeth), S(Cls) S(Func), NF
1511   Allocate a new ClsMethDataRef.
1513 | NewRClsMeth, D(RClsMeth), S(Cls) S(Func) S(Vec), LA|PRc
1515   Allocate a new reified class method by storing the Class in S0,
1516   the Func in S1 and the reified generics in S2.
1518 | NewRFunc, D(RFunc), S(Func) S(Vec), LA|PRc
1520   Allocate a new reified function pointer given the Func pointer in S0
1521   and reified generics in S1.
1523 | FuncCred, DAllocObj, S(Func), PRc
1525   Allocate a new FunctionCredential
1527 8. Call & Return
1529 | BeginInlining<func, offset>, D(FramePtr), S(StkPtr), NF
1531   Marks the start of an inlined function whose stack resides offset cells below
1532   the SP.
1534   Defines a new frame pointer for an ActRec at callBCOff for use in an inlined
1535   region. In resumed contexts the new frame is computed relative to S0 as S1 is
1536   not a stack location.
1538 | EndInlining, ND, S(FramePtr), NF
1540   Marks the end of an inlined function. S0 is no longer a valid frame location.
1542 | InlineCall<retSPOff>, ND, S(FramePtr) S(FramePtr), NF
1544   Sets the current vmfp for an inlined call to S0, and the m_sfp of S0 to the
1545   previous vmfp, S1.
1547   This instruction is primarily used to represent an inlined frame in the IR
1548   when it cannot be eliminated during a side-exit. It performs callee-side
1549   responsibilities for setting up an activation record (i.e. setting the return
1550   ip, m_func and m_callOff, storing the frame pointer into D).
1552   The caller frame pointer is passed as S1. This is used to keep track of the
1553   call chain of inlined functions for simplification and dead code elimination.
1555 | DefFuncEntryFP<func>,
1556 |   D(FramePtr),
1557 |   S(FramePtr) S(StkPtr) S(Int) S(Cls|Obj|Nullptr) S(Int),
1558 |   NF
1560   Writes a callee's frame and defines a frame pointer.
1562   `func': the function being called
1563   S0: frame pointer of the caller
1564   S1: stack pointer pointing to the space reserved for the callee's frame
1565   S2: prologue flags (see PrologueFlags)
1566   S3: prologue context
1567   S4: callee func id
1569 | Call<offset,numParams,callOff,destroyLocals>,
1570 |   DCall,
1571 |   S(StkPtr) S(FramePtr) S(Func) S(Cls|Obj|Nullptr) S(Int),
1572 |   CRc|PRc
1574   Transfer control to a callee S2, based on the pre-live activation record and
1575   set of args on the stack pointed to by S0 at `offset'. S1 is the current
1576   caller frame pointer. S3 is the context (nullptr, $this or static::class).
1577   S4 is the ambient coeffects.
1579 | NativeImpl<func>, ND, S(FramePtr) S(StkPtr), NF
1581   Execute a call to the native builtin specified by the current function. S0
1582   and S1 should be the current vmfp and vmsp, respectively.
1584 | CallBuiltin, DBuiltin, S(FramePtr) S(StkPtr) SVar(Mem,Cell,Nullptr), PRc
1586   Call builtin function with N arguments. S0 and S1 should be the current vmfp
1587   and vmsp, respectively.
1589   The source and destination types correspond to C++ parameter and return types
1590   as follows:
1592     C++ type            HHIR type         Position
1593     -----------------   ---------         --------
1594     bool                Bool              source, destination
1595     int64_t             Int               source, destination
1596     double              Dbl               source, destination
1597     const String&       Ptr               source
1598     const Array&        Ptr               source
1599     const Object&       Ptr               source
1600     const Variant&      Ptr               source
1601     Variant&            Ptr               source (ref param)
1602     String              {Str|InitNull}    destination
1603     Array               {Arr|InitNull}    destination
1604     Object              {Obj|InitNull}    destination
1605     Variant             {Cell-UninitNull} destination
1607 | RetCtrl<spOff,suspendingResumed>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1609   Ensure that S0 + `spOff' (in cells) is stored in rvmsp and that S1's saved
1610   frame pointer is stored in rvmfp, then return to the saved return address in
1611   S1.  The return value is S2, which is passed via the rret_*() registers to
1612   the caller.  The `suspendingResumed' flag indicates when this instruction is
1613   suspending a resumable rather than performing a normal function return.
1615 | AsyncFuncRetPrefetch, ND, S(FramePtr), NF
1617   Prefetch the WaitHandle that the current (async, resume-mode) frame's AFWH
1618   is blocking. If this AFWH is blocking multiple WaitHandles, we will only
1619   prefetch the first one; in any case, this IR op has no visible semantics.
1621 | AsyncFuncRet<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1623   Return from a resumed async function, assuming no surprise. Ensures that
1624   S0 + `spOff` (in cells) is stored in rvmsp and that S1 is stored in rvmfp,
1625   packs return value S2 into registers and calls the `asyncFuncRet` unique
1626   stub. The stub stores the result into the wait handle associated with the
1627   frame pointer, marks it as finished, unblocks its parents and if possible,
1628   directly resumes the first parent (fast path), or a pending fast runnable
1629   ResumableWaitHandle (slower path). Otherwise, it will exit VM and return
1630   control to the asio scheduler (slow path). The stack must contain exactly one
1631   cell containing uninitialized garbage, which will be populated by the stub
1632   either to pass the return value to the resumed function, or to return null
1633   to the scheduler.
1635 | AsyncFuncRetSlow<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell), T
1637   Return from a resumed async function, assuming unknown surprise flag state
1638   after the previous surprise was handled by executing "return" event hook.
1639   Calls the `asyncFuncRetSlow` stub, which re-checks the surprise flag and
1640   transfers control to the AsyncFuncRet if it was clear, or performs the slow
1641   path of AsyncFuncRet if it was not, without resuming another function, as
1642   we are not able to call a potential "resume await" event hook from the stub.
1644 | AsyncGenRetR<spOff>, ND, S(StkPtr) S(FramePtr), T
1646   Return from an async generator resumed at Await, assuming unknown surprise
1647   flag state. Ensures that S0 + `spOff` (in cells) is stored in rvmsp and that
1648   S1 is stored in rvmfp and calls the `asyncGenRetR` unique stub. The stub
1649   stores `null` result indicating end of iteration into the async generator
1650   wait handle associated with the generator associated with the frame pointer,
1651   marks the wait handle as finished and unblocks its parents. If the surprise
1652   flag was not set and there is a pending fast runnable ResumableWaitHandle,
1653   it resumes it directly (slow path). Otherwise, it will exit VM and return
1654   control to the asio scheduler (turtle path). The stack must contain exactly
1655   one cell containing uninitialized garbage, which will be populated by the
1656   stub either to pass the return value to the resumed function, or to return
1657   null to the scheduler.
1659 | AsyncGenYieldR<spOff>, ND, S(StkPtr) S(FramePtr) S(Cell) S(Cell), T
1661   Yield from an async generator resumed at Await, assuming unknown surprise
1662   flag state. Works the same as `AsyncGenRetR`, except the async generator
1663   wait handle is populated with `tuple($key, $value)` result of the iteration
1664   step, where `$key` is given by S2 and `$value` by S3.
1666 | AsyncSwitchFast<spOff>, ND, S(StkPtr) S(FramePtr), T
1668   Switch control to another ResumableWaitHandle. Ensures that S0 + `spOff`
1669   (in cells) is stored in rvmsp and that S1 is stored in rvmfp and calls the
1670   `asyncSwitchCtrl` unique stub, which tries to resume a pending fast runnable
1671   ResumableWaitHandle (fast path) if possible, otherwise it will exit VM and
1672   return control to the asio scheduler (slow path). As with AsyncRetFast, the
1673   stack must contain exactly one cell containing uninitialied garbage.
1675 | LdRetVal<T>, DParam(InitCell), S(FramePtr), NF
1677   Load the return value from the already-returned-from ActRec pointed to by S0
1678   into the dest.  This is used by NativeImpl.  TODO(#7150575): We want to make
1679   NativeImpl return a TypedValue in the C++ ABI registers.
1681 | GenericRetDecRefs, ND, S(FramePtr), NF
1683   Does decrefs of all the current function's locals, where S0 is a pointer to
1684   the relevant activation record. This instruction may not occur in an inlined
1685   call.
1687 9. Stores
1689 | StPtrAt, ND, S(VoidPtr) S(VoidPtr), NF
1691   Store the pointer address S1 to pointer S0.
1693 | StTypeAt, ND, S(VoidPtr) S(Cell), NF
1695   Store the type of S1 to pointer S0.
1697 | StClsInitElem<idx>, ND, S(PtrToClsInit) S(Cell), NF
1699   Store S1 into the slot at index `idx` in the class init vector at S0.
1701 | StMem, ND, S(Mem) S(Cell), NF
1703   Store S1 into the location pointed to by S0.
1705 | StMemMeta, ND, S(Mem) S(Cell), NF
1707   Logically store S1 into the location pointer to by S0. This is like StMem,
1708   but emits no code. It exists to update frame state tracking.
1710 | StTVInRDS<RDSHandle,includeAux>, ND, S(InitCell), NF
1712   Store the TypedValue in S0 into the specified RDS handle. Must store the aux
1713   bits if `includeAux` is true.
1715 | StImplicitContext, ND, S(Obj|InitNull), NF
1717   Sets the implicit context to S0.
1719 | StImplicitContextWH, ND, S(Obj), NF
1721   Stores the implicit context from RDS to the WaitHandle in S0.
1723 | StLoc<localId>, ND, S(FramePtr) S(Cell), NF
1725   Store S1 to local number localId on the frame pointed to by S0.
1727 | StLocMeta<localId>, ND, S(FramePtr) S(Cell), NF
1729   Logically store S1 to local number localId on the frame pointed to by
1730   S0. This is like StLoc, but emits no code. It exists to update frame state
1731   tracking.
1733 | StLocRange<localIds>, ND, S(FramePtr) S(Cell), NF
1735   Store S1 to the local variables corresponding to localIds, on the frame
1736   pointed to by S0.
1738 | StIterBase<iterId>, ND, S(FramePtr) S(ArrLike,Nullptr), LA
1740   Sets the base of the iterator at `iterId` to the pointer S1. The array must
1741   match the specialized type of the iterator, or be null (for local iterators).
1743 | StIterType<iterId,iterType>, ND, S(FramePtr), NF
1745   Sets the type of the iterator at `iterId` to `iterType`. This type must be a
1746   specialized type. Also sets auxiliary fields (like next helper index).
1748 | StIterPos<iterId>, ND, S(FramePtr) S(Int|PtrToElem), NF
1750 | StIterEnd<iterId>, ND, S(FramePtr) S(Int|PtrToElem), NF
1752   Store S1 to the given field of the iterator at `iterId`. S1 must be an int if
1753   we're doing index iteration and a pointer if we're doing pointer iteration.
1755 | StStk<offset>, ND, S(StkPtr) S(Cell), NF
1757   Store S1 to the stack pointed to by S0, at a given offset (in cells).
1759 | StStkMeta<offset>, ND, S(StkPtr) S(Cell), NF
1761   Logically store S1 to the stack pointed to by S0, at a given offset (in
1762   cells). This is like StStk, but emits no code. It exists to update frame
1763   state tracking.
1765 | StStkRange<offsets>, ND, S(StkPtr) S(Cell), NF
1767   Store S1 to the stack slots at the given offsets from S0.
1769 | StOutValue<index>, ND, S(FramePtr) S(Cell), NF
1771   Store S1 in a caller allocated out-value vm stack cell index cells above
1772   S0 on the stack.
1774 | LdOutAddr<index>, D(PtrToOther), S(FramePtr), NF
1776   Load the address of the storage for out parameter `index` provided by the
1777   callee (the address will be a location on the callee stack).
1779 | RecordReifiedGenericsAndGetTSList, D(Vec), S(Vec), CRc|LA
1781   Takes a varray of reified generics from the stack and adds them to the reified
1782   generics table and returns the input varray of reified generics, possibly
1783   static
1785 | StFrameCtx, ND, S(FramePtr) S(Obj,Cls), NF
1787   Store object or class S1 on frame S0.
1789 | StFrameFunc<func>, ND, S(FramePtr), NF
1791   Store the func in m_funcId/m_func for S0.
1793 | StFrameMeta<callBCOff,flags>, ND, S(FramePtr), NF
1795   Store the m_callOffAndFlags field of S0.
1797 10. Trace exits
1799 | StVMFP, ND, S(FramePtr), NF
1801 | StVMSP, ND, S(StkPtr), NF
1803 | StVMPC, ND, C(Int), NF
1805 | StVMReturnAddr, ND, C(Int), NF
1807 | StVMRegState, ND, C(Int), NF
1809   Sets the VM register state to the specified state. This is used
1810   to track whether the register state is clean or dirty as
1811   EagerSyncVMRegs is moved around by store elimination.
1813 | ReqBindJmp<target,invSPOff,irSPOff>, ND, S(StkPtr) S(FramePtr), T
1815   Emit a jump to a translation starting at `target'. If it does not exist, jump
1816   to a service request that will translate the code and bind this jump to it.
1818 | ReqRetranslate<irSPOff>, ND, S(StkPtr) S(FramePtr), T
1820   Emit a jump to a service request that will chain to a retranslation of this
1821   tracelet.
1823   This instruction is used in exit traces for a type prediction that occurs at
1824   the first bytecode offset of a tracelet.
1826 | ReqRetranslateOpt<irSPOff>, ND, S(StkPtr) S(FramePtr), T
1828   Emit a service request to retranslate the current function with a higher
1829   optimization gear. This instruction is used in exit traces that trigger
1830   profile-guided optimizations.
1832 | ReqInterpBBNoTranslate<target,invSPOff,irSPOff>, ND, S(StkPtr) S(FramePtr), T
1834   Jump to the `interpHelperNoTranslate' stub, which first interprets the basic
1835   block starting at `target' and then continues interpreting basic blocks until
1836   an already existing translation is found.
1839 11. Refcounting and copies
1841 | Mov, DofS(0), S(Top), P
1843   Defines D as S0. May imply register-to-register moves at code generation
1844   time. Does not imply an incref or any other manipulation of S0.
1846 | IncRef, ND, S(Cell), NF
1848   If S0 is a refcounted type, increment its refcount.
1850 | DecRef<locId>, ND, S(Cell), CRc
1852   Decrease the reference count of S0 by one, and call a destructor for types
1853   that require it if it goes to zero.
1855   The locId is just a hint to the runtime indicating which local variable is
1856   being DecRef'd, if any.
1858 | DecRefNZ<locId>, ND, S(Cell), CRc
1860   Decrease the reference count of S0 by one, do not check if it goes to zero.
1861   This instruction can be used for more efficient code when it is provable that
1862   the reference count cannot go to zero.
1864 | ProfileDecRef<locId>, ND, S(Cell), NF
1866   Update the DecRefProfile for the given input as if it were dec-ref-ed, but do
1867   not actually dec-ref it. We can use this op for e.g. iterator output locals,
1868   because we don't specialize iterators in profiling translations.
1870 | ReleaseShallow<locId>, ND, S(ArrLike), CRc|LA
1872   Release memory associated with array S0 without performing any other
1873   operations.
1875 | DecReleaseCheck<locId>, ND, S(Cell), B|P
1877   Decrease the refcount of S0 and fall through if the refcount goes to zero.
1878   Otherwise, branch to B.
1880 12. Misc
1882 | DefFP<offset>, D(FramePtr), NA, NF
1884   Creates a temporary D representing the current VM frame pointer.
1886   If the offset is specified, the frame is located at that offset from the SP,
1887   otherwise the frame either lives on the heap, or its position on the stack
1888   is unknown.
1890 | DefFrameRelSP<irSPOff, bcSPOff>, D(StkPtr), S(FramePtr), NF
1892 | DefRegSP<irSPOff, bcSPOff>, D(StkPtr), NA, NF
1894   Defines a stack positioned relative to the frame or the rvmsp register.
1896   Creates a temporary D representing the current VM stack pointer:
1897   - DefFrameRelSP: D points to the same location as the frame pointer S0
1898   - DefRegSP: D is the memory address given by the rvmsp register
1900   The logical stack starts at the stack base and its position and size is
1901   defined by these values:
1902   - `irSPOff' is the offset from the stack base to D
1903   - `bcSPOff' is the offset from the stack base to the top of the stack
1905   DefFrameRelSP is used at the beginning of translations of non-resumed
1906   functions to represent the state of the stack on entry.
1908   DegRegSP is used at the beginning of translations of prologues and
1909   resumed functions to represent the state of the stack on entry.
1911   In prologues, the stack base represents a stack without any func arguments,
1912   i.e. it is pointing to the empty space reserved for an ActRec.
1914   In resumables, the stack base represents an empty VM stack.
1916 | LoadBCSP<irSPOff>, D(StkPtr), S(StkPtr), NF
1918   Gets the bytecode stack pointer from IR stack pointer, for use in eager
1919   syncing.
1921 | DefFuncPrologueFlags, D(Int), NA, NF
1923 | DefFuncPrologueCallee, D(Func), NA, NF
1925 | DefFuncPrologueNumArgs, D(Int), NA, NF
1927 | DefFuncPrologueCtx, DParam(Cls|Obj), NA, NF
1929   Creates a temporary D representing prologue flags, callee function pointer,
1930   number of arguments, or context passed to the prologue.
1932   May be used only at the beginning of a prologue or a stub used in a prologue
1933   context.
1935 | ConvFuncPrologueFlagsToARFlags, D(Int), S(Int), NF
1937   Convert a function prologue flags to function entry flags.
1939 | Count, D(Int), S(Cell), NF
1941   Computes the number of elements in S0. The count of an array is the number of
1942   elements it contains, without recursing into containers in the array.
1943   Subtypes of Bool|Int|Dbl|Str|Res have a count of 1, subtypes of Null have a
1944   count of 0. The count of objects that implement the Countable interface is
1945   computed by returning the value of their count method. Objects that do not
1946   implement Countable have a count of 1.
1948 | CountVec,        D(Int), S(Vec),    LA
1950 | CountDict,       D(Int), S(Dict),   LA
1952 | CountKeyset,     D(Int), S(Keyset), LA
1954 | CountCollection, D(Int), S(Obj),    NF
1956   Computes the number of elements in S0 using the same definition as Count,
1957   but with a restriction on the input type that allows for optimizations.
1959 | Nop, ND, NA, NF
1961   Does nothing. It's sometimes useful for the simplifier to insert one of these
1962   in the instruction stream.
1964 | JmpPlaceholder, ND, NA, B
1966   Does nothing if executed. Semantically, this instruction carries a taken edge
1967   to a block of speculatively-generated code during initial IR generation, such
1968   as specialized code for an iterator init or next which we may or may not use.
1969   If it survives irgen, it should be eliminated in the first DCE pass.
1971 | CheckFuncNeedsCoverage<Func>, ND, NA, B
1973   Checks if Func needs to have coverage information recorded for the current
1974   request.
1976 | RecordFuncCall<Func>, ND, NA, NF
1978   Records a call to Func for a function call based code coverage report.
1980 13. Runtime helpers
1982 | VerifyParamCls<func,param,tc>, ND, S(Obj) S(Cls) S(Cls|Nullptr), NF
1984   Verify parameter type for classes or traits. If S1 does not extend (if S2 is
1985   a class) or implement (if S2 is an interface) S2, this instruction will raise
1986   a recoverable fatal error describing the type mismatch.
1988 | VerifyParamCallable<func,param>, ND, S(Cell), NF
1990   If S0 is not callable, as defined by the php function is_callable, this
1991   instruction will raise a recoverable fatal error describing the type
1992   mismatch.
1994 | VerifyParamFail<func,param,tc>, DVerifyParamFail, S(Cell) S(Cls|Nullptr), NF
1996   Assumes that parameter specified in extra-data in the current function
1997   has failed a its type check. Depending on the typehint being verified and
1998   a number of runtime options, may coerce the parameter to the correct type i
1999   or raise a recoverable fatal error describing the type mismatch.
2001 | VerifyParamFailHard<func,param,tc>, ND, S(Cell) S(Cls|Nullptr), T
2003   A terminal version of VerifyParamFail, to be used when the compiler can
2004   statically prove that this failure will result in a fatal error rather than a
2005   type coercion.
2007 | VerifyRetCallable<func,param>, ND, S(Cell), NF
2009   Verify a return type hint.
2011 | VerifyRetCls<func,param,tc>, ND, S(Obj) S(Cls) S(Cls|Nullptr), NF
2013   Verify a return type hint for a class.
2015 | VerifyRetFail<func,param,tc>, DVerifyParamFail, S(Cell) S(Cls|Nullptr), NF
2017   Failure to verify a return type hint.
2019 | VerifyRetFailHard<func,param,tc>, ND, S(Cell) S(Cls|Nullptr), T
2021   Terminal version of VerifyRetFail, to be used when the compiler can prove
2022   that this failure will result in a fatal error.
2024 | VerifyPropCls, ND, S(Cls) S(Int) S(Cls|Nullptr) S(Obj) C(Bool), NF
2026   Verify a property type hint with AnnotType::Object against an object
2027   value. S0 is the class of the object containing the property. S1 is the slot
2028   of the property on the class. S3 is the object which is being set in the
2029   property. If S2 is not nullptr, than the type-hint refers to that Class, and
2030   S3 will be checked to see if its an instance of S2. Otherwise, the type-hint
2031   refers to a type-alias, and the alias will be resolved and checked against
2032   S3. S4 is true if this is a static property, false otherwise.
2034 | VerifyPropFail, ND, S(Cls) S(Int) S(Cell) C(Bool), NF
2036   Failure to verify a property type hint. S0 is the class of the object
2037   containing the property. S1 is the slot of the property on the class. S2 is
2038   the value which was being set in the property. S3 is true if this is a static
2039   property, false otherwise.
2041 | VerifyPropFailHard, ND, S(Cls) S(Int) S(Cell) C(Bool), T
2043   Terminal version of VerifyPropFail, to be used when the compiler can prove
2044   that this failure will result in a fatal error.
2046 | VerifyProp, ND, S(Cls) S(Int) S(Cell) C(Bool), NF
2048   Verify that S2 is compatible with the type hint for the property at slot S1
2049   on S0. S3 is true if this is a static property, false otherwise.
2051 | VerifyPropAll, ND, S(Cls) S(Int) S(Cell) C(Bool), NF
2053   Verify that S2 is compatible with the all type hints for the property at slot
2054   S1 on S0 including upper-bounds. S3 is true if this is a static property,
2055   false otherwise.
2057 | VerifyPropCoerce, D(InitCell), S(Cls) S(Int) S(Cell) C(Bool), PRc|CRc
2059   Verify that S2 is compatible with the type hint for the property at slot S1
2060   on S0. S3 is true if this is a static property, false otherwise. Once support
2061   for coercing class_meth types is removed this ir instruction can also be
2062   removed (T61738946).
2064 | VerifyPropCoerceAll, D(InitCell), S(Cls) S(Int) S(Cell) C(Bool), PRc|CRc
2066   Verify that S2 is compatible with all type hints for the property at slot S1
2067   on S0, including upper-bounds. S3 is true if this is a static property,
2068   false otherwise. Once support for coercing class_meth types is removed this
2069   ir instruction can also be removed (T61738946).
2071 | VerifyReifiedLocalType<func,paramId>, ND, S(Cell) S(Dict) S(Cls|Nullptr), LA
2073   Raises a catchable type hint error if the reified generics of function
2074   parameter id does not match the type structure given on S0.
2076 | VerifyReifiedReturnType<func>, ND, S(Cell) S(Dict) S(Cls|Nullptr), LA
2078   Raises a catchable type hint error if the reified generics of S0 does not
2079   match the type structure given on S1.
2081 | ThrowUninitLoc<localId>, ND, S(Str), T
2083   Throws an UndefinedVariableException on an uninitialized local variable.
2085 | ThrowUndefPropException, ND, S(Obj) CStr, T
2087   Throws an UndefinedPropertyException on an undefined property named S1 on the
2088   class of S0.
2090 | RaiseTooManyArg<func>, ND, S(Vec), CRc|LA
2092   Raise a too many argument warning because extra arguments stored in S0 were
2093   passed to function func.
2095 | RaiseError, ND, S(Str), T
2097   Raises a fatal error with the text in S0 as its message.
2099 | RaiseWarning, ND, S(Str), NF
2101   Raises a warning with the text in S0 as its message.
2103 | RaiseNotice, ND, S(Str), NF
2105   Raises a notice with the text in S0 as its message.
2107 | ThrowHasThisNeedStatic, ND, S(Func), T
2109   Throws a BadMethodCallException to indicate that func was called on an object
2110   but is a static method.
2112 | ThrowMissingArg<func,argc>, ND, NA, T
2114   Throws a RuntimeExceptionObject to indicate that only argc arguments were
2115   passed to function func.
2117 | ThrowMissingThis, ND, S(Func), T
2119   Throws a BadMethodCallException to indicate that an instance method was called
2120   with null $this.
2122 | ThrowCallReifiedFunctionWithoutGenerics, ND, S(Func), T
2124   Throws a BadMethodCallException to indicate that S0 was called without reified
2125   generics.
2127 | CheckInOutMismatch<numArgs, inoutArgs>, ND, S(Func), NF
2129 | ThrowInOutMismatch<numArgs, inoutArgs>, ND, S(Func), T
2131   Throw an exception if the inout-ness of passed arguments given by `inoutArgs'
2132   does not match the inout-ness of parameters of the callee S0. There must be
2133   a mismatch if ThrowInOutMismatch is used.
2135   These don't verify that if there are packed args they are not in a position
2136   that require inout. You will still need verify that when unpacking.
2138 | CheckReadonlyMismatch<numArgs, readonlyArgs>, ND, S(Func), NF
2140   Checks whether readonly-ness of the caller matches that of callees
2142 | ThrowReadonlyMismatch<numArgs, readonlyArgs>, ND, S(Func), T
2144   Throw an exception if the readonly-ness of passed arguments given by `readonlyArgs'
2145   does not match the readonly-ness of parameters of the callee S0. There must be
2146   a mismatch if ThrowReadonlyMismatch is used.
2148   These don't verify that packed args are not in a position that require
2149   readonly. You will still need verify that when unpacking.
2151 | RaiseForbiddenDynCall, ND, S(Func), NF
2153   Depending on the setting of `ForbidDynamicCallsToFunc`,
2154   `ForbidDynamicCallsToClsMeth` and `ForbidDynamicCallsToInstMeth` runtime
2155   options, either raise a warning or throw an exception indicating that the
2156   func specified in S0 was called dynamically (and should not be).
2158 | RaiseForbiddenDynConstruct, ND, S(Cls), NF
2160   Depending on the setting of the `ForbidDynamicConstructs` runtime option, either
2161   raise a warning or throw an exception indicating that the class specified in
2162   S0 was constructed dynamically (and should not be).
2164 | RaiseCoeffectsCallViolation<func>, ND, S(Int) S(Int), NF
2166   Depending on the setting of the `CoeffectEnforcementLevels` runtime option,
2167   either raise a warning or throw an exception indicating that the caller
2168   was violating coeffects enforcement when calling the callee
2169   specified by func. S0 is used to pass the coeffects provided by the caller.
2170   S1 is used to pass the required coeffects of the callee.
2172 | RaiseCoeffectsFunParamTypeViolation<paramIdx>, ND, S(Cell), NF
2174   Raises a warning to indicate a violation for the expected type for S0
2175   at position paramIdx for the coeffect rule FunParam.
2177 | RaiseCoeffectsFunParamCoeffectRulesViolation, ND, S(Func), NF
2179   Raises a warning to indicate a violation for the input S0 to coeffect rule
2180   FunParam uses polymorphic coeffect rules.
2182 | RaiseStrToClassNotice, ND, S(Str), NF
2184   Raise a notice if a string is implicitly converted to a class.
2186 | CheckClsMethFunc, ND, S(Func), NF
2188   Raises runtime errors if the func in S0 is not a callable static method.
2190 | CheckClsReifiedGenericMismatch<cls>, ND, S(Vec), LA
2192   Raises a runtime error unless whether each generic in S0 is reified or erased
2193   matches exactly to the expectations of the cls.
2195 | CheckFunReifiedGenericMismatch, ND, S(Func) S(Vec), LA
2197   Raises a runtime error unless whether each generic in S0 is reified or erased
2198   matches exactly to the expectations of the func.
2200 | IsFunReifiedGenericsMatched<func>, D(Bool), S(Int), NF
2202   Load the generics bitmap from prologue flags given by S0 and check whether the
2203   bitmap proves that the number of given generics and positions of reified vs
2204   erased generics matches the expectations of the callee `func' (which must use
2205   reified generics). If this opcode returned false, further checks implemented
2206   by CheckFunReifiedGenericMismatch are needed.
2208 | InitClsCns<className,constName>, DParam(InitCell), NA, NF
2210   Initialize the RDS entry for a constant for a class, invoking autoload if it
2211   is not defined. The initialized value is returned. This instruction may raise
2212   an undefined constant error if autoload cannot define the constant.
2214 | PrintStr,  ND, S(Str),  CRc
2216 | PrintInt,  ND, S(Int),  CRc
2218 | PrintBool, ND, S(Bool), CRc
2220   Print for various types.
2222 | ConcatIntStr, D(Str), S(Int) S(Str), PRc
2224   Concatenate S0 and S1 after converting S0 to String.
2226 | ConcatStrInt, D(Str), S(Str) S(Int), CRc|PRc
2228   Concatenate S0 and S1 after converting S1 to String.
2230 | ConcatStrStr, D(Str), S(Str) S(Str), CRc|PRc
2232   Concatenate S0 and S1.
2234 | ConcatStr3, D(Str), S(Str) S(Str) S(Str), CRc|PRc
2236   Concatenate S0, S1, and S2.
2238 | ConcatStr4, D(Str), S(Str) S(Str) S(Str) S(Str), CRc|PRc
2240   Concatenate S0, S1, S2, and S3.
2242 | AddNewElemKeyset, D(Keyset),    S(Keyset) S(InitCell), CRc|PRc
2244 | AddNewElemVec,    DModified(0), S(Vec) S(InitCell),    CRc|PRc
2246   Add S1 as a new element to the array/keyset/vec S0.  (Note: S1 must actually
2247   be a subtype of InitCell for array invariants, but we can't assert this yet
2248   in the IR because many eval stack slots are not entirely typed wrt initness
2249   right now.)
2251 | AKExistsDict, D(Bool), S(Dict) S(Int,Str), NF
2253   Has the effects of array_key_exists(S0, S1).
2255 | AKExistsKeyset, D(Bool), S(Keyset) S(Int,Str), NF
2257   Has the effects of array_key_exists(S0, S1).
2259 | AKExistsObj, D(Bool), S(Obj) S(Int,Str), NF
2261   Has the effects of array_key_exists(S0, S1) on an object S0. This does
2262   collection accesses.
2264 | GetMemoKey, DMemoKey, S(Cell), PRc
2266   Given a cell, produces a string or an int that can be used as a memoize cache
2267   key. Valid values for the input include all basic types, arrays and
2268   collections, and objects that implement IMemoizeParam. Any other type will
2269   cause GetMemoKey to throw. This op can only be used within functions marked
2270   as memoize wrappers.
2272 | GetMemoKeyScalar, DMemoKey, S(Uncounted,Str), PRc
2274   Identical to GetMemoKey but only accepts scalar types and cannot produce
2275   errors.
2277 | DictIdx<sizeHint>, DDictElem, S(Dict) S(Int,Str) S(Cell), NF
2279   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2280   S2 is returned. The optimization data `sizeHint` doesn't affect semantics.
2281   (`sizeHint` describes S0; it's one of {Default, SmallStatic}. Default is a
2282   hash lookup. For SmallStatic, we'll do a linear scan for static string keys.)
2284 | KeysetIdx, DKeysetElem, S(Keyset) S(Int,Str) S(Cell), NF
2286   Checks if S0 contains the key S1 and returns the result if found. Otherwise
2287   S2 is returned.
2289 | MethodExists, D(Bool), S(Cls) S(Str), NF
2291   Checks if the method named S1 exists on class S0.  S0 must be a normal class
2292   that is not abstract.
2294 | LdBindAddr<SrcKey,spOff>, D(TCA), NA, NF
2296   Creates a service request to bind the given target address. Returns a TCA
2297   pointing either to the service request (before the service request is
2298   satisfied) or to the native code for the given target address (once the
2299   service request is satisfied).
2301 | LdSSwitchDest<numCases, cases, defaultOffset, bcSPOff>, D(TCA), S(Str), NF
2303   Using the cases in the extra data, create a hash table for destination lookup.
2304   Then, lookup the destination for the switched value in the table and yield the
2305   default if not present.
2307 | InterpOne<T,spOff,bcOff,numPopped,numPushed>, ND,
2308 |                                               S(StkPtr) S(FramePtr),
2309 |                                               NF
2311   Call the interpreter implementation function for one opcode. S0 + `spOff' (in
2312   cells) and S1 are, respectively, the VM stack and frame pointers before this
2313   instruction. T is only present if the instruction pushes to the stack, in
2314   which case it is the type of the top stack element after the call. `bcOff' is
2315   the bytecode offset. `numPopped' is the number of stack cells consumed by the
2316   instruction, and `numPushed' is the number of stack cells produced by the
2317   instruction.
2319 | InterpOneCF<T,bcOff,numPopped,numPushed>, ND,
2320 |                                           S(StkPtr) S(FramePtr),
2321 |                                           T
2323   Similar to InterpOne, but for instructions that may modify vmpc. This is
2324   implemented as a tail call to a stub, so any exceptions thrown will be thrown
2325   in the context of the stub, not the InterpOneCF instruction.
2327 | OODeclExists<kind>, D(Bool), S(Str) S(Bool), NF
2329   Returns a bool indicating whether the class, interface, or trait named by S0
2330   exists. Invokes autoload if S1 is true.
2332 | SetOpTV<op>, ND, S(Lval) S(Cell), NF
2334   Performs S0 <op>= S1.
2336 | OutlineSetOp<op>, D(InitCell), S(Cell) S(Cell), NF
2338   Similar to SetOpTV, but does not write back the result to S0, instead it is
2339   returned as the dest.  This is useful to handle ops that may require a
2340   type check before writing the value back.
2342 | GetTime, D(Dbl), NA, NF
2344   Returns a double of the current time in seconds.
2346 | GetTimeNs, D(Int), C(Int), NF
2348   Returns the current time of the given clock id specified as clockid_t in
2349   nanoseconds as integer. This will call kernel's clock_gettime_ns() API. Note
2350   that this cannot be used for CLOCK_THREAD_CPUTIME_ID, as HHVM provides
2351   different semantics for that counter.
2353 | LdUnitPerRequestFilepath<handle>, D(StaticStr), NA, NF
2355   Returns the filepath currently bound to the current unit (stored in the given
2356   RDS handle). The RDS handle must be an initialized normal handle. Only valid
2357   when Eval.ReuseUnitsByHash is enabled.
2359 | DirFromFilepath, D(StaticStr), S(StaticStr), NF
2361   Given a string representing a filepath in S0, return only the directory
2362   portion of the path.
2364 14. Generators & Closures
2366 | LdClosureCls, DParam(Cls), S(Obj), NF
2368 | LdClosureThis, DParam(Obj), S(Obj), NF
2370   Load the context from the closure object S0 into D, assuming `func' is
2371   S0's closure Func.
2373 | StClosureArg<index>, ND, S(Obj) S(Cell), CRc
2375   Store one of the closure environment arguments (i.e. from the closure's use
2376   clause) from S1 into the closure object S0.
2378 | CreateGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2380   Create a Generator object and suspend the ActRec provided by S0 into its
2381   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2382   resume address to S2 and resume offset to S3.
2384 | CreateAGen, DAllocObj, S(FramePtr) C(Int) S(TCA,Nullptr) C(Int), PRc
2386   Create an AsyncGenerator object and suspend the ActRec provided by S0 into its
2387   embedded ActRec, allocating S1 slots for locals/iterators. Set the native
2388   resume address to S2 and resume offset to S3.
2390 | CreateAFWH, DAllocObj,
2391 |             S(FramePtr) C(Int) S(TCA,Nullptr) C(Int) S(Obj),
2392 |             CRc|PRc
2394   Create an AsyncFunctionWaitHandle object and suspend the ActRec provided by
2395   S0 into its embedded ActRec, allocating S1 slots for locals/iterators.  Set
2396   the native resume address to S2, resume offset to S3, and mark it blocked on
2397   non-finished child S4.
2399 | CreateAGWH, DAllocObj,
2400 |             S(FramePtr) S(TCA,Nullptr) C(Int) S(Obj),
2401 |             CRc|PRc
2403   Create an AsyncGeneratorWaitHandle object and link it to the AsyncGenerator
2404   associated with the ActRec provided by S0.  Set the native resume address
2405   to S1, resume offset to S2, and mark it blocked on non-finished child S3.
2407 | CreateAAWH<local,count>, DAllocObj, S(FramePtr) S(Int), PRc
2409   Create an AwaitAllWaitHandle and add the count elements from frame contiguous
2410   frame locals beginning at local and extending count locals. S1 denotes the
2411   total number of non-completed waithandles. All locals must be subclasses of
2412   WaitHandle.
2414 | CreateSSWH, DAllocObj, S(Cell), CRc|PRc
2416   Call c_StaticWaitHandle::CreateSucceeded.
2418 | AFWHPrepareChild, ND, S(FramePtr) S(Obj), NF
2420   Prepare unfinished WaitableWaitHandle object specified by S1 for getting
2421   awaited by an AsyncFunctionWaitHandle object specified by its ActRec
2422   provided by S0.
2424   Injects S1 into the currently running scheduler instance and performs
2425   cross-scheduler and intra-scheduler cycle detection. Throws if the
2426   dependency cannot be established.
2428 | AFWHPushTailFrame, ND, S(Obj) C(Int), B
2430   If S0 is eligible for the tail frame optimization and has any free tail
2431   frame ID slots, pushes S1 as a new tail frame ID. Otherwise, branches to B.
2432   This IR op assumes that S0 is an Awaitable in the blocked state.
2434   S0 is eligible for the optimization if it is an AsyncFunctionWaitHandle,
2435   if this site "owns" it (i.e. if it has a refcount of exactly 2 - this site
2436   and its child's back pointer), and if it has space in its tail-frames list.
2438 | StArResumeAddr<offset>, ND, S(FramePtr) S(TCA), NF
2440   Store the resume address S1 into the Resumable whose ActRec is given by S0,
2441   marking the offset to resume at as `offset'.
2443 | ContEnter<spOffset,callBCOffset>,
2444 |   DGenIter,
2445 |   S(StkPtr) S(FramePtr) S(FramePtr) S(TCA) S(Cell),
2446 |   CRc
2448   Enters a generator body. S0 + `spOffset' (in cells) is a pointer to the
2449   stack, S1 is the current frame pointer, S2 is the generator frame pointer
2450   embedded in the Generator object, S3 is the address to jump to, and S4 is
2451   the value that will be pushed onto the stack to send it to the output of
2452   the yield statement. The `callBCOffset' will be stored to the m_callOff
2453   field of the ActRec in the generator.
2455 | ContCheckNext, ND, S(Obj) C(Bool), B
2457   Check whether the generator S0 can be iterated. If the generator is already
2458   running or finished, or it was not started yet and the S1 check-started flag
2459   is set, the branch B is taken.
2461 | ContValid, D(Bool), S(Obj), NF
2463   Return true if a generator is not done, false otherwise.
2465 | ContArIncKey, ND, S(FramePtr), NF
2467   Special-case key update for generator, ActRec of which is S0, which
2468   increments the key of a generator if that generator's key is an Int.
2469   This will cause undefined behavior if the generator's key is not an Int.
2471 | ContArIncIdx, D(Int), S(FramePtr), NF
2473   Increment the internal index in the Generator in S0, and return the new index
2474   value.
2476 | ContArUpdateIdx, ND, S(FramePtr) S(Int), NF
2478   Updates the internal index of generator with S1 if necessary, i.e. if S1
2479   is larger than the index. S0 is the pointer to the embedded ActRec.
2481 | LdContActRec, D(FramePtr), S(Obj), NF
2483   Loads the Generator object's ActRec, given a pointer to the generator
2484   object in S0.
2486 | LdContResumeAddr, D(TCA|Nullptr), S(Obj), NF
2488   Load the resume addr from the Generator in S0.
2490 | StContArState<state>, ND, S(FramePtr), NF
2492   Change the state of the Generator object which has frame pointer S0.
2494 | LdContArValue, DParam(InitCell), S(FramePtr), PRc
2496   Loads 'value' from the Generator object ActRec of which is S0.
2498 | StContArValue, ND, S(FramePtr) S(InitCell), CRc
2500   Stores 'value' into the Generator object ActRec of which is S0. S1 is the
2501   new value.
2503 | LdContArKey, DParam(InitCell), S(FramePtr), PRc
2505   Loads 'key' from the Generator object ActRec of which is S0.
2507 | StContArKey, ND, S(FramePtr) S(InitCell), CRc
2509   Stores 'key' into the Generator object ActRec of which is S0. S1 is the
2510   new value.
2512 | AFWHBlockOn, ND, S(FramePtr) S(Obj), CRc
2514   Establish dependency between parent AsyncFunctionWaitHandle object, whose
2515   ActRec is given by S0, and child WaitableWaitHandle object referenced by S1.
2517 | LdWHState, D(Int), S(Obj), NF
2519   Loads the state of the WaitHandle in S0, which is a value from the wait
2520   handle states in ext_asio.h. This instruction has undefined behavior if S0 is
2521   not a WaitHandle.
2523 | LdWHResult, DParam(InitCell), S(Obj), NF
2525   Loads the result of the WaitHandle in S0. This instruction has undefined
2526   behavior if S0 is not a WaitHandle, or if S0 is not finished.
2528 | LdWHNotDone, D(Int), S(Obj), NF
2530   Returns 1 if S0 is not finished, and 0 if S0 is finished.
2532 | CountWHNotDone<local,count>, D(Int), S(FramePtr), B
2534   Returns the number of unfinished awaitables contained in the contiguous
2535   locals beginning at local and extending count, skipping all nulls. A branch
2536   is taken if a non-Awaitable non-null value is encountered.
2538 | LdAFWHActRec, D(FramePtr), S(Obj), NF
2540   Loads the AsyncFunctionWaitHandle object's ActRec, given a pointer to the
2541   AsyncFunctionWaitHandle object in S0.
2544 15. Debugging, instrumentation, and profiling
2546 | IncStat, ND, C(Int), NF
2548   Increment stat counter. S0 is the implementation defined stat counter index.
2550 | IncProfCounter<TransID>, ND, NA, NF
2552   Increment the profiling counter associated with translation TransID.
2554 | IncCallCounter, ND, S(FramePtr), NF
2556   Increment the counter associated associated with the last call, namely from
2557   the function containing the previous translation in the call stack into the
2558   current function.
2560 | DbgAssertRefCount<AssertReason>, ND, S(Cell), NF
2562   Assert that S0 has a valid refcount. If S0 has a reference counted type and
2563   its count is implausible then execute a hardware trap instruction.
2565 | DbgTraceCall<spOffset>, ND, S(FramePtr) S(StkPtr), NF
2567   When EvalHHIRGenerateAsserts is on, this instruction is inserted at the
2568   start of each region, to emit some sanity checking code.
2570 | DbgAssertFunc, ND, S(FramePtr), NF
2572   Assert that the func on the srckey is the current function in Frame S0.
2573   If the assertion fails, execution is aborted via a hardware exception.
2575 | DbgCheckLocalsDecRefd, ND, S(FramePtr), NF
2577   In debug builds, if LocalsDecRefd flag is set on S0, causes runtime failure by
2578   emitting a trap instruction. Otherwise, this instruction does nothing.
2580 | DbgTrashStk<offset>, ND, S(StkPtr), NF
2582   For debugging purposes.  Store kTVTrashJITStk to the stack slot pointed to
2583   by S0, at a given offset (in cells).
2585 | DbgTrashFrame<offset>, ND, S(StkPtr), NF
2587   For debugging purposes.  Store kTVTrashJITFrame to kNumActRecCells stack
2588   slots starting at the offset (in cells), and going toward higher memory
2589   addresses.
2591 | DbgTrashMem, ND, S(Mem), NF
2593   For debugging purposes.  Store kTVTrashJITHeap to a heap slot pointed to by
2594   S0.
2596 | RBTraceEntry, ND, NA, NF
2598 | RBTraceMsg, ND, NA, NF
2600   Ring buffer tracing.
2602 | ZeroErrorLevel, D(Int), NA, NF
2604 | RestoreErrorLevel, ND, S(Int), NF
2606   Helper instructions for fast implementation of the PHP error silencing
2607   operator (@foo()).
2610 16. Iterators
2612 | IterInit<IterData>,   D(Bool), S(ArrLike,Obj) S(FramePtr), CRc|LA
2614 | IterInitK<IterData>,  D(Bool), S(ArrLike,Obj) S(FramePtr), CRc|LA
2616 | LIterInit<IterData>,  D(Bool), S(ArrLike) S(FramePtr),     LA
2618 | LIterInitK<IterData>, D(Bool), S(ArrLike) S(FramePtr),     LA
2620   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2621   the index of the iterator variable, keyId and valId are indices of local
2622   variables.
2624   Initializes the iterator variable whose index is given by iterId.
2625   This instruction creates the appropriate iterator for the array or object that
2626   S0 references, and rewinds the new iterator to its start. S0 points to the
2627   stack frame containing the iterator and local variables with the indices
2628   iterId, keyId and valId.
2630   If the new iterator is at its end (i.e., has no elements to iterate over),
2631   this instruction decrements the refcount of S0 and returns false; otheriwse,
2632   it stores a reference to S0 in the new iterator and returns true. If the
2633   iterator is not at its end, then this instruction stores the iterator's first
2634   value (and key) into the local variable with index valId (and keyId,
2635   respectively).
2637   The LIter variations only accept arrays and do not take ownership of their
2638   base. Instead, the base is provided on each operation on the iterator, so
2639   that we can avoid inc-ref-ing the base (in cases where that's safe).
2641   This instruction has the ConsumesRC property because it either decrements the
2642   reference count of S0 or stores a reference to S0 into the new iterator.
2644 | IterNext<IterData>,   D(Bool), S(FramePtr), NF
2646 | IterNextK<IterData>,  D(Bool), S(FramePtr), NF
2648 | LIterNext<IterData>,  D(Bool), S(ArrLike) S(FramePtr), LA
2650 | LIterNextK<IterData>, D(Bool), S(ArrLike) S(FramePtr), LA
2652   <IterData> consists of three indices, iterId, keyId and valId. iterId is
2653   the index of the iterator variable, keyId and valId are indices of local
2654   variables.  S0 points to the stack frame containing the iterator and local
2655   variables with the indices iterId, keyId and valId.
2657   Advances the iterator variable whose index is given by iterId.
2659   If the iterator has reached the end, this instruction frees the iterator
2660   variable and returns false; otherwise, it returns true. If the iterator has
2661   not reached its end, then this instruction stores the iterator's next value
2662   (and key) into the local variable with index valId (and keyId, respectively).
2664 | IterFree<iterId>, ND, S(FramePtr), NF
2666   Free the iterator variable with id `iterId` in the stack frame of S0.
2667   For non-local iterators, this instruction will dec-ref the stored base.
2669 | KillActRec, ND, S(FramePtr), NF
2671 | KillLoc<localId>, ND, S(FramePtr), NF
2673 | KillIter<iterId>, ND, S(FramePtr), NF
2675   Mark a given ActRec, local, or iterator as being dead for the purposes of
2676   memory effects. It no longer contains a meaningful value.
2678   These operations are used for both correctness and performance. Inserting a
2679   kill can help us do store-elimination; if a write is followed by a kill on
2680   all paths before any reads, then it can be eliminated. However, we also use
2681   kills to mark when a given location cannot be reused by load-elimination or
2682   similar optimizations, in which case, the kill ops are required.
2684   In debug builds, these ops will write poison values to these fields.
2686 | GetDictPtrIter, D(PtrToElem), S(Dict) S(Int), NF
2688 | GetVecPtrIter, D(PtrToElem), S(Vec) S(Int), NF
2690   Returns a pointer to the elm S1 of a vanilla dict or vec S0. S1 does not need
2691   to be a valid array position; for example, it may equal the size of the array
2692   (so that the "elm" returned is the pointer-iteration end for S0).
2694 | AdvanceDictPtrIter<offset>, D(PtrToElem), S(PtrToElem), NF
2696 | AdvanceVecPtrIter<offset>, D(PtrToElem), S(PtrToElem), NF
2698   Increments the pointer S0 to the array element with the given layout `offset`
2699   positions forward. `offset` is allowed to be negative.
2701 | LdPtrIterKey<T>, DParam(Int|Str), S(PtrToElem), NF
2703 | LdPtrIterVal<T>, DParam(InitCell), S(PtrToElem), NF
2705   Loads the key or val from the array element pointed to by S0. S0 must be a
2706   valid elm; that is, it can't point to the end of the array data. LdPtrIterKey
2707   can only be used for mixed elms, but LdPtrIterVal supports mixed and packed.
2709   T is used to type the result. For LdPtrIterKey, it must be a valid type for
2710   the array's keys - i.e., a subtype of TInt|TStr.
2712 | EqPtrIter, D(Bool), S(PtrToElem) S(PtrToElem), NF
2714   Compares two pointer iterators for equality.
2717 17. Member instruction support
2719 | LdMIStateTempBaseAddr, D(PtrToMISTemp), NA, NF
2721   Returns a pointer to the tvTempBase field within the current MInstrState.
2723 | LdMBase, DParam(Lval), NA, NF
2725   Load the current value of the member base register.
2727 | StMBase, ND, S(Lval), NF
2729   Store a new value to the member base register. It is illegal for any
2730   instruction other than StMBase or InterpOne (when interpreting a member
2731   instruction) to modify the member base register.
2733 | CheckMROProp, ND, NA, B
2735   If the roProp field of MInstrState is false, branch.
2737 | StMROProp, ND, S(Bool), NF
2739   Set the roProp field of MInstrState to S0.
2741 | FinishMemberOp, ND, NA, NF
2743   Mark the end of a member operation. This has no effect at runtime but exists
2744   to provide information for certain optimizations.
2746 All of the remaining opcodes in this section are simple wrappers around helper
2747 functions (specified in S0) to perform the corresponding vector operation. If
2748 S1 is a ConstCls it represents the context class for the operation.
2750 SetElem, SetProp, and SetNewElem are used to implement part of the SetM hhbc
2751 opcode, which almost always pushes its first stack input or a StaticStr as its
2752 stack result. The combinations of input types that cause SetM to push anything
2753 other than those two values are vanishingly rare in correct PHP programs, so
2754 these three instructions have been optimized for the common cases. SetNewElem
2755 and SetProp have no destination, allowing the compiler to predict that the
2756 SetM's output will be the same as its input (and optimize accordingly). If that
2757 turns out to not be the case at runtime, the instruction will throw an
2758 InvalidSetMException. The exception will hold a Cell containing the value the
2759 SetM should push on the stack instead of its input value. The runtime is
2760 responsible for catching this exception, finishing execution of the SetM
2761 instruction, pushing the value from the exception on the stack, and proceeding
2762 as appropriate (most likely with a side exit to the next bytecode instruction,
2763 since it has pushed an unexpected type onto the stack).
2765 SetElem is similar to SetProp and SetNewElem but can also be used for setting
2766 characters within strings. When given a string base and a valid offset, SetElem
2767 returns a string representation of the newly inserted character. In all other
2768 cases it returns nullptr or throws an InvalidSetMException. It will throw this
2769 exception when it detects invalid input types, or when trying to set a string
2770 offset that would grow the string beyond the maximum supported size.
2772 The input types that will cause the errors described above are listed here:
2774 SetNewElem will fail if the base is not a subtype of {Null|Str|Arr|Obj} and not
2775            Bool<false>.
2776 SetElem has the same base constraint as SetNewElem. In addition, the key must
2777         not be a subtype of {Arr|Obj}.
2778 SetProp will fail if the base is not a subtype of {Obj|Null}.
2780 Any instructions that take a pointer to an MInstrState struct use the various
2781 fields of that struct for holding intermediate values.
2783 | BaseG, D(LvalToGbl|LvalToConst), S(Str), NF
2785   Get a base from global named S0. If it is not a defining BaseG it can also
2786   return the init_null_variant
2788 | PropX, DPropLval, S(Cell) S(Cell) S(PtrToMISTemp|Nullptr), NF
2790   Lookup intermediate property in S0, with key S1. An exception is thrown if
2791   the property is Readonly when it was required to be Mutable.
2793 | PropQ, DPropLval, S(Cell) S(StaticStr) S(PtrToMISTemp|Nullptr), NF
2795   A nullsafe version of PropX, returns null if the base S0 is null. An exception
2796   is thrown if the property is Readonly when it was required to be Mutable.
2798 | PropDX, DPropLval, S(Cell) S(Cell) S(PtrToMISTemp|Nullptr), NF
2800   Like PropX, but used for intermediate element lookups that may modify the
2801   base. An exception is thrown if the property is Readonly when it was
2802   required to be Mutable.
2804 | CGetProp, D(InitCell), S(Cell) S(Cell), PRc
2806   Get property with key S1 from S0.
2808 | CGetPropQ, D(InitCell), S(Cell) S(StaticStr), PRc
2810   A nullsafe version of CGetProp, returns null if the base S0 is null.
2812 | SetProp, ND, S(Cell) S(Cell) S(Cell), NF
2814   Set property with key S1 in S0 to S2.
2816 | UnsetProp, ND, S(Cell) S(Cell), NF
2818   Unset an object property.
2820 | SetOpProp<op>, D(InitCell), S(Cell) S(Cell) S(Cell), PRc
2822   Set op propery with key S1 in base S0, using S2 as the right hand side.
2824 | IncDecProp<op>, D(InitCell), S(Cell) S(Cell), PRc
2826   Increment/decrement property with key S1 in base S0.
2828 | IssetProp, D(Bool), S(Cell) S(Cell), NF
2830   Returns true iff the property with key S1 in base S0 is set.
2832 | ElemX, D(InitCell), S(Cell) S(Cell), NF
2834   Get intermediate element with key S1 from base S0. The base will not be
2835   modified and the result will not be inc-ref-ed.
2837 | CheckDictKeys<T>, ND, S(Dict), B
2839   Check that the given mixed array is free of tombstones and that all of its
2840   elements' keys match the type T. If any check fails, branch to block B.
2841   Like CheckMixedArrayOffset, this check is allowed to have false negatives -
2842   it may fail even if the array has keys of the given type.
2844 | CheckArrayCOW, DCOW, S(ArrLike), B|PRc|CRc|LP
2846   Check that S0 has a refcount of exactly 1; if not, branch to B.
2848 | CopyArray, DCOW, S(ArrLike), PRc|LP
2850   Make a copy of S0 (regardless of its refcount). The resultant copy will
2851   always be counted with a ref-count of 1. The array must be of a kind that
2852   allows for counted variants.
2854 | ProfileDictAccess, ND, S(Dict) S(Int,Str), NF
2856   Profile access of the element keyed by S1 in S0, tracking sizes and offsets.
2858 | CheckDictOffset<pos>, ND, S(Dict) S(Int,Str), B
2860   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2861   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2862   fail, branch to B.  This check is allowed to have false negatives.
2864 | ProfileKeysetAccess, ND, S(Keyset) S(Int,Str), NF
2866   Profile access of the element keyed by S1 in S0, tracking sizes and offsets.
2868 | CheckKeysetOffset<pos>, ND, S(Keyset) S(Int,Str), B
2870   Check that `pos' is within the usage bounds of S0 (including tombstones), and
2871   that S1 exactly matches the element key of S0 at `pos'.  If any of the checks
2872   fail, branch to B.  This check is allowed to have false negatives.
2874 | ProfileArrayCOW, ND, S(ArrLike), LA
2876   Profile whether S0 would require a COW before being mutated.
2878 | CheckMissingKeyInArrLike, ND, S(ArrLike) S(StaticStr), B
2880   Uses the StrKeyTable to check if S1 is guaranteed to be missing in S0.
2881   If S1 may be present, branches to block B. If we branch here, the key may or
2882   may not be present.
2884 | ElemDictD, DElemLval, S(Lval) S(Int,Str), NF
2886 | ElemDictU, DElemLval, S(Lval) S(Int,Str), NF
2888   Similar to ElemDX and ElemUX, but specialized for when the base S0 is a
2889   dict and the key S1 is an int/str.
2891 | ElemDictK, DElemLvalPos, S(Dict) S(Int,Str) S(Int) S(Dict), NF
2893   Returns an lval to the element of dict S0 at the known position S2
2894   (corresponding to the key S1).  S3 is S0 with a potentially more refined type
2895   and used to calculate the elem type. It is not used at runtime.
2897 | ElemDX, D(LvalToElemOrConst), S(Lval) S(Cell), NF
2899   Like ElemX, but used for intermediate element lookups that may modify the
2900   base.
2902 | ElemUX, D(LvalToElemOrConst), S(Lval) S(Cell), NF
2904   Like ElemX, but used for intermediate element lookups that may modify the
2905   base as part of an unset operation.
2907 | DictGet, DDictElem, S(Dict) S(Int,Str), NF
2909   Get element with key S1 from base S0, throwing if the element is not present.
2911 | DictGetQuiet, DDictElem, S(Dict) S(Int,Str), NF
2913   Get element with key S1 from base S0, returning null if the element is not
2914   present.
2916 | DictGetK, DDictElem, S(Dict) S(Int,Str) S(Int), NF
2918   Like DictGet, but the element for S1 is at a known position S2 in S0.
2920 | KeysetGet, DKeysetElem, S(Keyset) S(Int,Str), NF
2922   Get element with key S1 from base S0, throwing if the element is not present.
2924 | KeysetGetQuiet, DKeysetElem, S(Keyset) S(Int,Str), NF
2926   Get element with key S1 from base S0, returning null if the element is not
2927   present.
2929 | KeysetGetK, DKeysetElem, S(Keyset) S(Int,Str) S(Int), NF
2931   Like KeysetGet, but the element for S1 is at a known position S2 in S0.
2933 | StringGet, D(StaticStr), S(Str) S(Int), PRc
2935   Get string representing character at position S1 from base string S0.  Raises
2936   a notice if the position is out of bounds.
2938 | MapGet, D(InitCell), S(Obj) S(Int,Str), PRc
2940   Get element with key S1 from base S0.
2942 | CGetElem, D(InitCell), S(Cell) S(Cell), PRc
2944   Get element with key S1 from S0.
2946 | MemoGetStaticValue<func,T>, DParam(InitCell), NA, B
2948   Get the memo value associated with the static function "func". If the value
2949   is not present, branch. The returned value is not inc-reffed. This op can
2950   only be used inside a memoize wrapper.
2952 | MemoGetStaticCache<func,keys,T>, DParam(InitCell), S(FramePtr), B
2954   Perform a lookup on the memo cache associated with the static function
2955   "func". The keys for the lookup are read from the locals on the frame pointed
2956   to by S0 (which must be ints or strings). If the lookup fails, branch. The
2957   returned value is not inc-reffed. This op can only be used inside a memoize
2958   wrapper.
2960 | MemoGetLSBValue<func,T>, DParam(InitCell), S(Cls), B
2962   Get the memo value associated with the static function "func" and late static
2963   bound class S0. If the value is not present, branch. The returned value is not
2964   inc-reffed. This op can only be used inside a memoize wrapper.
2966 | MemoGetLSBCache<func,keys,T>, DParam(InitCell), S(FramePtr) S(Cls), B
2968   Perform a lookup on the memo cache associated with the static function
2969   "func" and late static bound class S1. The keys for the lookup are read from
2970   the locals on the frame pointed to by S0 (which must be ints or strings). If
2971   the lookup fails, branch. The returned value is not inc-reffed. This op can
2972   only be used inside a memoize wrapper.
2974 | MemoGetInstanceValue<slot,func,T>, DParam(InitCell), S(Obj), B
2976   Get the memo value at the specified memo slot on S0. If the value is not
2977   present, branch. The returned value is not inc-reffed. This op can only be
2978   used inside a memoize wrapper.
2980 | MemoGetInstanceCache<func,keys,T>, DParam(InitCell), S(FramePtr) S(Obj), B
2982   Perform a lookup on the memo cache at the specified memo slot on S1. The keys
2983   for the lookup are read from the locals on the frame pointed to by S0 (which
2984   must be ints or strings). If the lookup fails, branch. The returned value is
2985   not inc-reffed. This op can only be used inside a memoize wrapper.
2987 | MemoSetStaticValue<func>, ND, S(InitCell), NF
2989   Set S0 as the memo value associated with the static function "func". Store
2990   the value, overwriting any previous value, with appropriate ref-count
2991   manipulations. This op can only be used inside a memoize wrapper.
2993 | MemoSetStaticCache<func,keys>, ND, S(FramePtr) S(InitCell), NF
2995   Store S1 in the memo cache associated with the static function "func". The
2996   keys for the lookup are read from the locals on the frame pointed to be S0
2997   (which must be ints or strings). Store the value, overwriting any previous
2998   value, with appropriate ref-count manipulations. This op can only be used
2999   inside a memoize wrapper.
3001 | MemoSetLSBValue<func>, ND, S(InitCell) S(Cls), NF
3003   Set S0 as the memo value associated with the static function "func" and
3004   late static bound class S1. Store the value, overwriting any previous
3005   value, with appropriate ref-count manipulations. This op can only be used
3006   inside a memoize wrapper.
3008 | MemoSetLSBCache<func,keys>, ND, S(FramePtr) S(Cls) S(InitCell), NF
3010   Store S2 in the memo cache associated with the static function "func" and
3011   late static bound class S1. The keys for the lookup are read from the
3012   locals on the frame pointed to be S0 (which must be ints or strings).
3013   Store the value, overwriting any previous value, with appropriate
3014   ref-count manipulations. This op can only be used inside a memoize wrapper.
3016 | MemoSetInstanceValue<slot,func>, ND, S(Obj) S(InitCell), NF
3018   Set S2 as the memo value at the specified memo slot on S1. Store the value,
3019   overwriting any previous value, with appropriate ref-count
3020   manipulations. This op can only be used inside a memoize wrapper.
3022 | MemoSetInstanceCache<slot,func,keys>, ND, S(FramePtr) S(Obj) S(InitCell), NF
3024   Store S2 in the memo cache at the specified memo slot on S1. Store the value,
3025   overwriting any previous value, with appropriate ref-count
3026   manipulations. This op can only be used inside a memoize wrapper.
3028 | InitObjMemoSlots<class>, ND, S(Obj), NF
3030   Initialize the memoization instance slots for object S0 of the given class.
3032 | DictSet, DArrLikeSet, S(Dict) S(Int,Str) S(InitCell), PRc|CRc
3034   Set element with key S1 in S0 to S2. The dest will be a new Dict that should
3035   replace S0.
3037 | BespokeGet, DBespokeElemUninit, S(Vec,Dict,Keyset) S(Int,Str), LA
3039   Get element with key S1 in the array S0, which may have an arbitrary layout.
3040   This op returns TUninit if the key is not in the array.
3042 | BespokeGetThrow, DBespokeElem, S(Vec,Dict,Keyset) S(Int,Str), LA
3044   Get element with key S1 in the array S0, which may have an arbitrary layout.
3045   This op throws if the key is not in the array.
3047 | BespokeElem, DElemLval, S(Lval) S(Int,Str) C(Bool), LA
3049   Get a half-lval to an element of type T with key S1 in the array S0, which
3050   may have an arbitrary layout. The op will copy or escalate the S0 as needed,
3051   with ElemInt/ElemStr semantics.
3053   If the key is missing in the array, we'll use S2 to determine what to do.
3054   If S2 is true, we'll throw; else, we'll return an immutable lval to null.
3056 | BespokeSet, DArrLikeSet, S(Vec,Dict,Keyset) S(Int,Str) S(InitCell), LA|PRc|CRc
3058   Set element with key S1 in the array S0, which may have an arbitrary layout.
3059   This op has SetMove semantics; it consumes a refcount on the input array and
3060   produces one on the output, and does no refcounting to the value S2.
3062 | BespokeUnset, DArrLikeUnset, S(Vec,Dict,Keyset) S(Int,Str), LA|PRc|CRc
3064   Unset element with key S1 in the array S0, which may have an arbitrary layout.
3066 | BespokeAppend, DArrLikeAppend, S(Vec,Dict,Keyset) S(InitCell), LA|PRc|CRc
3068   Set element with key S1 in the array S0, which may have an arbitrary layout.
3069   This op has AppendMove semantics; it consumes a refcount on the input array
3070   and produces one on the output, and does no refcounting to the value S2.
3072 | BespokeIterFirstPos, D(Int), S(ArrLike), LA
3074   Obtain the pos coresponding to the first valid element in the non-empty
3075   array S0, which may have an arbitrary layout.
3077 | BespokeIterLastPos, D(Int), S(ArrLike), LA
3079   Obtain the pos coresponding to the last valid element in the non-empty
3080   array S0, which may have an arbitrary layout.
3082 | BespokeIterEnd, D(Int), S(ArrLike), LA
3084   Returns the "end" iterator position for the given array. Unlike the "last"
3085   iterator position, the end is never a valid iterator position.
3087 | BespokeIterGetKey, DBespokePosKey, S(ArrLike) S(Int), LA
3089   Obtain the key at the valid pos S1 in the array S0.
3091 | BespokeIterGetVal, DBespokePosVal, S(ArrLike) S(Int), LA
3093   Obtain the value at the valid pos S1 in the array S0.
3095 | BespokeEscalateToVanilla<Layout>, DEscalateToVanilla, SBespokeArr CStr, PRc
3097   Escalate the bespoke array S0 to a vanilla array for the reason S1.
3099 | LdMonotypeDictTombstones, D(Int), SMonotypeDict, NF
3101   Returns the number of tombstones in the given MonotypeDict's value array.
3102   The MonotypeDict's IterEnd is equal to its size plus its tombstone count.
3104 | LdMonotypeDictKey, DBespokePosKey, SMonotypeDict S(Int), NF
3106 | LdMonotypeDictVal, DBespokePosVal, SMonotypeDict S(Int), NF
3108   Specializations of BespokeIterGetKey and BespokeIterGetVal for when the base
3109   is a monotype dict. The GetKey and GetVal ops require that S1 is a valid
3110   iterator position for S0.
3112 | LdMonotypeVecElem, DBespokeElem, SMonotypeVec S(Int), NF
3114   Loads the element of the monotype vec in S0 at offset S1. This instruction
3115   assumes that the vec actually contains an element at that offset (i.e. the
3116   index is within bounds).
3118 | StructDictUnset, DArrLikeUnset, SStructDict C(StaticStr), PRc|CRc
3120   Unset element with key S1 in the struct-layout dict S0. This op has move
3121   semantics: it consumes a refcount on S0 and produces one on the output.
3123 | StructDictSlot, D(Int), SStructDict S(Str), B
3125   Calculate the slot corresponding to key S1 in struct dict S0, branching if
3126   that key is not present.
3128 | StructDictElemAddr, D(LvalToElem), SStructDict S(Str) S(Int) SStructDict, NF
3130   Calculate the pointer to the value in struct dict S0 corresponding to slot
3131   S2. S1 is the corresponding key used to calculate the slot, and S3 is the
3132   struct dict to use for type calculations (if the struct dict has been COWed,
3133   this will correspond to the pre-COW version). S1 and S3 are only used for
3134   type calculations and not used at runtime.
3136 | StructDictAddNextSlot, ND, SStructDict S(Int), NF
3138   Mark the slot S1 as being used in struct dict S0. The slot must not have been
3139   previously in use (its corresponding value must have been Uninit).
3141 | StructDictTypeBoundCheck, DStructTypeBound, S(InitCell) SStructDict S(Int), B|P
3143   Check if S0 passes the type bound associated with slot S2 in struct dict
3144   S1. If not, branch. The returned value is a passthrough of S0, possibly
3145   refined with what we know statically of the type-bound. This is like a
3146   CheckType, but the type isn't known statically.
3148 | MapSet, ND, S(Obj) S(Int,Str) S(InitCell), CRc
3150   Set element with key S1 in S0 to S2.
3152 | VectorSet, ND, S(Obj) S(Int,Str) S(InitCell), CRc
3154   Set element with key S1 in S0 to S2.
3156 | SetElem<T>, DSetElem, S(Lval) S(Cell) S(InitCell), NF
3158   Set element with key S1 in S0 to S2. SetElem returns a Nullptr in the common
3159   case, where the logical result of the hhbc SetM is its right hand side. In
3160   the case of string bases, the SetM returns a new string containing the newly
3161   inserted character. So the return value of this instruction is Nullptr unless
3162   SetM needed to return a static string. The type param is the known type of
3163   the base that S0 points to.
3165   Furthermore, in the case of "invalid offsets", SetElem may throw an
3166   InvalidSetMException (see discussion above).
3168 | SetRange, ND, S(Lval) S(Int) S(Cell) S(Int) S(Int), NF
3170 | SetRangeRev, ND, S(Lval) S(Int) S(Cell) S(Int) S(Int), NF
3172   Perform a range set or reverse range set operation, with the same arguments
3173   and semantics as the RangeSet bytecode instruction.
3175 | UnsetElem, ND, S(Lval) S(Cell), NF
3177   Unsets the element at key S1 in the base S0.
3179 | SetOpElem<op>, D(InitCell), S(Lval) S(Cell) S(Cell), PRc
3181   Set op elem with key S1 in base S0, using S2 as the right hand side.
3183 | IncDecElem, D(InitCell), S(Lval) S(Cell), PRc
3185   Increment/decrement element with key S1 in base S0.
3187 | SetNewElem, ND, S(Lval) S(InitCell), NF
3189   Append the value in S1 to S0.
3191 | SetNewElemDict,   ND, S(Lval) S(InitCell), NF
3193 | SetNewElemVec,    ND, S(Lval) S(InitCell), NF
3195 | SetNewElemKeyset, ND, S(Lval) S(Int,Str), NF
3197   Specializations of SetNewElem for pointers to dicts, vecs, and keysets.
3199 | DictIsset, D(Bool), S(Dict) S(Int,Str), NF
3201   Returns true iff the element at key S1 in the base S0 is set.
3203 | KeysetIsset, D(Bool), S(Keyset) S(Int,Str), NF
3205   Returns true iff the element at key S1 in the base S0 is set.
3207 | StringIsset, D(Bool), S(Str) S(Int), NF
3209   Returns true iff the string S0 has a character at position S1.
3211 | VectorIsset, D(Bool), S(Obj) S(Int), NF
3213   Returns true iff the element at key S1 in the base S0 is set.
3215 | PairIsset, D(Bool), S(Obj) S(Int), NF
3217   Returns true iff the element at key S1 in the base S0 is set.
3219 | MapIsset, D(Bool), S(Obj) S(Int,Str), NF
3221   Returns true iff the element at key S1 in the base S0 is set.
3223 | IssetElem, D(Bool), S(Cell) S(Cell), NF
3225   Returns true iff the element at key S1 in S0 is set.
3227 | CheckRange, D(Bool), S(Int) S(Int), NF
3229   Returns true iff S0 is in the range [0, S1).
3231 | ThrowArrayIndexException, ND, S(ArrLike) S(Int), T
3233   Throws an OutOfBoundsException if S0 is an undefined index for an array.
3235 | ThrowArrayKeyException, ND, S(Dict) S(Str), T|LA
3237   Throws an OutOfBoundsException if S0 is an undefined key for a darray or dict.
3239 | ThrowOutOfBounds, ND, S(ArrLike|Obj) S(Cell), T|LA
3241   Throws an OutOfBoundsException corresponding to an access of S0 with the key
3242   S1.
3244 | ThrowInvalidArrayKey, ND, S(ArrLike) S(Cell), T|LA
3246   Throws an InvalidArgumentException corresponding to an access of S0 with the
3247   key S1, which has a type invalid for that array.
3249 | ThrowInvalidOperation, ND, S(Str), T
3251   Throws an InvalidOperationException with a message indicating S0.
3253 | ThrowDivisionByZeroException, ND, NA, T
3255   Throws a DivisionByZeroException.
3257 | ThrowLateInitPropError, ND, S(Cls) S(Str) S(Bool), T
3259   Throws an InvalidOperationException indicating an access of a unset LateInit
3260   property. S0 is the class the property was declared on. S1 is the property
3261   name. S2 is true if its a static property, false otherwise.
3263 | ThrowParameterWrongType<expectedType, func, argNum>, ND, S(Cell), T
3265   Throws a RuntimeException if calling a function with an argument that has the
3266   wrong type
3268 | ThrowMustBeMutableException<cls>, ND, S(Str), T
3270   Throws an InvalidOperationException indicating a readonly semantics violation
3271   where the property was required to be mutable. cls is the class the property
3272   was declared on. S0 is the property name.
3274 | ThrowMustBeReadonlyException<cls>, ND, S(Str), T
3276   Throws an InvalidOperationException indicating a readonly semantics violation
3277   where the property was required to be readonly. cls is the class the property
3278   was declared on. S0 is the property name.
3280 | ThrowLocalMustBeValueTypeException, ND, S(Str), T
3282   Throws an InvalidOperationException indicating a readonly semantics violation
3283   where the local was required to be a value type. S0 is the local name.
3285 | ThrowMustBeValueTypeException<cls>, ND, S(Str), T
3287   Throws an InvalidOperationException indicating a readonly semantics violation
3288   where the property was required to be a value type. S0 is the property
3289   name. cls is the class the property was declared on.
3291 | ThrowMustBeEnclosedInReadonly<cls>, ND, S(Str), T
3293   Throws an InvalidOperationException indicating a readonly semantics violation
3294   where the property was required to be enclosed in a readonly expression. cls
3295   is the class the property was declared on. S0 is the property name.
3297 | ThrowCannotModifyReadonlyCollection, ND, NA, T
3299   Throws an InvalidOperationException indicating a readonly semantics violation
3300   where a collection is modified.
3302 | ProfileType, ND, S(Cell), NF
3304   Profile the type of S0.
3306 | ProfileCall<rdsHandle>, ND, S(Func), NF
3308   Profile the call to a function S0.
3310 | ProfileMethod<rdsHandle>, ND, S(Cls) S(Func), NF
3312   Profile the method S1 called with class context S0.
3314 | ProfileProp, ND, C(StaticStr) C(StaticStr), NF
3316   Profile the access to property S(1) with base class S(0).
3318 | CheckVecBounds, ND, S(Vec) S(Int), B|LA
3320   Checks that the index in S1 is within the bounds of the packed array or
3321   vector array in S0. Branches to B if the index is out of bounds.
3323 | LdVecElemAddr, DElemLvalPos, S(Vec) S(Int) S(Vec), NF
3325   Loads the address of the element at index S1 of the vec array in S0. This
3326   instruction assumes the array actually contains an element at that offset
3327   (IE, the array has the proper length). S2 is S0 with a potentially more
3328   refined type and used to calculate the elem type. It is not used at runtime.
3330 | ReserveVecNewElem, D(Int), S(CountedVec), B
3332   If there is room in the packed or vec array (which is assumed to be mutable),
3333   increments the array size and returns the index of the new last element
3334   (which you must initialize); else jumps to the taken branch.
3336 | LdVecElem, DVecElem, S(Vec) S(Int), NF
3338   Loads the element of the vec array in S0 at offset S1. This instruction
3339   assumes that the vec actually contains an element at that offset (IE, the vec
3340   has the proper length).
3342 | LdVectorSize, D(Int), S(Obj), NF
3344   Returns the size of the given Vector collection in S0.
3346 | ColIsEmpty, D(Bool), S(Obj), NF
3348 | ColIsNEmpty, D(Bool), S(Obj), NF
3350   Returns whether a collection instance is empty or not.  S0 must be known to
3351   be an instance of a collection class at compile time.
3353 | VecFirst, DFirstElem, S(Vec), NF
3355   Returns the first value from the packed or vec array in S0.
3356   If the array is empty, it will return NULL.
3358 | VecLast, DLastElem, S(Vec), NF
3360   Returns the last value from the packed or vec array in S0.
3361   If the array is empty, it will return NULL.
3363 | DictFirst, DFirstElem, S(Dict), NF
3365   Returns the first value from the mixed or dict array in S0.
3366   If the array is empty, it will return NULL.
3368 | DictLast, DLastElem, S(Dict), NF
3370   Returns the last value from the mixed or dict array in S0.
3371   If the array is empty, it will return NULL.
3373 | DictFirstKey, DFirstKey, S(Dict), NF
3375   Returns the first key from the mixed or dict array in S0.
3376   If the array is empty, it will return NULL.
3378 | DictLastKey, DLastKey, S(Dict), NF
3380   Returns the last key from the mixed or dict array in S0.
3381   If the array is empty, it will return NULL.
3383 | KeysetFirst, DFirstElem, S(Keyset), NF
3385   Returns the first value(key) from the keyset in S0.
3386   If the array is empty, it will return NULL.
3388 | KeysetLast, DLastElem, S(Keyset), NF
3390   Returns the first value(key) from the keyset in S0.
3391   If the array is empty, it will return NULL.
3393 | IsLegacyArrLike, D(Bool), S(Vec|Dict), LA
3395   Returns true iff the given array has the legacy bit set.
3397 | ArrayMarkLegacyShallow,     DModified(0), S(Vec,Dict), CRc|PRc|LA
3399 | ArrayMarkLegacyRecursive,   DModified(0), S(Vec,Dict), CRc|PRc|LA
3401 | ArrayUnmarkLegacyShallow,   DModified(0), S(Vec,Dict), CRc|PRc|LA
3403 | ArrayUnmarkLegacyRecursive, DModified(0), S(Vec,Dict), CRc|PRc|LA
3405   Set or unset the legacy bit on the array-like in S0, copying it if needed.
3406   The recursive variants traverse through the array-like's transitive elements
3407   but stop traversal at any non-array-like.
3410 18. Exception/unwinding support
3412 | BeginCatch, ND, NA, NF
3414   Marks the beginning of a catch region. Exact behavior is implementation and
3415   architecture specific.
3417 | EndCatch<spOffset,mode,stublogue>, ND, S(FramePtr) S(StkPtr), T
3419   Marks the end of a catch region and returns control to the unwinder.  The
3420   `spOffset' field represents a logical adjustment to S1 (in cells) to yield
3421   the vm stack pointer, however the stack pointer is not actually adjusted
3422   before this instruction returns control to the unwinder.  The unwinder
3423   instead relies on fixup map information to find the appropriate stack
3424   pointers.  Instead it's part of this instruction to facilitate assertions and
3425   memory effect analysis.
3427   If the `stublogue' flag is set, the native stack pointer is updated to reflect
3428   the state prior to entering the stublogue context.
3430 | UnwindCheckSideExit, ND, S(FramePtr) S(StkPtr), B
3432   Branches to B if the currently executing catch region should return control
3433   to the unwinder rather than side exiting.  Used to control behavior in catch
3434   traces for the InvalidSetMException and TVCoercionException situations.
3436 | LdUnwinderValue<T>, DParam(Cell), NA, PRc
3438   Loads the value contained by the current unwinder exception.
3440 | EnterTCUnwind<spOff,teardown>, ND, S(Obj), CRc|T
3442   Enters tc_unwind_resume by doing a side enter, i.e. skipping
3443   itanium ABI. Stores the exception given by S0 to UnwindRDS's exn
3444   field as well as true to sideEnter field.
3446   If teardown is set, it notifies tc_unwind_resume to also teardown the locals.
3448 19. Function prologues
3450 | EnterPrologue, ND, NA, NF
3452   Enter prologue context, which operates in the same mode as unique stubs.
3453   Makes sure the native stack is properly aligned.
3455 | CheckStackOverflow, ND, S(StkPtr), NF
3457   Check if the stack depth has exceeded its limit.  If it has, jump to the
3458   stack overflow helper stub, which will throw.
3460 | CheckSurpriseFlagsEnter<func,argc>, ND, S(FramePtr), NF
3462   Test the implementation-specific surprise flags.  If they're nonzero, call
3463   the function enter helper.
3465 | CheckSurpriseAndStack<func,args>, ND, S(FramePtr), NF
3467   Test surprise flags and stack overflow at the same time.
3469 | LdARFlags, D(Int), S(FramePtr), NF
3471   Load the flags stored on the ActRec pointed to by the frame
3472   pointer S0. Bits not defined as flags may contain arbitrary garbage.
3474 | LdTVAux<ValidBits>, D(Int), S(Cell), NF
3476   Load the value of m_aux from the TypedValue S0.  ValidBits is a mask
3477   specifying which bits are allowed to be set.  The runtime may ignore it.
3479   Note that when we pass TypedValues around in registers, we usually use a byte
3480   register for the m_type member, and thus ignore m_aux.  LdTVAux is only valid
3481   when we know that S0's m_type and m_aux were both materialized into the same
3482   64-bit register.
3484 /* Local Variables: */
3485 /* fill-column: 79 */
3486 /* End: */
3487 vim:textwidth=80