12bde8e466a4451c7319e3a072d118917957d6554Steve Block/*
22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2011 Apple Inc. All rights reserved.
32bde8e466a4451c7319e3a072d118917957d6554Steve Block *
42bde8e466a4451c7319e3a072d118917957d6554Steve Block * Redistribution and use in source and binary forms, with or without
52bde8e466a4451c7319e3a072d118917957d6554Steve Block * modification, are permitted provided that the following conditions
62bde8e466a4451c7319e3a072d118917957d6554Steve Block * are met:
72bde8e466a4451c7319e3a072d118917957d6554Steve Block * 1. Redistributions of source code must retain the above copyright
82bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer.
92bde8e466a4451c7319e3a072d118917957d6554Steve Block * 2. Redistributions in binary form must reproduce the above copyright
102bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer in the
112bde8e466a4451c7319e3a072d118917957d6554Steve Block *    documentation and/or other materials provided with the distribution.
122bde8e466a4451c7319e3a072d118917957d6554Steve Block *
132bde8e466a4451c7319e3a072d118917957d6554Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
142bde8e466a4451c7319e3a072d118917957d6554Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
152bde8e466a4451c7319e3a072d118917957d6554Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
162bde8e466a4451c7319e3a072d118917957d6554Steve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
172bde8e466a4451c7319e3a072d118917957d6554Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
182bde8e466a4451c7319e3a072d118917957d6554Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
192bde8e466a4451c7319e3a072d118917957d6554Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
202bde8e466a4451c7319e3a072d118917957d6554Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
212bde8e466a4451c7319e3a072d118917957d6554Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
222bde8e466a4451c7319e3a072d118917957d6554Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
232bde8e466a4451c7319e3a072d118917957d6554Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
242bde8e466a4451c7319e3a072d118917957d6554Steve Block */
252bde8e466a4451c7319e3a072d118917957d6554Steve Block
262bde8e466a4451c7319e3a072d118917957d6554Steve Block#ifndef DFGNode_h
272bde8e466a4451c7319e3a072d118917957d6554Steve Block#define DFGNode_h
282bde8e466a4451c7319e3a072d118917957d6554Steve Block
292bde8e466a4451c7319e3a072d118917957d6554Steve Block// Emit various logging information for debugging, including dumping the dataflow graphs.
302bde8e466a4451c7319e3a072d118917957d6554Steve Block#define DFG_DEBUG_VERBOSE 0
312bde8e466a4451c7319e3a072d118917957d6554Steve Block// Enable generation of dynamic checks into the instruction stream.
322bde8e466a4451c7319e3a072d118917957d6554Steve Block#define DFG_JIT_ASSERT 0
332bde8e466a4451c7319e3a072d118917957d6554Steve Block// Consistency check contents compiler data structures.
342bde8e466a4451c7319e3a072d118917957d6554Steve Block#define DFG_CONSISTENCY_CHECK 0
352bde8e466a4451c7319e3a072d118917957d6554Steve Block// Emit a breakpoint into the head of every generated function, to aid debugging in GDB.
362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define DFG_JIT_BREAK_ON_EVERY_FUNCTION 0
372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Emit a breakpoint into the head of every generated node, to aid debugging in GDB.
382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define DFG_JIT_BREAK_ON_EVERY_BLOCK 0
392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Emit a breakpoint into the head of every generated node, to aid debugging in GDB.
402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define DFG_JIT_BREAK_ON_EVERY_NODE 0
412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Disable the DFG JIT without having to touch Platform.h!
422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define DFG_DEBUG_LOCAL_DISBALE 0
432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch// Generate stats on how successful we were in making use of the DFG jit, and remaining on the hot path.
442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define DFG_SUCCESS_STATS 0
452bde8e466a4451c7319e3a072d118917957d6554Steve Block
462bde8e466a4451c7319e3a072d118917957d6554Steve Block
472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(DFG_JIT)
482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <wtf/Vector.h>
502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
512bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace JSC { namespace DFG {
522bde8e466a4451c7319e3a072d118917957d6554Steve Block
532bde8e466a4451c7319e3a072d118917957d6554Steve Block// Type for a virtual register number (spill location).
542bde8e466a4451c7319e3a072d118917957d6554Steve Block// Using an enum to make this type-checked at compile time, to avert programmer errors.
552bde8e466a4451c7319e3a072d118917957d6554Steve Blockenum VirtualRegister { InvalidVirtualRegister = -1 };
562bde8e466a4451c7319e3a072d118917957d6554Steve BlockCOMPILE_ASSERT(sizeof(VirtualRegister) == sizeof(int), VirtualRegister_is_32bit);
572bde8e466a4451c7319e3a072d118917957d6554Steve Block
582bde8e466a4451c7319e3a072d118917957d6554Steve Block// Type for a reference to another node in the graph.
592bde8e466a4451c7319e3a072d118917957d6554Steve Blocktypedef uint32_t NodeIndex;
602bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const NodeIndex NoNode = UINT_MAX;
612bde8e466a4451c7319e3a072d118917957d6554Steve Block
622bde8e466a4451c7319e3a072d118917957d6554Steve Block// Information used to map back from an exception to any handler/source information.
632bde8e466a4451c7319e3a072d118917957d6554Steve Block// (Presently implemented as a bytecode index).
642bde8e466a4451c7319e3a072d118917957d6554Steve Blocktypedef uint32_t ExceptionInfo;
652bde8e466a4451c7319e3a072d118917957d6554Steve Block
662bde8e466a4451c7319e3a072d118917957d6554Steve Block// Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
672bde8e466a4451c7319e3a072d118917957d6554Steve Block// and some additional informative flags (must generate, is constant, etc).
682bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NodeIdMask          0xFFF
692bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NodeResultMask     0xF000
702bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NodeMustGenerate  0x10000 // set on nodes that have side effects, and may not trivially be removed by DCE.
712bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NodeIsConstant    0x20000
722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define NodeIsJump        0x40000
732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#define NodeIsBranch      0x80000
742bde8e466a4451c7319e3a072d118917957d6554Steve Block
752bde8e466a4451c7319e3a072d118917957d6554Steve Block// These values record the result type of the node (as checked by NodeResultMask, above), 0 for no result.
762bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NodeResultJS      0x1000
772bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NodeResultDouble  0x2000
782bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NodeResultInt32   0x3000
792bde8e466a4451c7319e3a072d118917957d6554Steve Block
802bde8e466a4451c7319e3a072d118917957d6554Steve Block// This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
812bde8e466a4451c7319e3a072d118917957d6554Steve Block#define FOR_EACH_DFG_OP(macro) \
822bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Nodes for constants. */\
832bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(JSConstant, NodeResultJS | NodeIsConstant) \
842bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(Int32Constant, NodeResultJS | NodeIsConstant) \
852bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(DoubleConstant, NodeResultJS | NodeIsConstant) \
862bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ConvertThis, NodeResultJS) \
872bde8e466a4451c7319e3a072d118917957d6554Steve Block    \
882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    /* Nodes for local variable access. */\
892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(GetLocal, NodeResultJS) \
902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(SetLocal, NodeMustGenerate) \
912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    \
922bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Nodes for bitwise operations. */\
932bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(BitAnd, NodeResultInt32) \
942bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(BitOr, NodeResultInt32) \
952bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(BitXor, NodeResultInt32) \
962bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(BitLShift, NodeResultInt32) \
972bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(BitRShift, NodeResultInt32) \
982bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(BitURShift, NodeResultInt32) \
992bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Bitwise operators call ToInt32 on their operands. */\
1002bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(NumberToInt32, NodeResultInt32) \
1012bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ValueToInt32, NodeResultInt32 | NodeMustGenerate) \
1022bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
1032bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(UInt32ToNumber, NodeResultDouble) \
1042bde8e466a4451c7319e3a072d118917957d6554Steve Block    \
1052bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Nodes for arithmetic operations. */\
1062bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ArithAdd, NodeResultDouble) \
1072bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ArithSub, NodeResultDouble) \
1082bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ArithMul, NodeResultDouble) \
1092bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ArithDiv, NodeResultDouble) \
1102bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ArithMod, NodeResultDouble) \
1112bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Arithmetic operators call ToNumber on their operands. */\
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(Int32ToNumber, NodeResultDouble) \
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ValueToNumber, NodeResultDouble | NodeMustGenerate) \
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block    \
1152bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Add of values may either be arithmetic, or result in string concatenation. */\
1162bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
1172bde8e466a4451c7319e3a072d118917957d6554Steve Block    \
1182bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Property access. */\
1192bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* Since a put to 'length' may invalidate optimizations here, */\
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block    /* this must be the directly subsequent property put. */\
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(GetByVal, NodeResultJS | NodeMustGenerate) \
1232bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(PutByVal, NodeMustGenerate) \
1242bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(PutByValAlias, NodeMustGenerate) \
1252bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(GetById, NodeResultJS | NodeMustGenerate) \
1262bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(PutById, NodeMustGenerate) \
1272bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(PutByIdDirect, NodeMustGenerate) \
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(GetGlobalVar, NodeResultJS | NodeMustGenerate) \
1292bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(PutGlobalVar, NodeMustGenerate) \
1302bde8e466a4451c7319e3a072d118917957d6554Steve Block    \
1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    /* Nodes for comparison operations. */\
1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(CompareLess, NodeResultJS | NodeMustGenerate) \
1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(CompareLessEq, NodeResultJS | NodeMustGenerate) \
1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(CompareEq, NodeResultJS | NodeMustGenerate) \
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(CompareStrictEq, NodeResultJS) \
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    \
1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    /* Nodes for misc operations. */\
1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(LogicalNot, NodeResultJS) \
1392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    \
1402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    /* Block terminals. */\
1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(Jump, NodeMustGenerate | NodeIsJump) \
1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    macro(Branch, NodeMustGenerate | NodeIsBranch) \
1432bde8e466a4451c7319e3a072d118917957d6554Steve Block    macro(Return, NodeMustGenerate)
1442bde8e466a4451c7319e3a072d118917957d6554Steve Block
1452bde8e466a4451c7319e3a072d118917957d6554Steve Block// This enum generates a monotonically increasing id for all Node types,
1462bde8e466a4451c7319e3a072d118917957d6554Steve Block// and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
1472bde8e466a4451c7319e3a072d118917957d6554Steve Blockenum NodeId {
1482bde8e466a4451c7319e3a072d118917957d6554Steve Block#define DFG_OP_ENUM(opcode, flags) opcode##_id,
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block    FOR_EACH_DFG_OP(DFG_OP_ENUM)
1502bde8e466a4451c7319e3a072d118917957d6554Steve Block#undef DFG_OP_ENUM
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block};
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block
1532bde8e466a4451c7319e3a072d118917957d6554Steve Block// Entries in this enum describe all Node types.
1542bde8e466a4451c7319e3a072d118917957d6554Steve Block// The enum value contains a monotonically increasing id, a result type, and additional flags.
1552bde8e466a4451c7319e3a072d118917957d6554Steve Blockenum NodeType {
1562bde8e466a4451c7319e3a072d118917957d6554Steve Block#define DFG_OP_ENUM(opcode, flags) opcode = opcode##_id | (flags),
1572bde8e466a4451c7319e3a072d118917957d6554Steve Block    FOR_EACH_DFG_OP(DFG_OP_ENUM)
1582bde8e466a4451c7319e3a072d118917957d6554Steve Block#undef DFG_OP_ENUM
1592bde8e466a4451c7319e3a072d118917957d6554Steve Block};
1602bde8e466a4451c7319e3a072d118917957d6554Steve Block
1612bde8e466a4451c7319e3a072d118917957d6554Steve Block// This type used in passing an immediate argument to Node constructor;
1622bde8e466a4451c7319e3a072d118917957d6554Steve Block// distinguishes an immediate value (typically an index into a CodeBlock data structure -
1632bde8e466a4451c7319e3a072d118917957d6554Steve Block// a constant index, argument, or identifier) from a NodeIndex.
1642bde8e466a4451c7319e3a072d118917957d6554Steve Blockstruct OpInfo {
1652bde8e466a4451c7319e3a072d118917957d6554Steve Block    explicit OpInfo(unsigned value) : m_value(value) {}
1662bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned m_value;
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block};
1682bde8e466a4451c7319e3a072d118917957d6554Steve Block
1692bde8e466a4451c7319e3a072d118917957d6554Steve Block// === Node ===
1702bde8e466a4451c7319e3a072d118917957d6554Steve Block//
1712bde8e466a4451c7319e3a072d118917957d6554Steve Block// Node represents a single operation in the data flow graph.
1722bde8e466a4451c7319e3a072d118917957d6554Steve Blockstruct Node {
1732bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Construct a node with up to 3 children, no immediate value.
1742bde8e466a4451c7319e3a072d118917957d6554Steve Block    Node(NodeType op, ExceptionInfo exceptionInfo, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
1752bde8e466a4451c7319e3a072d118917957d6554Steve Block        : op(op)
1762bde8e466a4451c7319e3a072d118917957d6554Steve Block        , exceptionInfo(exceptionInfo)
1772bde8e466a4451c7319e3a072d118917957d6554Steve Block        , child1(child1)
1782bde8e466a4451c7319e3a072d118917957d6554Steve Block        , child2(child2)
1792bde8e466a4451c7319e3a072d118917957d6554Steve Block        , child3(child3)
1802bde8e466a4451c7319e3a072d118917957d6554Steve Block        , virtualRegister(InvalidVirtualRegister)
1812bde8e466a4451c7319e3a072d118917957d6554Steve Block        , refCount(0)
1822bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
1832bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1842bde8e466a4451c7319e3a072d118917957d6554Steve Block
1852bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Construct a node with up to 3 children and an immediate value.
1862bde8e466a4451c7319e3a072d118917957d6554Steve Block    Node(NodeType op, ExceptionInfo exceptionInfo, OpInfo imm, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
1872bde8e466a4451c7319e3a072d118917957d6554Steve Block        : op(op)
1882bde8e466a4451c7319e3a072d118917957d6554Steve Block        , exceptionInfo(exceptionInfo)
1892bde8e466a4451c7319e3a072d118917957d6554Steve Block        , child1(child1)
1902bde8e466a4451c7319e3a072d118917957d6554Steve Block        , child2(child2)
1912bde8e466a4451c7319e3a072d118917957d6554Steve Block        , child3(child3)
1922bde8e466a4451c7319e3a072d118917957d6554Steve Block        , virtualRegister(InvalidVirtualRegister)
1932bde8e466a4451c7319e3a072d118917957d6554Steve Block        , refCount(0)
1942bde8e466a4451c7319e3a072d118917957d6554Steve Block        , m_opInfo(imm.m_value)
1952bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
1962bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1972bde8e466a4451c7319e3a072d118917957d6554Steve Block
1982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Construct a node with up to 3 children and two immediate values.
1992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    Node(NodeType op, ExceptionInfo exceptionInfo, OpInfo imm1, OpInfo imm2, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
2002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        : op(op)
2012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        , exceptionInfo(exceptionInfo)
2022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        , child1(child1)
2032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        , child2(child2)
2042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        , child3(child3)
2052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        , virtualRegister(InvalidVirtualRegister)
2062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        , refCount(0)
2072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        , m_opInfo(imm1.m_value)
2082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
2092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_constantValue.opInfo2 = imm2.m_value;
2102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
2112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool mustGenerate()
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block        return op & NodeMustGenerate;
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2162bde8e466a4451c7319e3a072d118917957d6554Steve Block
2172bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool isConstant()
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2192bde8e466a4451c7319e3a072d118917957d6554Steve Block        return op & NodeIsConstant;
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned constantNumber()
2232bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2242bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(isConstant());
2252bde8e466a4451c7319e3a072d118917957d6554Steve Block        return m_opInfo;
2262bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2272bde8e466a4451c7319e3a072d118917957d6554Steve Block
2282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool hasLocal()
2292bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return op == GetLocal || op == SetLocal;
2312bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2322bde8e466a4451c7319e3a072d118917957d6554Steve Block
2332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    VirtualRegister local()
2342bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(hasLocal());
2362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return (VirtualRegister)m_opInfo;
2372bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2382bde8e466a4451c7319e3a072d118917957d6554Steve Block
2392bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasIdentifier()
2402bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2412bde8e466a4451c7319e3a072d118917957d6554Steve Block        return op == GetById || op == PutById || op == PutByIdDirect;
2422bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2432bde8e466a4451c7319e3a072d118917957d6554Steve Block
2442bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned identifierNumber()
2452bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2462bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(hasIdentifier());
2472bde8e466a4451c7319e3a072d118917957d6554Steve Block        return m_opInfo;
2482bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2492bde8e466a4451c7319e3a072d118917957d6554Steve Block
2502bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasVarNumber()
2512bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2522bde8e466a4451c7319e3a072d118917957d6554Steve Block        return op == GetGlobalVar || op == PutGlobalVar;
2532bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2542bde8e466a4451c7319e3a072d118917957d6554Steve Block
2552bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned varNumber()
2562bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2572bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(hasVarNumber());
2582bde8e466a4451c7319e3a072d118917957d6554Steve Block        return m_opInfo;
2592bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2602bde8e466a4451c7319e3a072d118917957d6554Steve Block
2612bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasInt32Result()
2622bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2632bde8e466a4451c7319e3a072d118917957d6554Steve Block        return (op & NodeResultMask) == NodeResultInt32;
2642bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2652bde8e466a4451c7319e3a072d118917957d6554Steve Block
2662bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasDoubleResult()
2672bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2682bde8e466a4451c7319e3a072d118917957d6554Steve Block        return (op & NodeResultMask) == NodeResultDouble;
2692bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block
2712bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasJSResult()
2722bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2732bde8e466a4451c7319e3a072d118917957d6554Steve Block        return (op & NodeResultMask) == NodeResultJS;
2742bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2752bde8e466a4451c7319e3a072d118917957d6554Steve Block
2762bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Check for integers or doubles.
2772bde8e466a4451c7319e3a072d118917957d6554Steve Block    bool hasNumericResult()
2782bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2792bde8e466a4451c7319e3a072d118917957d6554Steve Block        // This check will need updating if more result types are added.
2802bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT((hasInt32Result() || hasDoubleResult()) == !hasJSResult());
2812bde8e466a4451c7319e3a072d118917957d6554Steve Block        return !hasJSResult();
2822bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2832bde8e466a4451c7319e3a072d118917957d6554Steve Block
2842bde8e466a4451c7319e3a072d118917957d6554Steve Block    int32_t int32Constant()
2852bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2862bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(op == Int32Constant);
2872bde8e466a4451c7319e3a072d118917957d6554Steve Block        return m_constantValue.asInt32;
2882bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2892bde8e466a4451c7319e3a072d118917957d6554Steve Block
2902bde8e466a4451c7319e3a072d118917957d6554Steve Block    void setInt32Constant(int32_t value)
2912bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2922bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(op == Int32Constant);
2932bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_constantValue.asInt32 = value;
2942bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2952bde8e466a4451c7319e3a072d118917957d6554Steve Block
2962bde8e466a4451c7319e3a072d118917957d6554Steve Block    double numericConstant()
2972bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2982bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(op == DoubleConstant);
2992bde8e466a4451c7319e3a072d118917957d6554Steve Block        return m_constantValue.asDouble;
3002bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3012bde8e466a4451c7319e3a072d118917957d6554Steve Block
3022bde8e466a4451c7319e3a072d118917957d6554Steve Block    void setDoubleConstant(double value)
3032bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
3042bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(op == DoubleConstant);
3052bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_constantValue.asDouble = value;
3062bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3072bde8e466a4451c7319e3a072d118917957d6554Steve Block
3082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool isJump()
3092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return op & NodeIsJump;
3112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
3122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool isBranch()
3142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return op & NodeIsBranch;
3162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
3172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    unsigned takenBytecodeOffset()
3192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(isBranch() || isJump());
3212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return m_opInfo;
3222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
3232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    unsigned notTakenBytecodeOffset()
3252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(isBranch());
3272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return m_constantValue.opInfo2;
3282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
3292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3302bde8e466a4451c7319e3a072d118917957d6554Steve Block    // This enum value describes the type of the node.
3312bde8e466a4451c7319e3a072d118917957d6554Steve Block    NodeType op;
3322bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Used to look up exception handling information (currently implemented as a bytecode index).
3332bde8e466a4451c7319e3a072d118917957d6554Steve Block    ExceptionInfo exceptionInfo;
3342bde8e466a4451c7319e3a072d118917957d6554Steve Block    // References to up to 3 children (0 for no child).
3352bde8e466a4451c7319e3a072d118917957d6554Steve Block    NodeIndex child1, child2, child3;
3362bde8e466a4451c7319e3a072d118917957d6554Steve Block    // The virtual register number (spill location) associated with this .
3372bde8e466a4451c7319e3a072d118917957d6554Steve Block    VirtualRegister virtualRegister;
3382bde8e466a4451c7319e3a072d118917957d6554Steve Block    // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
3392bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned refCount;
3402bde8e466a4451c7319e3a072d118917957d6554Steve Block
3412bde8e466a4451c7319e3a072d118917957d6554Steve Blockprivate:
3422bde8e466a4451c7319e3a072d118917957d6554Steve Block    // An immediate value, accesses type-checked via accessors above.
3432bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned m_opInfo;
3442bde8e466a4451c7319e3a072d118917957d6554Steve Block    // The value of an int32/double constant.
3452bde8e466a4451c7319e3a072d118917957d6554Steve Block    union {
3462bde8e466a4451c7319e3a072d118917957d6554Steve Block        int32_t asInt32;
3472bde8e466a4451c7319e3a072d118917957d6554Steve Block        double asDouble;
3482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        unsigned opInfo2;
3492bde8e466a4451c7319e3a072d118917957d6554Steve Block    } m_constantValue;
3502bde8e466a4451c7319e3a072d118917957d6554Steve Block};
3512bde8e466a4451c7319e3a072d118917957d6554Steve Block
3522bde8e466a4451c7319e3a072d118917957d6554Steve Block} } // namespace JSC::DFG
3532bde8e466a4451c7319e3a072d118917957d6554Steve Block
3542bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
3552bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
356