/*
 * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "DFGFixupPhase.h"

#if ENABLE(DFG_JIT)

#include "ArrayPrototype.h"
#include "DFGGraph.h"
#include "DFGInsertionSet.h"
#include "DFGPhase.h"
#include "DFGPredictionPropagationPhase.h"
#include "DFGVariableAccessDataDump.h"
#include "GetterSetter.h"
#include "JSCInlines.h"
#include "TypeLocation.h"

namespace JSC { namespace DFG {

class FixupPhase : public Phase {
public:
    FixupPhase(Graph& graph)
        : Phase(graph, "fixup")
        , m_insertionSet(graph)
    {
    }
    
    bool run()
    {
        ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
        ASSERT(m_graph.m_form == ThreadedCPS);
        
        m_profitabilityChanged = false;
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
            fixupBlock(m_graph.block(blockIndex));
        
        while (m_profitabilityChanged) {
            m_profitabilityChanged = false;
            
            for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
                m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
            
            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
                fixupGetAndSetLocalsInBlock(m_graph.block(blockIndex));
        }
        
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
            fixupChecksInBlock(m_graph.block(blockIndex));

        m_graph.m_planStage = PlanStage::AfterFixup;

        return true;
    }

private:

    void fixupArithDivInt32(Node* node, Edge& leftChild, Edge& rightChild)
    {
        if (optimizeForX86() || optimizeForARM64() || optimizeForARMv7IDIVSupported()) {
            fixIntOrBooleanEdge(leftChild);
            fixIntOrBooleanEdge(rightChild);
            if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
                node->setArithMode(Arith::Unchecked);
            else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
                node->setArithMode(Arith::CheckOverflow);
            else
                node->setArithMode(Arith::CheckOverflowAndNegativeZero);
            return;
        }

        // This will cause conversion nodes to be inserted later.
        fixDoubleOrBooleanEdge(leftChild);
        fixDoubleOrBooleanEdge(rightChild);

        // We don't need to do ref'ing on the children because we're stealing them from
        // the original division.
        Node* newDivision = m_insertionSet.insertNode(m_indexInBlock, SpecBytecodeDouble, *node);
        newDivision->setResult(NodeResultDouble);

        node->setOp(DoubleAsInt32);
        node->children.initialize(Edge(newDivision, DoubleRepUse), Edge(), Edge());
        if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
            node->setArithMode(Arith::CheckOverflow);
        else
            node->setArithMode(Arith::CheckOverflowAndNegativeZero);

    }

    void fixupArithPow(Node* node)
    {
        if (node->child2()->shouldSpeculateInt32OrBooleanForArithmetic()) {
            fixDoubleOrBooleanEdge(node->child1());
            fixIntOrBooleanEdge(node->child2());
            return;
        }

        fixDoubleOrBooleanEdge(node->child1());
        fixDoubleOrBooleanEdge(node->child2());
    }

    void fixupArithDiv(Node* node, Edge& leftChild, Edge& rightChild)
    {
        if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
            fixupArithDivInt32(node, leftChild, rightChild);
            return;
        }
        
        fixDoubleOrBooleanEdge(leftChild);
        fixDoubleOrBooleanEdge(rightChild);
        node->setResult(NodeResultDouble);
    }
    
    void fixupArithMul(Node* node, Edge& leftChild, Edge& rightChild)
    {
        if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
            fixIntOrBooleanEdge(leftChild);
            fixIntOrBooleanEdge(rightChild);
            if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
                node->setArithMode(Arith::Unchecked);
            else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()) || leftChild.node() == rightChild.node())
                node->setArithMode(Arith::CheckOverflow);
            else
                node->setArithMode(Arith::CheckOverflowAndNegativeZero);
            return;
        }
        if (m_graph.binaryArithShouldSpeculateInt52(node, FixupPass)) {
            fixEdge<Int52RepUse>(leftChild);
            fixEdge<Int52RepUse>(rightChild);
            if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()) || leftChild.node() == rightChild.node())
                node->setArithMode(Arith::CheckOverflow);
            else
                node->setArithMode(Arith::CheckOverflowAndNegativeZero);
            node->setResult(NodeResultInt52);
            return;
        }

        fixDoubleOrBooleanEdge(leftChild);
        fixDoubleOrBooleanEdge(rightChild);
        node->setResult(NodeResultDouble);
    }

    void fixupBlock(BasicBlock* block)
    {
        if (!block)
            return;
        ASSERT(block->isReachable);
        m_block = block;
        for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
            m_currentNode = block->at(m_indexInBlock);
            fixupNode(m_currentNode);
        }
        m_insertionSet.execute(block);
    }
    
    void fixupNode(Node* node)
    {
        NodeType op = node->op();

        switch (op) {
        case SetLocal: {
            // This gets handled by fixupGetAndSetLocalsInBlock().
            return;
        }

        case Inc:
        case Dec: {
            if (node->child1()->shouldSpeculateUntypedForArithmetic()) {
                fixEdge<UntypedUse>(node->child1());
                break;
            }

            Node* nodeConstantOne;
            if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
                node->setOp(op == Inc ? ArithAdd : ArithSub);
                node->setArithMode(Arith::CheckOverflow);
                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecInt32Only, JSConstant, node->origin, OpInfo(m_graph.freeze(jsNumber(1))));
                node->children.setChild2(Edge(nodeConstantOne));
                fixEdge<Int32Use>(node->child1());
                fixEdge<Int32Use>(node->child2());
                node->setResult(NodeResultInt32);
            } else if (node->child1()->shouldSpeculateBigInt()) {
                // FIXME: the freezing does not appear useful (since the JSCell is kept alive by vm), but it refuses to compile otherwise.
                node->setOp(op == Inc ? ValueAdd : ValueSub);
                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBigInt, JSConstant, node->origin, OpInfo(m_graph.freeze(vm().bigIntConstantOne.get())));
                node->children.setChild2(Edge(nodeConstantOne));
                fixEdge<BigIntUse>(node->child1());
                fixEdge<BigIntUse>(node->child2());
                // BigInts are currently cells, so the default of NodeResultJS is good here
            } else if (node->child1()->shouldSpeculateInt52()) {
                node->setOp(op == Inc ? ArithAdd : ArithSub);
                node->setArithMode(Arith::CheckOverflow);
                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecInt32AsInt52, JSConstant, node->origin, OpInfo(m_graph.freeze(jsNumber(1))));
                node->children.setChild2(Edge(nodeConstantOne));
                fixEdge<Int52RepUse>(node->child1());
                fixEdge<Int52RepUse>(node->child2());
                node->setResult(NodeResultInt52);
            } else {
                node->setOp(op == Inc ? ArithAdd : ArithSub);
                node->setArithMode(Arith::Unchecked);
                nodeConstantOne = m_insertionSet.insertNode(m_indexInBlock, SpecBytecodeDouble, JSConstant, node->origin, OpInfo(m_graph.freeze(jsNumber(1))));
                node->children.setChild2(Edge(nodeConstantOne));
                fixEdge<DoubleRepUse>(node->child1());
                fixEdge<DoubleRepUse>(node->child2());
                node->setResult(NodeResultDouble);
            }
            node->clearFlags(NodeMustGenerate);
            break;
        }

        case ValueSub: {
            Edge& child1 = node->child1();
            Edge& child2 = node->child2();

            if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) {
                fixEdge<BigIntUse>(child1);
                fixEdge<BigIntUse>(child2);
                break; 
            }
            
            if (Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
                fixEdge<UntypedUse>(child1);
                fixEdge<UntypedUse>(child2);
                break;
            }

            if (attemptToMakeIntegerAdd(node)) {
                // FIXME: Clear ArithSub's NodeMustGenerate when ArithMode is unchecked
                // https://bugs.webkit.org/show_bug.cgi?id=190607
                node->setOp(ArithSub);
                break;
            }

            fixDoubleOrBooleanEdge(node->child1());
            fixDoubleOrBooleanEdge(node->child2());
            node->setOp(ArithSub);
            node->setResult(NodeResultDouble);

            break;
        }

        case ValueBitLShift:
        case ValueBitRShift:
        case ValueBitXor:
        case ValueBitOr:
        case ValueBitAnd: {
            if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
                fixEdge<BigIntUse>(node->child1());
                fixEdge<BigIntUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }

            if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
                fixEdge<UntypedUse>(node->child1());
                fixEdge<UntypedUse>(node->child2());
                break;
            }
            
            switch (op) {
            case ValueBitXor:
                node->setOp(ArithBitXor);
                break;
            case ValueBitOr:
                node->setOp(ArithBitOr);
                break;
            case ValueBitAnd:
                node->setOp(ArithBitAnd);
                break;
            case ValueBitLShift:
                node->setOp(ArithBitLShift);
                break;
            case ValueBitRShift:
                node->setOp(ArithBitRShift);
                break;
            default:
                DFG_CRASH(m_graph, node, "Unexpected node during ValueBit operation fixup");
                break;
            }

            node->clearFlags(NodeMustGenerate);
            node->setResult(NodeResultInt32);
            fixIntConvertingEdge(node->child1());
            fixIntConvertingEdge(node->child2());
            break;
        }

        case ValueBitNot: {
            Edge& operandEdge = node->child1();

            if (operandEdge.node()->shouldSpeculateBigInt()) {
                node->clearFlags(NodeMustGenerate);
                fixEdge<BigIntUse>(operandEdge);
            } else if (operandEdge.node()->shouldSpeculateUntypedForBitOps())
                fixEdge<UntypedUse>(operandEdge);
            else {
                node->setOp(ArithBitNot);
                node->setResult(NodeResultInt32);
                node->clearFlags(NodeMustGenerate);
                fixIntConvertingEdge(operandEdge);
            }
            break;
        }

        case ArithBitNot: {
            Edge& operandEdge = node->child1();

            fixIntConvertingEdge(operandEdge);
            break;
        }

        case ArithBitRShift:
        case ArithBitLShift: 
        case ArithBitXor:
        case ArithBitOr:
        case ArithBitAnd: {
            fixIntConvertingEdge(node->child1());
            fixIntConvertingEdge(node->child2());
            break;
        }

        case BitURShift: {
            if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
                fixEdge<UntypedUse>(node->child1());
                fixEdge<UntypedUse>(node->child2());
                break;
            }
            fixIntConvertingEdge(node->child1());
            fixIntConvertingEdge(node->child2());
            break;
        }

        case ArithIMul: {
            fixIntConvertingEdge(node->child1());
            fixIntConvertingEdge(node->child2());
            node->setOp(ArithMul);
            node->setArithMode(Arith::Unchecked);
            node->child1().setUseKind(Int32Use);
            node->child2().setUseKind(Int32Use);
            break;
        }

        case ArithClz32: {
            if (node->child1()->shouldSpeculateNotCell()) {
                fixIntConvertingEdge(node->child1());
                node->clearFlags(NodeMustGenerate);
            } else
                fixEdge<UntypedUse>(node->child1());
            break;
        }
            
        case UInt32ToNumber: {
            fixIntConvertingEdge(node->child1());
            if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
                node->convertToIdentity();
            else if (node->canSpeculateInt32(FixupPass))
                node->setArithMode(Arith::CheckOverflow);
            else {
                node->setArithMode(Arith::DoOverflow);
                node->setResult(enableInt52() ? NodeResultInt52 : NodeResultDouble);
            }
            break;
        }

        case ValueNegate: {
            if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
                node->setOp(ArithNegate);
                fixIntOrBooleanEdge(node->child1());
                if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
                    node->setArithMode(Arith::Unchecked);
                else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
                    node->setArithMode(Arith::CheckOverflow);
                else
                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
                node->setResult(NodeResultInt32);
                node->clearFlags(NodeMustGenerate);
                break;
            }
            
            if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
                node->setOp(ArithNegate);
                fixEdge<Int52RepUse>(node->child1());
                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
                    node->setArithMode(Arith::CheckOverflow);
                else
                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
                node->setResult(NodeResultInt52);
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (node->child1()->shouldSpeculateNotCell()) {
                node->setOp(ArithNegate);
                fixDoubleOrBooleanEdge(node->child1());
                node->setResult(NodeResultDouble);
                node->clearFlags(NodeMustGenerate);
            } else {
                fixEdge<UntypedUse>(node->child1());
                node->setResult(NodeResultJS);
            }
            break;
        }

        case ValueAdd: {
            if (attemptToMakeIntegerAdd(node)) {
                node->setOp(ArithAdd);
                break;
            }
            if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
                fixDoubleOrBooleanEdge(node->child1());
                fixDoubleOrBooleanEdge(node->child2());
                node->setOp(ArithAdd);
                node->setResult(NodeResultDouble);
                break;
            }
            
            if (attemptToMakeFastStringAdd(node))
                break;

            Edge& child1 = node->child1();
            Edge& child2 = node->child2();
            if (child1->shouldSpeculateString() || child2->shouldSpeculateString()) {
                if (child1->shouldSpeculateInt32() || child2->shouldSpeculateInt32()) {
                    auto convertString = [&](Node* node, Edge& edge) {
                        if (edge->shouldSpeculateInt32())
                            convertStringAddUse<Int32Use>(node, edge);
                        else {
                            ASSERT(edge->shouldSpeculateString());
                            convertStringAddUse<StringUse>(node, edge);
                        }
                    };
                    convertString(node, child1);
                    convertString(node, child2);
                    convertToMakeRope(node);
                    break;
                }
            }

            if (Node::shouldSpeculateBigInt(child1.node(), child2.node())) {
                fixEdge<BigIntUse>(child1);
                fixEdge<BigIntUse>(child2);
            } else {
                fixEdge<UntypedUse>(child1);
                fixEdge<UntypedUse>(child2);
            }

            node->setResult(NodeResultJS);
            break;
        }

        case StrCat: {
            if (attemptToMakeFastStringAdd(node))
                break;

            // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
            // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
            // the implementation of StrCat doesn't dynamically optimize for empty strings.
            // https://bugs.webkit.org/show_bug.cgi?id=148540
            m_graph.doToChildren(
                node,
                [&] (Edge& edge) {
                    fixEdge<KnownPrimitiveUse>(edge);
                    // StrCat automatically coerces the values into strings before concatenating them.
                    // The ECMA spec says that we're not allowed to automatically coerce a Symbol into
                    // a string. If a Symbol is encountered, a TypeError will be thrown. As a result,
                    // our runtime functions for this slow path expect that they will never be passed
                    // Symbols.
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, Check, node->origin,
                        Edge(edge.node(), NotSymbolUse));
                });
            break;
        }
            
        case MakeRope: {
            fixupMakeRope(node);
            break;
        }
            
        case ArithAdd:
        case ArithSub: {
            // FIXME: Clear ArithSub's NodeMustGenerate when ArithMode is unchecked
            // https://bugs.webkit.org/show_bug.cgi?id=190607
            if (attemptToMakeIntegerAdd(node))
                break;
            fixDoubleOrBooleanEdge(node->child1());
            fixDoubleOrBooleanEdge(node->child2());
            node->setResult(NodeResultDouble);
            break;
        }
            
        case ArithNegate: {
            if (node->child1()->shouldSpeculateInt32OrBoolean() && node->canSpeculateInt32(FixupPass)) {
                fixIntOrBooleanEdge(node->child1());
                if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
                    node->setArithMode(Arith::Unchecked);
                else if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
                    node->setArithMode(Arith::CheckOverflow);
                else
                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
                node->setResult(NodeResultInt32);
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (m_graph.unaryArithShouldSpeculateInt52(node, FixupPass)) {
                fixEdge<Int52RepUse>(node->child1());
                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
                    node->setArithMode(Arith::CheckOverflow);
                else
                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
                node->setResult(NodeResultInt52);
                node->clearFlags(NodeMustGenerate);
                break;
            }

            fixDoubleOrBooleanEdge(node->child1());
            node->setResult(NodeResultDouble);
            node->clearFlags(NodeMustGenerate);
            break;
        }

        case ValueMul: {
            Edge& leftChild = node->child1();
            Edge& rightChild = node->child2();

            if (Node::shouldSpeculateBigInt(leftChild.node(), rightChild.node())) {
                fixEdge<BigIntUse>(node->child1());
                fixEdge<BigIntUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }

            // There are cases where we can have BigInt + Int32 operands reaching ValueMul.
            // Imagine the scenario where ValueMul was never executed, but we can predict types
            // reaching the node:
            //
            // 63: GetLocal(Check:Untyped:@72, JS|MustGen, NonBoolInt32, ...)  predicting NonBoolInt32
            // 64: GetLocal(Check:Untyped:@71, JS|MustGen, BigInt, ...)  predicting BigInt
            // 65: ValueMul(Check:Untyped:@63, Check:Untyped:@64, BigInt|BoolInt32|NonBoolInt32, ...)
            // 
            // In such scenario, we need to emit ValueMul(Untyped, Untyped), so the runtime can throw 
            // an exception whenever it gets excuted.
            if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
                fixEdge<UntypedUse>(leftChild);
                fixEdge<UntypedUse>(rightChild);
                break;
            }

            // At this point, all other possible specializations are only handled by ArithMul.
            node->setOp(ArithMul);
            node->setResult(NodeResultNumber);
            fixupArithMul(node, leftChild, rightChild);
            break;
        }

        case ArithMul: {
            Edge& leftChild = node->child1();
            Edge& rightChild = node->child2();

            fixupArithMul(node, leftChild, rightChild);
            break;
        }

        case ValueMod: 
        case ValueDiv: {
            Edge& leftChild = node->child1();
            Edge& rightChild = node->child2();

            if (Node::shouldSpeculateBigInt(leftChild.node(), rightChild.node())) {
                fixEdge<BigIntUse>(leftChild);
                fixEdge<BigIntUse>(rightChild);
                node->clearFlags(NodeMustGenerate);
                break; 
            }

            if (Node::shouldSpeculateUntypedForArithmetic(leftChild.node(), rightChild.node())) {
                fixEdge<UntypedUse>(leftChild);
                fixEdge<UntypedUse>(rightChild);
                break;
            }

            if (op == ValueDiv)
                node->setOp(ArithDiv);
            else
                node->setOp(ArithMod);

            node->setResult(NodeResultNumber);
            fixupArithDiv(node, leftChild, rightChild);
            break;

        }

        case ArithDiv:
        case ArithMod: {
            Edge& leftChild = node->child1();
            Edge& rightChild = node->child2();

            fixupArithDiv(node, leftChild, rightChild);
            break;
        }
            
        case ArithMin:
        case ArithMax: {
            if (m_graph.binaryArithShouldSpeculateInt32(node, FixupPass)) {
                fixIntOrBooleanEdge(node->child1());
                fixIntOrBooleanEdge(node->child2());
                break;
            }
            fixDoubleOrBooleanEdge(node->child1());
            fixDoubleOrBooleanEdge(node->child2());
            node->setResult(NodeResultDouble);
            break;
        }
            
        case ArithAbs: {
            if (node->child1()->shouldSpeculateInt32OrBoolean()
                && node->canSpeculateInt32(FixupPass)) {
                fixIntOrBooleanEdge(node->child1());
                if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
                    node->setArithMode(Arith::Unchecked);
                else
                    node->setArithMode(Arith::CheckOverflow);
                node->clearFlags(NodeMustGenerate);
                node->setResult(NodeResultInt32);
                break;
            }

            if (node->child1()->shouldSpeculateNotCell()) {
                fixDoubleOrBooleanEdge(node->child1());
                node->clearFlags(NodeMustGenerate);
            } else
                fixEdge<UntypedUse>(node->child1());
            node->setResult(NodeResultDouble);
            break;
        }

        case ValuePow: {
            if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
                fixEdge<BigIntUse>(node->child1());
                fixEdge<BigIntUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }

            if (Node::shouldSpeculateUntypedForArithmetic(node->child1().node(), node->child2().node())) {
                fixEdge<UntypedUse>(node->child1());
                fixEdge<UntypedUse>(node->child2());
                break;
            }

            node->setOp(ArithPow);
            node->clearFlags(NodeMustGenerate);
            node->setResult(NodeResultDouble);

            fixupArithPow(node);
            break;
        }

        case ArithPow: {
            fixupArithPow(node);
            break;
        }

        case ArithRandom: {
            node->setResult(NodeResultDouble);
            break;
        }

        case ArithRound:
        case ArithFloor:
        case ArithCeil:
        case ArithTrunc: {
            if (node->child1()->shouldSpeculateInt32OrBoolean() && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
                fixIntOrBooleanEdge(node->child1());
                insertCheck<Int32Use>(node->child1().node());
                node->convertToIdentity();
                break;
            }
            if (node->child1()->shouldSpeculateNotCell()) {
                fixDoubleOrBooleanEdge(node->child1());

                if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, FixupPass)) {
                    node->setResult(NodeResultInt32);
                    if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
                        node->setArithRoundingMode(Arith::RoundingMode::Int32);
                    else
                        node->setArithRoundingMode(Arith::RoundingMode::Int32WithNegativeZeroCheck);
                } else {
                    node->setResult(NodeResultDouble);
                    node->setArithRoundingMode(Arith::RoundingMode::Double);
                }
                node->clearFlags(NodeMustGenerate);
            } else
                fixEdge<UntypedUse>(node->child1());
            break;
        }

        case ArithFRound:
        case ArithSqrt:
        case ArithUnary: {
            Edge& child1 = node->child1();
            if (child1->shouldSpeculateNotCell()) {
                fixDoubleOrBooleanEdge(child1);
                node->clearFlags(NodeMustGenerate);
            } else
                fixEdge<UntypedUse>(child1);
            break;
        }
            
        case LogicalNot: {
            if (node->child1()->shouldSpeculateBoolean()) {
                if (node->child1()->result() == NodeResultBoolean) {
                    // This is necessary in case we have a bytecode instruction implemented by:
                    //
                    // a: CompareEq(...)
                    // b: LogicalNot(@a)
                    //
                    // In that case, CompareEq might have a side-effect. Then, we need to make
                    // sure that we know that Branch does not exit.
                    fixEdge<KnownBooleanUse>(node->child1());
                } else
                    fixEdge<BooleanUse>(node->child1());
            } else if (node->child1()->shouldSpeculateObjectOrOther())
                fixEdge<ObjectOrOtherUse>(node->child1());
            else if (node->child1()->shouldSpeculateInt32OrBoolean())
                fixIntOrBooleanEdge(node->child1());
            else if (node->child1()->shouldSpeculateNumber())
                fixEdge<DoubleRepUse>(node->child1());
            else if (node->child1()->shouldSpeculateString())
                fixEdge<StringUse>(node->child1());
            else if (node->child1()->shouldSpeculateStringOrOther())
                fixEdge<StringOrOtherUse>(node->child1());
            else {
                WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
                if (masqueradesAsUndefinedWatchpoint->isStillValid())
                    m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
            }
            break;
        }

        case CompareEq:
        case CompareLess:
        case CompareLessEq:
        case CompareGreater:
        case CompareGreaterEq: {
            if (node->op() == CompareEq
                && Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
                fixEdge<BooleanUse>(node->child1());
                fixEdge<BooleanUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (Node::shouldSpeculateInt32OrBoolean(node->child1().node(), node->child2().node())) {
                fixIntOrBooleanEdge(node->child1());
                fixIntOrBooleanEdge(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (Node::shouldSpeculateInt52(node->child1().node(), node->child2().node())) {
                fixEdge<Int52RepUse>(node->child1());
                fixEdge<Int52RepUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
                fixDoubleOrBooleanEdge(node->child1());
                fixDoubleOrBooleanEdge(node->child2());
            }
            if (node->op() != CompareEq
                && node->child1()->shouldSpeculateNotCell()
                && node->child2()->shouldSpeculateNotCell()) {
                if (node->child1()->shouldSpeculateNumberOrBoolean())
                    fixDoubleOrBooleanEdge(node->child1());
                else
                    fixEdge<DoubleRepUse>(node->child1());
                if (node->child2()->shouldSpeculateNumberOrBoolean())
                    fixDoubleOrBooleanEdge(node->child2());
                else
                    fixEdge<DoubleRepUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
                fixEdge<StringIdentUse>(node->child1());
                fixEdge<StringIdentUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
                fixEdge<StringUse>(node->child1());
                fixEdge<StringUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }

            if (node->op() != CompareEq)
                break;
            if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
                fixEdge<SymbolUse>(node->child1());
                fixEdge<SymbolUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
                fixEdge<ObjectUse>(node->child1());
                fixEdge<ObjectUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }

            // If either child can be proved to be Null or Undefined, comparing them is greatly simplified.
            bool oneArgumentIsUsedAsSpecOther = false;
            if (node->child1()->isUndefinedOrNullConstant()) {
                fixEdge<KnownOtherUse>(node->child1());
                oneArgumentIsUsedAsSpecOther = true;
            } else if (node->child1()->shouldSpeculateOther()) {
                m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
                    Edge(node->child1().node(), OtherUse));
                fixEdge<KnownOtherUse>(node->child1());
                oneArgumentIsUsedAsSpecOther = true;
            }
            if (node->child2()->isUndefinedOrNullConstant()) {
                fixEdge<KnownOtherUse>(node->child2());
                oneArgumentIsUsedAsSpecOther = true;
            } else if (node->child2()->shouldSpeculateOther()) {
                m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin,
                    Edge(node->child2().node(), OtherUse));
                fixEdge<KnownOtherUse>(node->child2());
                oneArgumentIsUsedAsSpecOther = true;
            }
            if (oneArgumentIsUsedAsSpecOther) {
                node->clearFlags(NodeMustGenerate);
                break;
            }

            if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
                fixEdge<ObjectUse>(node->child1());
                fixEdge<ObjectOrOtherUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
                fixEdge<ObjectOrOtherUse>(node->child1());
                fixEdge<ObjectUse>(node->child2());
                node->clearFlags(NodeMustGenerate);
                break;
            }

            break;
        }
            
        case CompareStrictEq:
        case SameValue: {
            fixupCompareStrictEqAndSameValue(node);
            break;
        }

        case StringFromCharCode:
            if (node->child1()->shouldSpeculateInt32()) {
                fixEdge<Int32Use>(node->child1());
                node->clearFlags(NodeMustGenerate);
            } else
                fixEdge<UntypedUse>(node->child1());
            break;

        case StringCharAt:
        case StringCharCodeAt:
        case StringCodePointAt: {
            // Currently we have no good way of refining these.
            ASSERT(node->arrayMode() == ArrayMode(Array::String, Array::Read));
            blessArrayOperation(node->child1(), node->child2(), node->child3());
            fixEdge<KnownStringUse>(node->child1());
            fixEdge<Int32Use>(node->child2());
            break;
        }

        case GetByVal: {
            if (!node->prediction()) {
                m_insertionSet.insertNode(
                    m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
            }
            
            node->setArrayMode(
                node->arrayMode().refine(
                    m_graph, node,
                    m_graph.varArgChild(node, 0)->prediction(),
                    m_graph.varArgChild(node, 1)->prediction(),
                    SpecNone));
            
            blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
            
            ArrayMode arrayMode = node->arrayMode();
            switch (arrayMode.type()) {
            case Array::Contiguous:
            case Array::Double:
                if (arrayMode.isJSArrayWithOriginalStructure() && arrayMode.speculation() == Array::InBounds) {
                    // Check if SaneChain will work on a per-type basis. Note that:
                    //
                    // 1) We don't want double arrays to sometimes return undefined, since
                    // that would require a change to the return type and it would pessimise
                    // things a lot. So, we'd only want to do that if we actually had
                    // evidence that we could read from a hole. That's pretty annoying.
                    // Likely the best way to handle that case is with an equivalent of
                    // SaneChain for OutOfBounds. For now we just detect when Undefined and
                    // NaN are indistinguishable according to backwards propagation, and just
                    // use SaneChain in that case. This happens to catch a lot of cases.
                    //
                    // 2) We don't want int32 array loads to have to do a hole check just to
                    // coerce to Undefined, since that would mean twice the checks.
                    //
                    // This has two implications. First, we have to do more checks than we'd
                    // like. It's unfortunate that we have to do the hole check. Second,
                    // some accesses that hit a hole will now need to take the full-blown
                    // out-of-bounds slow path. We can fix that with:
                    // https://bugs.webkit.org/show_bug.cgi?id=144668
                    
                    bool canDoSaneChain = false;
                    switch (arrayMode.type()) {
                    case Array::Contiguous:
                        // This is happens to be entirely natural. We already would have
                        // returned any JSValue, and now we'll return Undefined. We still do
                        // the check but it doesn't require taking any kind of slow path.
                        canDoSaneChain = true;
                        break;
                        
                    case Array::Double:
                        if (!(node->flags() & NodeBytecodeUsesAsOther)) {
                            // Holes look like NaN already, so if the user doesn't care
                            // about the difference between Undefined and NaN then we can
                            // do this.
                            canDoSaneChain = true;
                        }
                        break;
                        
                    default:
                        break;
                    }
                    
                    if (canDoSaneChain)
                        setSaneChainIfPossible(node);
                }
                break;
                
            case Array::String:
                if ((node->prediction() & ~SpecString)
                    || m_graph.hasExitSite(node->origin.semantic, OutOfBounds))
                    node->setArrayMode(arrayMode.withSpeculation(Array::OutOfBounds));
                break;
                
            default:
                break;
            }
            
            arrayMode = node->arrayMode();
            switch (arrayMode.type()) {
            case Array::SelectUsingPredictions:
            case Array::Unprofiled:
                RELEASE_ASSERT_NOT_REACHED();
                break;
            case Array::Generic:
                if (m_graph.varArgChild(node, 0)->shouldSpeculateObject()) {
                    if (m_graph.varArgChild(node, 1)->shouldSpeculateString()) {
                        fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
                        fixEdge<StringUse>(m_graph.varArgChild(node, 1));
                        break;
                    }

                    if (m_graph.varArgChild(node, 1)->shouldSpeculateSymbol()) {
                        fixEdge<ObjectUse>(m_graph.varArgChild(node, 0));
                        fixEdge<SymbolUse>(m_graph.varArgChild(node, 1));
                        break;
                    }
                }
#if USE(JSVALUE32_64)
                fixEdge<CellUse>(m_graph.varArgChild(node, 0)); // Speculating cell due to register pressure on 32-bit.
#endif
                break;
            case Array::ForceExit:
                break;
            case Array::String:
                fixEdge<KnownStringUse>(m_graph.varArgChild(node, 0));
                fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
                break;
            default:
                fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
                fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
                break;
            }
            
            switch (arrayMode.type()) {
            case Array::Double:
                if (!arrayMode.isOutOfBounds())
                    node->setResult(NodeResultDouble);
                break;
                
            case Array::Float32Array:
            case Array::Float64Array:
                node->setResult(NodeResultDouble);
                break;
                
            case Array::Uint32Array:
                if (node->shouldSpeculateInt32())
                    break;
                if (node->shouldSpeculateInt52())
                    node->setResult(NodeResultInt52);
                else
                    node->setResult(NodeResultDouble);
                break;
                
            default:
                break;
            }
            
            break;
        }

        case PutByValDirect:
        case PutByVal:
        case PutByValAlias: {
            Edge& child1 = m_graph.varArgChild(node, 0);
            Edge& child2 = m_graph.varArgChild(node, 1);
            Edge& child3 = m_graph.varArgChild(node, 2);

            node->setArrayMode(
                node->arrayMode().refine(
                    m_graph, node,
                    child1->prediction(),
                    child2->prediction(),
                    child3->prediction()));
            
            blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
            
            switch (node->arrayMode().modeForPut().type()) {
            case Array::SelectUsingPredictions:
            case Array::SelectUsingArguments:
            case Array::Unprofiled:
            case Array::Undecided:
                RELEASE_ASSERT_NOT_REACHED();
                break;
            case Array::ForceExit:
            case Array::Generic:
                if (child1->shouldSpeculateCell()) {
                    if (child2->shouldSpeculateString()) {
                        fixEdge<CellUse>(child1);
                        fixEdge<StringUse>(child2);
                        break;
                    }

                    if (child2->shouldSpeculateSymbol()) {
                        fixEdge<CellUse>(child1);
                        fixEdge<SymbolUse>(child2);
                        break;
                    }
                }
#if USE(JSVALUE32_64)
                // Due to register pressure on 32-bit, we speculate cell and
                // ignore the base-is-not-cell case entirely by letting the
                // baseline JIT handle it.
                fixEdge<CellUse>(child1);
#endif
                break;
            case Array::Int32:
                fixEdge<KnownCellUse>(child1);
                fixEdge<Int32Use>(child2);
                fixEdge<Int32Use>(child3);
                break;
            case Array::Double:
                fixEdge<KnownCellUse>(child1);
                fixEdge<Int32Use>(child2);
                fixEdge<DoubleRepRealUse>(child3);
                break;
            case Array::Int8Array:
            case Array::Int16Array:
            case Array::Int32Array:
            case Array::Uint8Array:
            case Array::Uint8ClampedArray:
            case Array::Uint16Array:
            case Array::Uint32Array:
                fixEdge<KnownCellUse>(child1);
                fixEdge<Int32Use>(child2);
                if (child3->shouldSpeculateInt32())
                    fixIntOrBooleanEdge(child3);
                else if (child3->shouldSpeculateInt52())
                    fixEdge<Int52RepUse>(child3);
                else
                    fixDoubleOrBooleanEdge(child3);
                break;
            case Array::Float32Array:
            case Array::Float64Array:
                fixEdge<KnownCellUse>(child1);
                fixEdge<Int32Use>(child2);
                fixDoubleOrBooleanEdge(child3);
                break;
            case Array::Contiguous:
            case Array::ArrayStorage:
            case Array::SlowPutArrayStorage:
                fixEdge<KnownCellUse>(child1);
                fixEdge<Int32Use>(child2);
                speculateForBarrier(child3);
                break;
            default:
                fixEdge<KnownCellUse>(child1);
                fixEdge<Int32Use>(child2);
                break;
            }
            break;
        }
            
        case AtomicsAdd:
        case AtomicsAnd:
        case AtomicsCompareExchange:
        case AtomicsExchange:
        case AtomicsLoad:
        case AtomicsOr:
        case AtomicsStore:
        case AtomicsSub:
        case AtomicsXor: {
            Edge& base = m_graph.child(node, 0);
            Edge& index = m_graph.child(node, 1);
            
            bool badNews = false;
            for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
                Edge& child = m_graph.child(node, 2 + i);
                // NOTE: DFG is not smart enough to handle double->int conversions in atomics. So, we
                // just call the function when that happens. But the FTL is totally cool with those
                // conversions.
                if (!child->shouldSpeculateInt32()
                    && !child->shouldSpeculateInt52()
                    && !(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL()))
                    badNews = true;
            }
            
            if (badNews) {
                node->setArrayMode(ArrayMode(Array::Generic, node->arrayMode().action()));
                break;
            }
            
            node->setArrayMode(
                node->arrayMode().refine(
                    m_graph, node, base->prediction(), index->prediction()));
            
            if (node->arrayMode().type() == Array::Generic)
                break;
            
            for (unsigned i = numExtraAtomicsArgs(node->op()); i--;) {
                Edge& child = m_graph.child(node, 2 + i);
                if (child->shouldSpeculateInt32())
                    fixIntOrBooleanEdge(child);
                else if (child->shouldSpeculateInt52())
                    fixEdge<Int52RepUse>(child);
                else {
                    RELEASE_ASSERT(child->shouldSpeculateNumberOrBoolean() && m_graph.m_plan.isFTL());
                    fixDoubleOrBooleanEdge(child);
                }
            }
            
            blessArrayOperation(base, index, m_graph.child(node, 2 + numExtraAtomicsArgs(node->op())));
            fixEdge<CellUse>(base);
            fixEdge<Int32Use>(index);
            
            if (node->arrayMode().type() == Array::Uint32Array) {
                // NOTE: This means basically always doing Int52.
                if (node->shouldSpeculateInt52())
                    node->setResult(NodeResultInt52);
                else
                    node->setResult(NodeResultDouble);
            }
            break;
        }
            
        case AtomicsIsLockFree:
            if (node->child1()->shouldSpeculateInt32())
                fixIntOrBooleanEdge(node->child1());
            break;
            
        case ArrayPush: {
            // May need to refine the array mode in case the value prediction contravenes
            // the array prediction. For example, we may have evidence showing that the
            // array is in Int32 mode, but the value we're storing is likely to be a double.
            // Then we should turn this into a conversion to Double array followed by the
            // push. On the other hand, we absolutely don't want to refine based on the
            // base prediction. If it has non-cell garbage in it, then we want that to be
            // ignored. That's because ArrayPush can't handle any array modes that aren't
            // array-related - so if refine() turned this into a "Generic" ArrayPush then
            // that would break things.
            Edge& storageEdge = m_graph.varArgChild(node, 0);
            Edge& arrayEdge = m_graph.varArgChild(node, 1);
            unsigned elementOffset = 2;
            unsigned elementCount = node->numChildren() - elementOffset;
            for (unsigned i = 0; i < elementCount; ++i) {
                Edge& element = m_graph.varArgChild(node, i + elementOffset);
                node->setArrayMode(
                    node->arrayMode().refine(
                        m_graph, node,
                        arrayEdge->prediction() & SpecCell,
                        SpecInt32Only,
                        element->prediction()));
            }
            blessArrayOperation(arrayEdge, Edge(), storageEdge);
            fixEdge<KnownCellUse>(arrayEdge);

            // Convert `array.push()` to GetArrayLength.
            if (!elementCount && node->arrayMode().supportsSelfLength()) {
                node->setOpAndDefaultFlags(GetArrayLength);
                node->child1() = arrayEdge;
                node->child2() = storageEdge;
                fixEdge<KnownCellUse>(node->child1());
                break;
            }

            // We do not want to perform osr exit and retry for ArrayPush. We insert Check with appropriate type,
            // and ArrayPush uses the edge as known typed edge. Therefore, ArrayPush do not need to perform type checks.
            for (unsigned i = 0; i < elementCount; ++i) {
                Edge& element = m_graph.varArgChild(node, i + elementOffset);
                switch (node->arrayMode().type()) {
                case Array::Int32:
                    fixEdge<Int32Use>(element);
                    break;
                case Array::Double:
                    fixEdge<DoubleRepRealUse>(element);
                    break;
                case Array::Contiguous:
                case Array::ArrayStorage:
                    speculateForBarrier(element);
                    break;
                default:
                    break;
                }
            }
            break;
        }
            
        case ArrayPop: {
            blessArrayOperation(node->child1(), Edge(), node->child2());
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case ArraySlice: {
            fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
            if (node->numChildren() >= 3) {
                fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
                if (node->numChildren() == 4)
                    fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
            }
            break;
        }

        case ArrayIndexOf:
            fixupArrayIndexOf(node);
            break;
            
        case RegExpExec:
        case RegExpTest: {
            fixEdge<KnownCellUse>(node->child1());
            
            if (node->child2()->shouldSpeculateRegExpObject()) {
                fixEdge<RegExpObjectUse>(node->child2());

                if (node->child3()->shouldSpeculateString())
                    fixEdge<StringUse>(node->child3());
            }
            break;
        }

        case RegExpMatchFast: {
            fixEdge<KnownCellUse>(node->child1());
            fixEdge<RegExpObjectUse>(node->child2());
            fixEdge<StringUse>(node->child3());
            break;
        }

        case StringReplace:
        case StringReplaceRegExp: {
            if (node->child2()->shouldSpeculateString()) {
                m_insertionSet.insertNode(
                    m_indexInBlock, SpecNone, Check, node->origin,
                    Edge(node->child2().node(), StringUse));
                fixEdge<StringUse>(node->child2());
            } else if (op == StringReplace) {
                if (node->child2()->shouldSpeculateRegExpObject())
                    addStringReplacePrimordialChecks(node->child2().node());
                else 
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
            }

            if (node->child1()->shouldSpeculateString()
                && node->child2()->shouldSpeculateRegExpObject()
                && node->child3()->shouldSpeculateString()) {

                fixEdge<StringUse>(node->child1());
                fixEdge<RegExpObjectUse>(node->child2());
                fixEdge<StringUse>(node->child3());
                break;
            }
            break;
        }
            
        case Branch: {
            if (node->child1()->shouldSpeculateBoolean()) {
                if (node->child1()->result() == NodeResultBoolean) {
                    // This is necessary in case we have a bytecode instruction implemented by:
                    //
                    // a: CompareEq(...)
                    // b: Branch(@a)
                    //
                    // In that case, CompareEq might have a side-effect. Then, we need to make
                    // sure that we know that Branch does not exit.
                    fixEdge<KnownBooleanUse>(node->child1());
                } else
                    fixEdge<BooleanUse>(node->child1());
            } else if (node->child1()->shouldSpeculateObjectOrOther())
                fixEdge<ObjectOrOtherUse>(node->child1());
            else if (node->child1()->shouldSpeculateInt32OrBoolean())
                fixIntOrBooleanEdge(node->child1());
            else if (node->child1()->shouldSpeculateNumber())
                fixEdge<DoubleRepUse>(node->child1());
            else if (node->child1()->shouldSpeculateString())
                fixEdge<StringUse>(node->child1());
            else if (node->child1()->shouldSpeculateStringOrOther())
                fixEdge<StringOrOtherUse>(node->child1());
            else {
                WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
                if (masqueradesAsUndefinedWatchpoint->isStillValid())
                    m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
            }
            break;
        }
            
        case Switch: {
            SwitchData* data = node->switchData();
            switch (data->kind) {
            case SwitchImm:
                if (node->child1()->shouldSpeculateInt32())
                    fixEdge<Int32Use>(node->child1());
                break;
            case SwitchChar:
                if (node->child1()->shouldSpeculateString())
                    fixEdge<StringUse>(node->child1());
                break;
            case SwitchString:
                if (node->child1()->shouldSpeculateStringIdent())
                    fixEdge<StringIdentUse>(node->child1());
                else if (node->child1()->shouldSpeculateString())
                    fixEdge<StringUse>(node->child1());
                break;
            case SwitchCell:
                if (node->child1()->shouldSpeculateCell())
                    fixEdge<CellUse>(node->child1());
                // else it's fine for this to have UntypedUse; we will handle this by just making
                // non-cells take the default case.
                break;
            }
            break;
        }
            
        case ToPrimitive: {
            fixupToPrimitive(node);
            break;
        }

        case ToPropertyKey: {
            if (node->child1()->shouldSpeculateString()) {
                fixEdge<StringUse>(node->child1());
                node->convertToIdentity();

                return;
            }

            if (node->child1()->shouldSpeculateSymbol()) {
                fixEdge<SymbolUse>(node->child1());
                node->convertToIdentity();
                return;
            }

            if (node->child1()->shouldSpeculateStringObject()
                && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
                addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, node->child1().node());
                fixEdge<StringObjectUse>(node->child1());
                node->convertToToString();
                return;
            }

            if (node->child1()->shouldSpeculateStringOrStringObject()
                && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
                addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, node->child1().node());
                fixEdge<StringOrStringObjectUse>(node->child1());
                node->convertToToString();
                return;
            }
            break;
        }

        case ToNumber: {
            fixupToNumber(node);
            break;
        }

        case ToNumeric: {
            fixupToNumeric(node);
            break;
        }
            
        case ToString:
        case CallStringConstructor: {
            fixupToStringOrCallStringConstructor(node);
            break;
        }
            
        case NewStringObject: {
            fixEdge<KnownStringUse>(node->child1());
            break;
        }

        case NewSymbol: {
            if (node->child1())
                fixEdge<KnownStringUse>(node->child1());
            break;
        }

        case NewArrayWithSpread: {
            watchHavingABadTime(node);
            
            BitVector* bitVector = node->bitVector();
            for (unsigned i = node->numChildren(); i--;) {
                if (bitVector->get(i))
                    fixEdge<KnownCellUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
                else
                    fixEdge<UntypedUse>(m_graph.m_varArgChildren[node->firstChild() + i]);
            }

            break;
        }

        case Spread: {
            // Note: We care about performing the protocol on our child's global object, not necessarily ours.
            
            watchHavingABadTime(node->child1().node());

            JSGlobalObject* globalObject = m_graph.globalObjectFor(node->child1()->origin.semantic);
            // When we go down the fast path, we don't consult the prototype chain, so we must prove
            // that it doesn't contain any indexed properties, and that any holes will result in
            // jsUndefined().
            Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
            Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
            if (node->child1()->shouldSpeculateArray()
                && arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
                && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
                && globalObject->arrayPrototypeChainIsSane()
                && m_graph.isWatchingArrayIteratorProtocolWatchpoint(node->child1().node())
                && m_graph.isWatchingHavingABadTimeWatchpoint(node->child1().node())) {
                m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
                m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
                fixEdge<ArrayUse>(node->child1());
            } else
                fixEdge<CellUse>(node->child1());
            break;
        }
            
        case NewArray: {
            watchHavingABadTime(node);
            
            for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
                node->setIndexingType(
                    leastUpperBoundOfIndexingTypeAndType(
                        node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
            }
            switch (node->indexingType()) {
            case ALL_BLANK_INDEXING_TYPES:
                CRASH();
                break;
            case ALL_UNDECIDED_INDEXING_TYPES:
                if (node->numChildren()) {
                    // This will only happen if the children have no type predictions. We
                    // would have already exited by now, but insert a forced exit just to
                    // be safe.
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
                }
                break;
            case ALL_INT32_INDEXING_TYPES:
                for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
                    fixEdge<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
                break;
            case ALL_DOUBLE_INDEXING_TYPES:
                for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
                    fixEdge<DoubleRepRealUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
                break;
            case ALL_CONTIGUOUS_INDEXING_TYPES:
            case ALL_ARRAY_STORAGE_INDEXING_TYPES:
                break;
            default:
                CRASH();
                break;
            }
            break;
        }
            
        case NewTypedArray: {
            watchHavingABadTime(node);
            
            if (node->child1()->shouldSpeculateInt32()) {
                fixEdge<Int32Use>(node->child1());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            break;
        }
            
        case NewArrayWithSize: {
            watchHavingABadTime(node);
            fixEdge<Int32Use>(node->child1());
            break;
        }

        case NewArrayBuffer: {
            watchHavingABadTime(node);
            break;
        }

        case ToObject: {
            fixupToObject(node);
            break;
        }

        case CallObjectConstructor: {
            fixupCallObjectConstructor(node);
            break;
        }

        case ToThis: {
            fixupToThis(node);
            break;
        }
            
        case PutStructure: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }
            
        case GetClosureVar:
        case GetFromArguments:
        case GetInternalField: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case PutClosureVar:
        case PutToArguments:
        case PutInternalField: {
            fixEdge<KnownCellUse>(node->child1());
            speculateForBarrier(node->child2());
            break;
        }

        case SkipScope:
        case GetScope:
        case GetGetter:
        case GetSetter:
        case GetGlobalObject: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }
            
        case AllocatePropertyStorage:
        case ReallocatePropertyStorage: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }
            
        case NukeStructureAndSetButterfly: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case TryGetById: {
            if (node->child1()->shouldSpeculateCell())
                fixEdge<CellUse>(node->child1());
            break;
        }

        case GetByIdDirect:
        case GetByIdDirectFlush: {
            if (node->child1()->shouldSpeculateCell())
                fixEdge<CellUse>(node->child1());
            break;
        }

        case DeleteByVal: {
#if USE(JSVALUE64)
            if (node->child1()->shouldSpeculateCell()) {
                fixEdge<CellUse>(node->child1());
                if (node->child2()->shouldSpeculateCell())
                    fixEdge<CellUse>(node->child2());
            }
#endif
            break;
        }

        case DeleteById: {
#if USE(JSVALUE64)
            if (node->child1()->shouldSpeculateCell())
                fixEdge<CellUse>(node->child1());
#endif
            break;
        }

        case GetById:
        case GetByIdFlush: {
            // FIXME: This should be done in the ByteCodeParser based on reading the
            // PolymorphicAccess, which will surely tell us that this is a AccessCase::ArrayLength.
            // https://bugs.webkit.org/show_bug.cgi?id=154990
            auto uid = m_graph.identifiers()[node->identifierNumber()];
            if (node->child1()->shouldSpeculateCellOrOther()
                && !m_graph.hasExitSite(node->origin.semantic, BadType)
                && !m_graph.hasExitSite(node->origin.semantic, BadCache)
                && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
                && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
                
                if (uid == vm().propertyNames->length.impl()) {
                    attemptToMakeGetArrayLength(node);
                    break;
                }

                if (uid == vm().propertyNames->lastIndex.impl()
                    && node->child1()->shouldSpeculateRegExpObject()) {
                    node->setOp(GetRegExpObjectLastIndex);
                    node->clearFlags(NodeMustGenerate);
                    fixEdge<RegExpObjectUse>(node->child1());
                    break;
                }
            }

            if (node->child1()->shouldSpeculateNumber()) {
                if (uid == vm().propertyNames->toString.impl()) {
                    if (m_graph.isWatchingNumberToStringWatchpoint(node)) {
                        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
                        if (node->child1()->shouldSpeculateInt32()) {
                            insertCheck<Int32Use>(node->child1().node());
                            m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
                            break;
                        }

                        if (node->child1()->shouldSpeculateInt52()) {
                            insertCheck<Int52RepUse>(node->child1().node());
                            m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
                            break;
                        }

                        ASSERT(node->child1()->shouldSpeculateNumber());
                        insertCheck<DoubleRepUse>(node->child1().node());
                        m_graph.convertToConstant(node, m_graph.freeze(globalObject->numberProtoToStringFunction()));
                        break;
                    }
                }
            }

            if (node->child1()->shouldSpeculateCell())
                fixEdge<CellUse>(node->child1());
            break;
        }
        
        case GetByIdWithThis: {
            if (node->child1()->shouldSpeculateCell() && node->child2()->shouldSpeculateCell()) {
                fixEdge<CellUse>(node->child1());
                fixEdge<CellUse>(node->child2());
            }
            break;
        }

        case PutById:
        case PutByIdFlush:
        case PutByIdDirect: {
            if (node->child1()->shouldSpeculateCellOrOther()
                && !m_graph.hasExitSite(node->origin.semantic, BadType)
                && !m_graph.hasExitSite(node->origin.semantic, BadCache)
                && !m_graph.hasExitSite(node->origin.semantic, BadIndexingType)
                && !m_graph.hasExitSite(node->origin.semantic, ExoticObjectMode)) {
                
                auto uid = m_graph.identifiers()[node->identifierNumber()];
                
                if (uid == vm().propertyNames->lastIndex.impl()
                    && node->child1()->shouldSpeculateRegExpObject()) {
                    node->convertToSetRegExpObjectLastIndex();
                    fixEdge<RegExpObjectUse>(node->child1());
                    speculateForBarrier(node->child2());
                    break;
                }
            }
            
            fixEdge<CellUse>(node->child1());
            break;
        }

        case PutGetterById:
        case PutSetterById: {
            fixEdge<KnownCellUse>(node->child1());
            fixEdge<KnownCellUse>(node->child2());
            break;
        }

        case PutGetterSetterById: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case PutGetterByVal:
        case PutSetterByVal: {
            fixEdge<KnownCellUse>(node->child1());
            fixEdge<KnownCellUse>(node->child3());
            break;
        }

        case GetExecutable: {
            fixEdge<FunctionUse>(node->child1());
            break;
        }

        case OverridesHasInstance:
        case CheckStructure:
        case CheckCell:
        case CreateThis:
        case CreatePromise:
        case CreateGenerator:
        case CreateAsyncGenerator:
        case GetButterfly: {
            fixEdge<CellUse>(node->child1());
            break;
        }

        case ObjectCreate: {
            if (node->child1()->shouldSpeculateObject()) {
                fixEdge<ObjectUse>(node->child1());
                node->clearFlags(NodeMustGenerate);
                break;
            }
            break;
        }

        case ObjectKeys: {
            if (node->child1()->shouldSpeculateObject()) {
                watchHavingABadTime(node);
                fixEdge<ObjectUse>(node->child1());
            }
            break;
        }

        case CheckIdent: {
            if (node->uidOperand()->isSymbol())
                fixEdge<SymbolUse>(node->child1());
            else
                fixEdge<StringIdentUse>(node->child1());
            break;
        }
            
        case Arrayify:
        case ArrayifyToStructure: {
            fixEdge<CellUse>(node->child1());
            if (node->child2())
                fixEdge<Int32Use>(node->child2());
            break;
        }
            
        case GetByOffset:
        case GetGetterSetterByOffset: {
            if (!node->child1()->hasStorageResult())
                fixEdge<KnownCellUse>(node->child1());
            fixEdge<KnownCellUse>(node->child2());
            break;
        }
            
        case MultiGetByOffset: {
            fixEdge<CellUse>(node->child1());
            break;
        }
            
        case PutByOffset: {
            if (!node->child1()->hasStorageResult())
                fixEdge<KnownCellUse>(node->child1());
            fixEdge<KnownCellUse>(node->child2());
            speculateForBarrier(node->child3());
            break;
        }
            
        case MultiPutByOffset: {
            fixEdge<CellUse>(node->child1());
            break;
        }
            
        case MatchStructure: {
            // FIXME: Introduce a variant of MatchStructure that doesn't do a cell check.
            // https://bugs.webkit.org/show_bug.cgi?id=185784
            fixEdge<CellUse>(node->child1());
            break;
        }
            
        case InstanceOf: {
            if (node->child1()->shouldSpeculateCell()
                && node->child2()->shouldSpeculateCell()
                && is64Bit()) {
                fixEdge<CellUse>(node->child1());
                fixEdge<CellUse>(node->child2());
                break;
            }
            break;
        }

        case InstanceOfCustom:
            fixEdge<CellUse>(node->child2());
            break;

        case InById: {
            fixEdge<CellUse>(node->child1());
            break;
        }

        case InByVal: {
            if (node->child2()->shouldSpeculateInt32()) {
                convertToHasIndexedProperty(node);
                break;
            }

            fixEdge<CellUse>(node->child1());
            break;
        }

        case HasOwnProperty: {
            fixEdge<ObjectUse>(node->child1());
            if (node->child2()->shouldSpeculateString())
                fixEdge<StringUse>(node->child2());
            else if (node->child2()->shouldSpeculateSymbol())
                fixEdge<SymbolUse>(node->child2());
            else
                fixEdge<UntypedUse>(node->child2());
            break;
        }

        case CheckVarargs:
        case Check: {
            m_graph.doToChildren(
                node,
                [&] (Edge& edge) {
                    switch (edge.useKind()) {
                    case NumberUse:
                        if (edge->shouldSpeculateInt32ForArithmetic())
                            edge.setUseKind(Int32Use);
                        break;
                    default:
                        break;
                    }
                    observeUseKindOnEdge(edge);
                });
            break;
        }

        case Phantom:
            // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
            node->remove(m_graph);
            break;

        case FiatInt52: {
            RELEASE_ASSERT(enableInt52());
            node->convertToIdentity();
            fixEdge<Int52RepUse>(node->child1());
            node->setResult(NodeResultInt52);
            break;
        }

        case GetArrayLength: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case GetTypedArrayByteOffset: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case CompareBelow:
        case CompareBelowEq: {
            fixEdge<Int32Use>(node->child1());
            fixEdge<Int32Use>(node->child2());
            break;
        }

        case GetPrototypeOf: {
            fixupGetPrototypeOf(node);
            break;
        }

        case CheckNeutered:
        case CheckArray: {
            fixEdge<CellUse>(node->child1());
            break;
        }

        case Phi:
        case Upsilon:
        case EntrySwitch:
        case GetIndexedPropertyStorage:
        case LastNodeType:
        case CheckTierUpInLoop:
        case CheckTierUpAtReturn:
        case CheckTierUpAndOSREnter:
        case CheckInBounds:
        case ConstantStoragePointer:
        case DoubleAsInt32:
        case ValueToInt32:
        case DoubleRep:
        case ValueRep:
        case Int52Rep:
        case Int52Constant:
        case Identity: // This should have been cleaned up.
        case BooleanToNumber:
        case PhantomNewObject:
        case PhantomNewFunction:
        case PhantomNewGeneratorFunction:
        case PhantomNewAsyncGeneratorFunction:
        case PhantomNewAsyncFunction:
        case PhantomNewArrayIterator:
        case PhantomCreateActivation:
        case PhantomDirectArguments:
        case PhantomCreateRest:
        case PhantomSpread:
        case PhantomNewArrayWithSpread:
        case PhantomNewArrayBuffer:
        case PhantomClonedArguments:
        case PhantomNewRegexp:
        case GetMyArgumentByVal:
        case GetMyArgumentByValOutOfBounds:
        case GetVectorLength:
        case PutHint:
        case CheckStructureImmediate:
        case CheckStructureOrEmpty:
        case CheckArrayOrEmpty:
        case MaterializeNewObject:
        case MaterializeCreateActivation:
        case MaterializeNewInternalFieldObject:
        case PutStack:
        case KillStack:
        case GetStack:
        case StoreBarrier:
        case FencedStoreBarrier:
        case GetRegExpObjectLastIndex:
        case SetRegExpObjectLastIndex:
        case RecordRegExpCachedResult:
        case RegExpExecNonGlobalOrSticky:
        case RegExpMatchFastGlobal:
            // These are just nodes that we don't currently expect to see during fixup.
            // If we ever wanted to insert them prior to fixup, then we just have to create
            // fixup rules for them.
            DFG_CRASH(m_graph, node, "Unexpected node during fixup");
            break;

        case PutGlobalVariable: {
            fixEdge<CellUse>(node->child1());
            speculateForBarrier(node->child2());
            break;
        }

        case IsObject:
            if (node->child1()->shouldSpeculateObject()) {
                m_insertionSet.insertNode(
                    m_indexInBlock, SpecNone, Check, node->origin,
                    Edge(node->child1().node(), ObjectUse));
                m_graph.convertToConstant(node, jsBoolean(true));
                observeUseKindOnNode<ObjectUse>(node);
            }
            break;

        case IsCellWithType: {
            fixupIsCellWithType(node);
            break;
        }

        case GetEnumerableLength: {
            fixEdge<CellUse>(node->child1());
            break;
        }
        case HasGenericProperty: {
            fixEdge<CellUse>(node->child2());
            break;
        }
        case HasStructureProperty: {
            fixEdge<StringUse>(node->child2());
            fixEdge<KnownCellUse>(node->child3());
            break;
        }
        case HasIndexedProperty: {
            node->setArrayMode(
                node->arrayMode().refine(
                    m_graph, node,
                    m_graph.varArgChild(node, 0)->prediction(),
                    m_graph.varArgChild(node, 1)->prediction(),
                    SpecNone));
            
            blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
            fixEdge<CellUse>(m_graph.varArgChild(node, 0));
            fixEdge<Int32Use>(m_graph.varArgChild(node, 1));

            ArrayMode arrayMode = node->arrayMode();
            // FIXME: OutOfBounds shouldn't preclude going sane chain because OOB is just false and cannot have effects.
            // See: https://bugs.webkit.org/show_bug.cgi?id=209456
            if (arrayMode.isJSArrayWithOriginalStructure() && arrayMode.speculation() == Array::InBounds)
                setSaneChainIfPossible(node);
            break;
        }
        case GetDirectPname: {
            Edge& base = m_graph.varArgChild(node, 0);
            Edge& property = m_graph.varArgChild(node, 1);
            Edge& index = m_graph.varArgChild(node, 2);
            Edge& enumerator = m_graph.varArgChild(node, 3);
            fixEdge<CellUse>(base);
            fixEdge<KnownCellUse>(property);
            fixEdge<Int32Use>(index);
            fixEdge<KnownCellUse>(enumerator);
            break;
        }
        case GetPropertyEnumerator: {
            if (node->child1()->shouldSpeculateCell())
                fixEdge<CellUse>(node->child1());
            break;
        }
        case GetEnumeratorStructurePname: {
            fixEdge<KnownCellUse>(node->child1());
            fixEdge<Int32Use>(node->child2());
            break;
        }
        case GetEnumeratorGenericPname: {
            fixEdge<KnownCellUse>(node->child1());
            fixEdge<Int32Use>(node->child2());
            break;
        }
        case ToIndexString: {
            fixEdge<Int32Use>(node->child1());
            break;
        }
        case ProfileType: {
            // We want to insert type checks based on the instructionTypeSet of the TypeLocation, not the globalTypeSet.
            // Because the instructionTypeSet is contained in globalTypeSet, if we produce a type check for
            // type T for the instructionTypeSet, the global type set must also have information for type T.
            // So if it the type check succeeds for type T in the instructionTypeSet, a type check for type T 
            // in the globalTypeSet would've also succeeded.
            // (The other direction does not hold in general).

            RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
            RuntimeTypeMask seenTypes = typeSet->seenTypes();
            if (typeSet->doesTypeConformTo(TypeAnyInt)) {
                if (node->child1()->shouldSpeculateInt32()) {
                    fixEdge<Int32Use>(node->child1());
                    node->remove(m_graph);
                    break;
                }

                if (enableInt52()) {
                    fixEdge<AnyIntUse>(node->child1());
                    node->remove(m_graph);
                    break;
                }

                // Must not perform fixEdge<NumberUse> here since the type set only includes TypeAnyInt. Double values should be logged.
            }

            if (typeSet->doesTypeConformTo(TypeNumber | TypeAnyInt)) {
                fixEdge<NumberUse>(node->child1());
                node->remove(m_graph);
            } else if (typeSet->doesTypeConformTo(TypeString)) {
                fixEdge<StringUse>(node->child1());
                node->remove(m_graph);
            } else if (typeSet->doesTypeConformTo(TypeBoolean)) {
                fixEdge<BooleanUse>(node->child1());
                node->remove(m_graph);
            } else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
                fixEdge<OtherUse>(node->child1());
                node->remove(m_graph);
            } else if (typeSet->doesTypeConformTo(TypeObject)) {
                StructureSet set;
                {
                    ConcurrentJSLocker locker(typeSet->m_lock);
                    set = typeSet->structureSet(locker);
                }
                if (!set.isEmpty()) {
                    fixEdge<CellUse>(node->child1());
                    node->convertToCheckStructureOrEmpty(m_graph.addStructureSet(set));
                }
            }

            break;
        }

        case CreateClonedArguments: {
            watchHavingABadTime(node);
            break;
        }

        case CreateScopedArguments:
        case CreateActivation:
        case NewFunction:
        case NewGeneratorFunction:
        case NewAsyncGeneratorFunction:
        case NewAsyncFunction: {
            // Child 1 is always the current scope, which is guaranteed to be an object
            // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case PushWithScope: {
            // Child 1 is always the current scope, which is guaranteed to be an object
            // FIXME: should be KnownObjectUse once that exists (https://bugs.webkit.org/show_bug.cgi?id=175689)
            fixEdge<KnownCellUse>(node->child1());
            if (node->child2()->shouldSpeculateObject())
                fixEdge<ObjectUse>(node->child2());
            break;
        }

        case SetFunctionName: {
            // The first child is guaranteed to be a cell because op_set_function_name is only used
            // on a newly instantiated function object (the first child).
            fixEdge<KnownCellUse>(node->child1());
            fixEdge<UntypedUse>(node->child2());
            break;
        }

        case CreateRest: {
            watchHavingABadTime(node);
            fixEdge<Int32Use>(node->child1());
            break;
        }

        case ResolveScopeForHoistingFuncDeclInEval: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }
        case ResolveScope:
        case GetDynamicVar:
        case PutDynamicVar: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }

        case LogShadowChickenPrologue: {
            fixEdge<KnownCellUse>(node->child1());
            break;
        }
        case LogShadowChickenTail: {
            fixEdge<UntypedUse>(node->child1());
            fixEdge<KnownCellUse>(node->child2());
            break;
        }

        case GetMapBucket:
            if (node->child1().useKind() == MapObjectUse)
                fixEdge<MapObjectUse>(node->child1());
            else if (node->child1().useKind() == SetObjectUse)
                fixEdge<SetObjectUse>(node->child1());
            else
                RELEASE_ASSERT_NOT_REACHED();

#if USE(JSVALUE64)
            if (node->child2()->shouldSpeculateBoolean())
                fixEdge<BooleanUse>(node->child2());
            else if (node->child2()->shouldSpeculateInt32())
                fixEdge<Int32Use>(node->child2());
            else if (node->child2()->shouldSpeculateSymbol())
                fixEdge<SymbolUse>(node->child2());
            else if (node->child2()->shouldSpeculateObject())
                fixEdge<ObjectUse>(node->child2());
            else if (node->child2()->shouldSpeculateString())
                fixEdge<StringUse>(node->child2());
            else if (node->child2()->shouldSpeculateCell())
                fixEdge<CellUse>(node->child2());
            else
                fixEdge<UntypedUse>(node->child2());
#else
            fixEdge<UntypedUse>(node->child2());
#endif // USE(JSVALUE64)

            fixEdge<Int32Use>(node->child3());
            break;

        case GetMapBucketHead:
            if (node->child1().useKind() == MapObjectUse)
                fixEdge<MapObjectUse>(node->child1());
            else if (node->child1().useKind() == SetObjectUse)
                fixEdge<SetObjectUse>(node->child1());
            else
                RELEASE_ASSERT_NOT_REACHED();
            break;

        case GetMapBucketNext:
        case LoadKeyFromMapBucket:
        case LoadValueFromMapBucket:
            fixEdge<CellUse>(node->child1());
            break;

        case MapHash: {
#if USE(JSVALUE64)
            if (node->child1()->shouldSpeculateBoolean()) {
                fixEdge<BooleanUse>(node->child1());
                break;
            }

            if (node->child1()->shouldSpeculateInt32()) {
                fixEdge<Int32Use>(node->child1());
                break;
            }

            if (node->child1()->shouldSpeculateSymbol()) {
                fixEdge<SymbolUse>(node->child1());
                break;
            }

            if (node->child1()->shouldSpeculateObject()) {
                fixEdge<ObjectUse>(node->child1());
                break;
            }

            if (node->child1()->shouldSpeculateString()) {
                fixEdge<StringUse>(node->child1());
                break;
            }

            if (node->child1()->shouldSpeculateCell()) {
                fixEdge<CellUse>(node->child1());
                break;
            }

            fixEdge<UntypedUse>(node->child1());
#else
            fixEdge<UntypedUse>(node->child1());
#endif // USE(JSVALUE64)
            break;
        }

        case NormalizeMapKey: {
            fixupNormalizeMapKey(node);
            break;
        }

        case WeakMapGet: {
            if (node->child1().useKind() == WeakMapObjectUse)
                fixEdge<WeakMapObjectUse>(node->child1());
            else if (node->child1().useKind() == WeakSetObjectUse)
                fixEdge<WeakSetObjectUse>(node->child1());
            else
                RELEASE_ASSERT_NOT_REACHED();
            fixEdge<ObjectUse>(node->child2());
            fixEdge<Int32Use>(node->child3());
            break;
        }

        case SetAdd: {
            fixEdge<SetObjectUse>(node->child1());
            fixEdge<Int32Use>(node->child3());
            break;
        }

        case MapSet: {
            fixEdge<MapObjectUse>(m_graph.varArgChild(node, 0));
            fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
            break;
        }

        case WeakSetAdd: {
            fixEdge<WeakSetObjectUse>(node->child1());
            fixEdge<ObjectUse>(node->child2());
            fixEdge<Int32Use>(node->child3());
            break;
        }

        case WeakMapSet: {
            fixEdge<WeakMapObjectUse>(m_graph.varArgChild(node, 0));
            fixEdge<ObjectUse>(m_graph.varArgChild(node, 1));
            fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
            break;
        }

        case DefineDataProperty: {
            fixEdge<CellUse>(m_graph.varArgChild(node, 0));
            Edge& propertyEdge = m_graph.varArgChild(node, 1);
            if (propertyEdge->shouldSpeculateSymbol())
                fixEdge<SymbolUse>(propertyEdge);
            else if (propertyEdge->shouldSpeculateStringIdent())
                fixEdge<StringIdentUse>(propertyEdge);
            else if (propertyEdge->shouldSpeculateString())
                fixEdge<StringUse>(propertyEdge);
            else
                fixEdge<UntypedUse>(propertyEdge);
            fixEdge<UntypedUse>(m_graph.varArgChild(node, 2));
            fixEdge<Int32Use>(m_graph.varArgChild(node, 3));
            break;
        }

        case StringValueOf: {
            fixupStringValueOf(node);
            break;
        }

        case StringSlice: {
            fixEdge<StringUse>(node->child1());
            fixEdge<Int32Use>(node->child2());
            if (node->child3())
                fixEdge<Int32Use>(node->child3());
            break;
        }

        case ToLowerCase: {
            // We currently only support StringUse since that will ensure that
            // ToLowerCase is a pure operation. If we decide to update this with
            // more types in the future, we need to ensure that the clobberize rules
            // are correct.
            fixEdge<StringUse>(node->child1());
            break;
        }

        case NumberToStringWithRadix: {
            if (node->child1()->shouldSpeculateInt32())
                fixEdge<Int32Use>(node->child1());
            else if (node->child1()->shouldSpeculateInt52())
                fixEdge<Int52RepUse>(node->child1());
            else
                fixEdge<DoubleRepUse>(node->child1());
            fixEdge<Int32Use>(node->child2());
            break;
        }

        case DefineAccessorProperty: {
            fixEdge<CellUse>(m_graph.varArgChild(node, 0));
            Edge& propertyEdge = m_graph.varArgChild(node, 1);
            if (propertyEdge->shouldSpeculateSymbol())
                fixEdge<SymbolUse>(propertyEdge);
            else if (propertyEdge->shouldSpeculateStringIdent())
                fixEdge<StringIdentUse>(propertyEdge);
            else if (propertyEdge->shouldSpeculateString())
                fixEdge<StringUse>(propertyEdge);
            else
                fixEdge<UntypedUse>(propertyEdge);
            fixEdge<CellUse>(m_graph.varArgChild(node, 2));
            fixEdge<CellUse>(m_graph.varArgChild(node, 3));
            fixEdge<Int32Use>(m_graph.varArgChild(node, 4));
            break;
        }

        case CheckSubClass: {
            fixupCheckSubClass(node);
            break;
        }

        case CallDOMGetter: {
            DOMJIT::CallDOMGetterSnippet* snippet = node->callDOMGetterData()->snippet;
            fixEdge<CellUse>(node->child1()); // DOM.
            if (snippet && snippet->requireGlobalObject)
                fixEdge<KnownCellUse>(node->child2()); // GlobalObject.
            break;
        }

        case CallDOM: {
            fixupCallDOM(node);
            break;
        }

        case Call: {
            attemptToMakeCallDOM(node);
            break;
        }

        case ParseInt: {
            if (node->child1()->shouldSpeculateInt32() && !node->child2()) {
                fixEdge<Int32Use>(node->child1());
                node->convertToIdentity();
                break;
            }

            if (node->child1()->shouldSpeculateString()) {
                fixEdge<StringUse>(node->child1());
                node->clearFlags(NodeMustGenerate);
            }

            if (node->child2())
                fixEdge<Int32Use>(node->child2());

            break;
        }

        case IdentityWithProfile: {
            node->clearFlags(NodeMustGenerate);
            break;
        }

        case ThrowStaticError:
            fixEdge<StringUse>(node->child1());
            break;

        case NumberIsInteger:
            if (node->child1()->shouldSpeculateInt32()) {
                m_insertionSet.insertNode(
                    m_indexInBlock, SpecNone, Check, node->origin,
                    Edge(node->child1().node(), Int32Use));
                m_graph.convertToConstant(node, jsBoolean(true));
                break;
            }
            break;

        case SetCallee:
            fixEdge<CellUse>(node->child1());
            break;

        case DateGetInt32OrNaN:
        case DateGetTime:
            fixEdge<DateObjectUse>(node->child1());
            break;

        case DataViewGetInt:
        case DataViewGetFloat: {
            fixEdge<DataViewObjectUse>(node->child1());
            fixEdge<Int32Use>(node->child2());
            if (node->child3())
                fixEdge<BooleanUse>(node->child3());

            if (node->op() == DataViewGetInt) {
                DataViewData data = node->dataViewData();
                switch (data.byteSize) {
                case 1:
                case 2:
                    node->setResult(NodeResultInt32);
                    break;
                case 4:
                    if (data.isSigned)
                        node->setResult(NodeResultInt32);
                    else
                        node->setResult(NodeResultInt52);
                    break;
                default:
                    RELEASE_ASSERT_NOT_REACHED();
                }
            }
            break;
        }

        case DataViewSet: {
            fixEdge<DataViewObjectUse>(m_graph.varArgChild(node, 0));
            fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
            if (m_graph.varArgChild(node, 3))
                fixEdge<BooleanUse>(m_graph.varArgChild(node, 3));
            
            DataViewData data = node->dataViewData();
            Edge& valueToStore = m_graph.varArgChild(node, 2);
            if (data.isFloatingPoint)
                fixEdge<DoubleRepUse>(valueToStore);
            else {
                switch (data.byteSize) {
                case 1:
                case 2:
                    fixEdge<Int32Use>(valueToStore);
                    break;
                case 4:
                    if (data.isSigned)
                        fixEdge<Int32Use>(valueToStore);
                    else
                        fixEdge<Int52RepUse>(valueToStore);
                    break;
                }
            }
            break;
        }

        case ForwardVarargs:
        case LoadVarargs: {
            fixEdge<KnownInt32Use>(node->child1());
            break;
        }

#if ASSERT_ENABLED
        // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
        case SetArgumentDefinitely:
        case SetArgumentMaybe:
        case JSConstant:
        case LazyJSConstant:
        case DoubleConstant:
        case GetLocal:
        case GetCallee:
        case GetArgumentCountIncludingThis:
        case SetArgumentCountIncludingThis:
        case GetRestLength:
        case GetArgument:
        case Flush:
        case PhantomLocal:
        case GetGlobalVar:
        case GetGlobalLexicalVariable:
        case NotifyWrite:
        case DirectCall:
        case CheckTypeInfoFlags:
        case TailCallInlinedCaller:
        case DirectTailCallInlinedCaller:
        case Construct:
        case DirectConstruct:
        case CallVarargs:
        case CallEval:
        case TailCallVarargsInlinedCaller:
        case ConstructVarargs:
        case CallForwardVarargs:
        case ConstructForwardVarargs:
        case TailCallForwardVarargs:
        case TailCallForwardVarargsInlinedCaller:
        case VarargsLength:
        case ProfileControlFlow:
        case NewObject:
        case NewPromise:
        case NewGenerator:
        case NewAsyncGenerator:
        case NewArrayIterator:
        case NewRegexp:
        case IsTypedArrayView:
        case IsEmpty:
        case IsUndefined:
        case IsUndefinedOrNull:
        case IsBoolean:
        case IsNumber:
        case IsObjectOrNull:
        case IsFunction:
        case CreateDirectArguments:
        case Jump:
        case Return:
        case TailCall:
        case DirectTailCall:
        case TailCallVarargs:
        case Throw:
        case CountExecution:
        case SuperSamplerBegin:
        case SuperSamplerEnd:
        case ForceOSRExit:
        case CheckBadCell:
        case CheckNotEmpty:
        case AssertNotEmpty:
        case CheckTraps:
        case Unreachable:
        case ExtractOSREntryLocal:
        case ExtractCatchLocal:
        case ClearCatchLocals:
        case LoopHint:
        case MovHint:
        case InitializeEntrypointArguments:
        case ZombieHint:
        case ExitOK:
        case BottomValue:
        case TypeOf:
        case PutByIdWithThis:
        case PutByValWithThis:
        case GetByValWithThis:
        case CompareEqPtr:
        case NumberToStringWithValidRadixConstant:
        case GetGlobalThis:
        case ExtractValueFromWeakMapGet:
        case CPUIntrinsic:
        case FilterCallLinkStatus:
        case FilterGetByStatus:
        case FilterPutByIdStatus:
        case FilterInByIdStatus:
        case InvalidationPoint:
        case CreateArgumentsButterfly:
            break;
#else // not ASSERT_ENABLED
        default:
            break;
#endif // not ASSERT_ENABLED
        }
    }

    void watchHavingABadTime(Node* node)
    {
        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);

        // If this global object is not having a bad time, watch it. We go down this path anytime the code
        // does an array allocation. The types of array allocations may change if we start to have a bad
        // time. It's easier to reason about this if we know that whenever the types change after we start
        // optimizing, the code just gets thrown out. Doing this at FixupPhase is just early enough, since
        // prior to this point nobody should have been doing optimizations based on the indexing type of
        // the allocation.
        if (!globalObject->isHavingABadTime()) {
            m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
            m_graph.freeze(globalObject);
        }
    }
    
    template<UseKind useKind>
    void createToString(Node* node, Edge& edge)
    {
        Node* toString = m_insertionSet.insertNode(
            m_indexInBlock, SpecString, ToString, node->origin,
            Edge(edge.node(), useKind));
        switch (useKind) {
        case Int32Use:
        case Int52RepUse:
        case DoubleRepUse:
        case NotCellUse:
            toString->clearFlags(NodeMustGenerate);
            break;
        default:
            break;
        }
        edge.setNode(toString);
    }
    
    template<UseKind useKind>
    void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
    {
        ASSERT(arrayMode == ArrayMode(Array::Generic, Array::Read) || arrayMode == ArrayMode(Array::Generic, Array::OriginalNonArray, Array::Read));
        
        if (!m_graph.canOptimizeStringObjectAccess(node->origin.semantic))
            return;
        
        addCheckStructureForOriginalStringObjectUse(useKind, node->origin, node->child1().node());
        createToString<useKind>(node, node->child1());
        arrayMode = ArrayMode(Array::String, Array::Read);
    }

    void addCheckStructureForOriginalStringObjectUse(UseKind useKind, const NodeOrigin& origin, Node* node)
    {
        RELEASE_ASSERT(useKind == StringObjectUse || useKind == StringOrStringObjectUse);

        StructureSet set;
        set.add(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
        if (useKind == StringOrStringObjectUse)
            set.add(vm().stringStructure.get());

        m_insertionSet.insertNode(
            m_indexInBlock, SpecNone, CheckStructure, origin,
            OpInfo(m_graph.addStructureSet(set)), Edge(node, CellUse));
    }
    
    template<UseKind useKind>
    void convertStringAddUse(Node* node, Edge& edge)
    {
        if (useKind == StringUse) {
            observeUseKindOnNode<StringUse>(edge.node());
            m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, Check, node->origin,
                Edge(edge.node(), StringUse));
            edge.setUseKind(KnownStringUse);
            return;
        }
        
        observeUseKindOnNode<useKind>(edge.node());
        createToString<useKind>(node, edge);
    }
    
    void convertToMakeRope(Node* node)
    {
        node->setOpAndDefaultFlags(MakeRope);
        fixupMakeRope(node);
    }
    
    void fixupMakeRope(Node* node)
    {
        for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
            Edge& edge = node->children.child(i);
            if (!edge)
                break;
            edge.setUseKind(KnownStringUse);
            JSString* string = edge->dynamicCastConstant<JSString*>(vm());
            if (!string)
                continue;
            if (string->length())
                continue;
            
            // Don't allow the MakeRope to have zero children.
            if (!i && !node->child2())
                break;
            
            node->children.removeEdge(i--);
        }
        
        if (!node->child2()) {
            ASSERT(!node->child3());
            node->convertToIdentity();
        }
    }

    void fixupIsCellWithType(Node* node)
    {
        Optional<SpeculatedType> filter = node->speculatedTypeForQuery();
        if (filter) {
            switch (filter.value()) {
            case SpecString:
                if (node->child1()->shouldSpeculateString()) {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, Check, node->origin,
                        Edge(node->child1().node(), StringUse));
                    m_graph.convertToConstant(node, jsBoolean(true));
                    observeUseKindOnNode<StringUse>(node);
                    return;
                }
                break;

            case SpecProxyObject:
                if (node->child1()->shouldSpeculateProxyObject()) {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, Check, node->origin,
                        Edge(node->child1().node(), ProxyObjectUse));
                    m_graph.convertToConstant(node, jsBoolean(true));
                    observeUseKindOnNode<ProxyObjectUse>(node);
                    return;
                }
                break;

            case SpecRegExpObject:
                if (node->child1()->shouldSpeculateRegExpObject()) {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, Check, node->origin,
                        Edge(node->child1().node(), RegExpObjectUse));
                    m_graph.convertToConstant(node, jsBoolean(true));
                    observeUseKindOnNode<RegExpObjectUse>(node);
                    return;
                }
                break;

            case SpecArray:
                if (node->child1()->shouldSpeculateArray()) {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, Check, node->origin,
                        Edge(node->child1().node(), ArrayUse));
                    m_graph.convertToConstant(node, jsBoolean(true));
                    observeUseKindOnNode<ArrayUse>(node);
                    return;
                }
                break;

            case SpecDerivedArray:
                if (node->child1()->shouldSpeculateDerivedArray()) {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, Check, node->origin,
                        Edge(node->child1().node(), DerivedArrayUse));
                    m_graph.convertToConstant(node, jsBoolean(true));
                    observeUseKindOnNode<DerivedArrayUse>(node);
                    return;
                }
                break;
            }
        }

        if (node->child1()->shouldSpeculateCell()) {
            fixEdge<CellUse>(node->child1());
            return;
        }

        if (node->child1()->shouldSpeculateNotCell()) {
            m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, Check, node->origin,
                Edge(node->child1().node(), NotCellUse));
            m_graph.convertToConstant(node, jsBoolean(false));
            observeUseKindOnNode<NotCellUse>(node);
            return;
        }
    }

    void fixupGetPrototypeOf(Node* node)
    {
        // Reflect.getPrototypeOf only accepts Objects. For Reflect.getPrototypeOf, ByteCodeParser attaches ObjectUse edge filter before fixup phase.
        if (node->child1().useKind() != ObjectUse) {
            if (node->child1()->shouldSpeculateString()) {
                insertCheck<StringUse>(node->child1().node());
                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->stringPrototype()));
                return;
            }
            if (node->child1()->shouldSpeculateInt32()) {
                insertCheck<Int32Use>(node->child1().node());
                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
                return;
            }
            if (node->child1()->shouldSpeculateInt52()) {
                insertCheck<Int52RepUse>(node->child1().node());
                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
                return;
            }
            if (node->child1()->shouldSpeculateNumber()) {
                insertCheck<NumberUse>(node->child1().node());
                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
                return;
            }
            if (node->child1()->shouldSpeculateSymbol()) {
                insertCheck<SymbolUse>(node->child1().node());
                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->symbolPrototype()));
                return;
            }
            if (node->child1()->shouldSpeculateBoolean()) {
                insertCheck<BooleanUse>(node->child1().node());
                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->booleanPrototype()));
                return;
            }
        }

        if (node->child1()->shouldSpeculateFinalObject()) {
            fixEdge<FinalObjectUse>(node->child1());
            node->clearFlags(NodeMustGenerate);
            return;
        }
        if (node->child1()->shouldSpeculateArray()) {
            fixEdge<ArrayUse>(node->child1());
            node->clearFlags(NodeMustGenerate);
            return;
        }
        if (node->child1()->shouldSpeculateFunction()) {
            fixEdge<FunctionUse>(node->child1());
            node->clearFlags(NodeMustGenerate);
            return;
        }
    }

    void fixupToThis(Node* node)
    {
        bool isStrictMode = m_graph.isStrictModeFor(node->origin.semantic);

        if (isStrictMode) {
            if (node->child1()->shouldSpeculateBoolean()) {
                fixEdge<BooleanUse>(node->child1());
                node->convertToIdentity();
                return;
            }

            if (node->child1()->shouldSpeculateInt32()) {
                fixEdge<Int32Use>(node->child1());
                node->convertToIdentity();
                return;
            }

            if (node->child1()->shouldSpeculateInt52()) {
                fixEdge<Int52RepUse>(node->child1());
                node->convertToIdentity();
                node->setResult(NodeResultInt52);
                return;
            }

            if (node->child1()->shouldSpeculateNumber()) {
                fixEdge<DoubleRepUse>(node->child1());
                node->convertToIdentity();
                node->setResult(NodeResultDouble);
                return;
            }

            if (node->child1()->shouldSpeculateSymbol()) {
                fixEdge<SymbolUse>(node->child1());
                node->convertToIdentity();
                return;
            }

            if (node->child1()->shouldSpeculateStringIdent()) {
                fixEdge<StringIdentUse>(node->child1());
                node->convertToIdentity();
                return;
            }

            if (node->child1()->shouldSpeculateString()) {
                fixEdge<StringUse>(node->child1());
                node->convertToIdentity();
                return;
            }
            
            if (node->child1()->shouldSpeculateBigInt()) {
                fixEdge<BigIntUse>(node->child1());
                node->convertToIdentity();
                return;
            }
        }

        if (node->child1()->shouldSpeculateOther()) {
            if (isStrictMode) {
                fixEdge<OtherUse>(node->child1());
                node->convertToIdentity();
                return;
            }

            m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, Check, node->origin,
                Edge(node->child1().node(), OtherUse));
            observeUseKindOnNode<OtherUse>(node->child1().node());
            m_graph.convertToConstant(
                node, m_graph.globalThisObjectFor(node->origin.semantic));
            return;
        }

        // FIXME: This should cover other use cases but we don't have use kinds for them. It's not critical,
        // however, since we cover all the missing cases in constant folding.
        // https://bugs.webkit.org/show_bug.cgi?id=157213
        if (node->child1()->shouldSpeculateStringObject()) {
            fixEdge<StringObjectUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (isFinalObjectSpeculation(node->child1()->prediction())) {
            fixEdge<FinalObjectUse>(node->child1());
            node->convertToIdentity();
            return;
        }
    }
    
    void fixupToPrimitive(Node* node)
    {
        if (node->child1()->shouldSpeculateInt32()) {
            fixEdge<Int32Use>(node->child1());
            node->convertToIdentity();
            return;
        }
        
        if (node->child1()->shouldSpeculateString()) {
            fixEdge<StringUse>(node->child1());
            node->convertToIdentity();
            return;
        }
        
        if (node->child1()->shouldSpeculateStringObject()
            && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
            addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, node->child1().node());
            fixEdge<StringObjectUse>(node->child1());
            node->convertToToString();
            return;
        }
        
        if (node->child1()->shouldSpeculateStringOrStringObject()
            && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
            addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, node->child1().node());
            fixEdge<StringOrStringObjectUse>(node->child1());
            node->convertToToString();
            return;
        }
    }

    void fixupToNumeric(Node* node)
    {
        // If the prediction of the child is BigInt, we attempt to convert ToNumeric to Identity, since it can only return a BigInt when fed a BigInt.
        if (node->child1()->shouldSpeculateBigInt()) {
            fixEdge<BigIntUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        fixupToNumber(node);
    }

    void fixupToNumber(Node* node)
    {
        // At first, attempt to fold Boolean or Int32 to Int32.
        if (node->child1()->shouldSpeculateInt32OrBoolean()) {
            if (isInt32Speculation(node->getHeapPrediction())) {
                fixIntOrBooleanEdge(node->child1());
                node->convertToIdentity();
                return;
            }
        }

        // If the prediction of the child is Number, we attempt to convert ToNumber to Identity.
        if (node->child1()->shouldSpeculateNumber()) {
            if (isInt32Speculation(node->getHeapPrediction())) {
                // If the both predictions of this node and the child is Int32, we just convert ToNumber to Identity, that's simple.
                if (node->child1()->shouldSpeculateInt32()) {
                    fixEdge<Int32Use>(node->child1());
                    node->convertToIdentity();
                    return;
                }

                // The another case is that the predicted type of the child is Int32, but the heap prediction tell the users that this will produce non Int32 values.
                // In that case, let's receive the child value as a Double value and convert it to Int32. This case happens in misc-bugs-847389-jpeg2000.
                fixEdge<DoubleRepUse>(node->child1());
                node->setOp(DoubleAsInt32);
                if (bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
                    node->setArithMode(Arith::CheckOverflow);
                else
                    node->setArithMode(Arith::CheckOverflowAndNegativeZero);
                return;
            }

            fixEdge<DoubleRepUse>(node->child1());
            node->convertToIdentity();
            node->setResult(NodeResultDouble);
            return;
        }

        fixEdge<UntypedUse>(node->child1());
        node->setResult(NodeResultJS);
    }

    void fixupToObject(Node* node)
    {
        if (node->child1()->shouldSpeculateObject()) {
            fixEdge<ObjectUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        // ToObject(Null/Undefined) can throw an error. We can emit filters to convert ToObject to CallObjectConstructor.

        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);

        if (node->child1()->shouldSpeculateString()) {
            insertCheck<StringUse>(node->child1().node());
            fixEdge<KnownStringUse>(node->child1());
            node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
            return;
        }

        if (node->child1()->shouldSpeculateSymbol()) {
            insertCheck<SymbolUse>(node->child1().node());
            node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
            return;
        }

        if (node->child1()->shouldSpeculateNumber()) {
            insertCheck<NumberUse>(node->child1().node());
            node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
            return;
        }

        if (node->child1()->shouldSpeculateBoolean()) {
            insertCheck<BooleanUse>(node->child1().node());
            node->convertToCallObjectConstructor(m_graph.freeze(globalObject));
            return;
        }

        fixEdge<UntypedUse>(node->child1());
    }

    void fixupCallObjectConstructor(Node* node)
    {
        if (node->child1()->shouldSpeculateObject()) {
            fixEdge<ObjectUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (node->child1()->shouldSpeculateString()) {
            auto* globalObject = jsCast<JSGlobalObject*>(node->cellOperand()->cell());
            insertCheck<StringUse>(node->child1().node());
            fixEdge<KnownStringUse>(node->child1());
            node->convertToNewStringObject(m_graph.registerStructure(globalObject->stringObjectStructure()));
            return;
        }

        // While ToObject(Null/Undefined) throws an error, CallObjectConstructor(Null/Undefined) generates a new empty object.
        if (node->child1()->shouldSpeculateOther()) {
            insertCheck<OtherUse>(node->child1().node());
            node->convertToNewObject(m_graph.registerStructure(jsCast<JSGlobalObject*>(node->cellOperand()->cell())->objectStructureForObjectConstructor()));
            return;
        }

        fixEdge<UntypedUse>(node->child1());
    }
    
    void fixupToStringOrCallStringConstructor(Node* node)
    {
        if (node->child1()->shouldSpeculateString()) {
            fixEdge<StringUse>(node->child1());
            node->convertToIdentity();
            return;
        }
        
        if (node->child1()->shouldSpeculateStringObject()
            && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
            addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, node->child1().node());
            fixEdge<StringObjectUse>(node->child1());
            return;
        }
        
        if (node->child1()->shouldSpeculateStringOrStringObject()
            && m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
            addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, node->child1().node());
            fixEdge<StringOrStringObjectUse>(node->child1());
            return;
        }
        
        if (node->child1()->shouldSpeculateCell()) {
            fixEdge<CellUse>(node->child1());
            return;
        }

        if (node->child1()->shouldSpeculateInt32()) {
            fixEdge<Int32Use>(node->child1());
            node->clearFlags(NodeMustGenerate);
            return;
        }

        if (node->child1()->shouldSpeculateInt52()) {
            fixEdge<Int52RepUse>(node->child1());
            node->clearFlags(NodeMustGenerate);
            return;
        }

        if (node->child1()->shouldSpeculateNumber()) {
            fixEdge<DoubleRepUse>(node->child1());
            node->clearFlags(NodeMustGenerate);
            return;
        }

        // ToString(Symbol) throws an error. So if the child1 can include Symbols,
        // we need to care about it in the clobberize. In the following case,
        // since NotCellUse edge filter is used and this edge filters Symbols,
        // we can say that ToString never throws an error!
        if (node->child1()->shouldSpeculateNotCell()) {
            fixEdge<NotCellUse>(node->child1());
            node->clearFlags(NodeMustGenerate);
            return;
        }
    }

    void fixupStringValueOf(Node* node)
    {
        if (node->child1()->shouldSpeculateString()) {
            fixEdge<StringUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (node->child1()->shouldSpeculateStringObject()) {
            fixEdge<StringObjectUse>(node->child1());
            node->convertToToString();
            // It does not need to look up a toString property for the StringObject case. So we can clear NodeMustGenerate.
            node->clearFlags(NodeMustGenerate);
            return;
        }

        if (node->child1()->shouldSpeculateStringOrStringObject()) {
            fixEdge<StringOrStringObjectUse>(node->child1());
            node->convertToToString();
            // It does not need to look up a toString property for the StringObject case. So we can clear NodeMustGenerate.
            node->clearFlags(NodeMustGenerate);
            return;
        }
    }

    bool attemptToMakeFastStringAdd(Node* node)
    {
        bool goodToGo = true;
        m_graph.doToChildren(
            node,
            [&] (Edge& edge) {
                if (edge->shouldSpeculateString())
                    return;
                if (m_graph.canOptimizeStringObjectAccess(node->origin.semantic)) {
                    if (edge->shouldSpeculateStringObject())
                        return;
                    if (edge->shouldSpeculateStringOrStringObject())
                        return;
                }
                goodToGo = false;
            });
        if (!goodToGo)
            return false;

        m_graph.doToChildren(
            node,
            [&] (Edge& edge) {
                if (edge->shouldSpeculateString()) {
                    convertStringAddUse<StringUse>(node, edge);
                    return;
                }
                if (!Options::useConcurrentJIT())
                    ASSERT(m_graph.canOptimizeStringObjectAccess(node->origin.semantic));
                if (edge->shouldSpeculateStringObject()) {
                    addCheckStructureForOriginalStringObjectUse(StringObjectUse, node->origin, edge.node());
                    convertStringAddUse<StringObjectUse>(node, edge);
                    return;
                }
                if (edge->shouldSpeculateStringOrStringObject()) {
                    addCheckStructureForOriginalStringObjectUse(StringOrStringObjectUse, node->origin, edge.node());
                    convertStringAddUse<StringOrStringObjectUse>(node, edge);
                    return;
                }
                RELEASE_ASSERT_NOT_REACHED();
            });
        
        convertToMakeRope(node);
        return true;
    }

    void fixupGetAndSetLocalsInBlock(BasicBlock* block)
    {
        if (!block)
            return;
        ASSERT(block->isReachable);
        m_block = block;
        for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
            Node* node = m_currentNode = block->at(m_indexInBlock);
            if (node->op() != SetLocal && node->op() != GetLocal)
                continue;
            
            VariableAccessData* variable = node->variableAccessData();
            switch (node->op()) {
            case GetLocal:
                switch (variable->flushFormat()) {
                case FlushedDouble:
                    node->setResult(NodeResultDouble);
                    break;
                case FlushedInt52:
                    node->setResult(NodeResultInt52);
                    break;
                default:
                    break;
                }
                break;
                
            case SetLocal:
                // NOTE: Any type checks we put here may get hoisted by fixupChecksInBlock(). So, if we
                // add new type checking use kind for SetLocals, we need to modify that code as well.
                
                switch (variable->flushFormat()) {
                case FlushedJSValue:
                    break;
                case FlushedDouble:
                    fixEdge<DoubleRepUse>(node->child1());
                    break;
                case FlushedInt32:
                    fixEdge<Int32Use>(node->child1());
                    break;
                case FlushedInt52:
                    fixEdge<Int52RepUse>(node->child1());
                    break;
                case FlushedCell:
                    fixEdge<CellUse>(node->child1());
                    break;
                case FlushedBoolean:
                    fixEdge<BooleanUse>(node->child1());
                    break;
                default:
                    RELEASE_ASSERT_NOT_REACHED();
                    break;
                }
                break;
                
            default:
                RELEASE_ASSERT_NOT_REACHED();
                break;
            }
        }
        m_insertionSet.execute(block);
    }
    
    void addStringReplacePrimordialChecks(Node* searchRegExp)
    {
        Node* node = m_currentNode;

        // Check that structure of searchRegExp is RegExp object
        m_insertionSet.insertNode(
            m_indexInBlock, SpecNone, Check, node->origin,
            Edge(searchRegExp, RegExpObjectUse));

        auto emitPrimordialCheckFor = [&] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
            unsigned index = m_graph.identifiers().ensure(propertyUID);

            Node* actualProperty = m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, TryGetById, node->origin,
                OpInfo(index), OpInfo(SpecFunction), Edge(searchRegExp, CellUse));

            m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, CheckCell, node->origin,
                OpInfo(m_graph.freeze(primordialProperty)), Edge(actualProperty, CellUse));
        };

        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);

        // Check that searchRegExp.exec is the primordial RegExp.prototype.exec
        emitPrimordialCheckFor(globalObject->regExpProtoExecFunction(), vm().propertyNames->exec.impl());
        // Check that searchRegExp.global is the primordial RegExp.prototype.global
        emitPrimordialCheckFor(globalObject->regExpProtoGlobalGetter(), vm().propertyNames->global.impl());
        // Check that searchRegExp.unicode is the primordial RegExp.prototype.unicode
        emitPrimordialCheckFor(globalObject->regExpProtoUnicodeGetter(), vm().propertyNames->unicode.impl());
        // Check that searchRegExp[Symbol.match] is the primordial RegExp.prototype[Symbol.replace]
        emitPrimordialCheckFor(globalObject->regExpProtoSymbolReplaceFunction(), vm().propertyNames->replaceSymbol.impl());
    }

    Node* checkArray(ArrayMode arrayMode, const NodeOrigin& origin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
    {
        ASSERT(arrayMode.isSpecific());
        
        if (arrayMode.type() == Array::String) {
            m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
        } else {
            // Note that we only need to be using a structure check if we opt for SaneChain, since
            // that needs to protect against JSArray's __proto__ being changed.
            Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
        
            Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
            
            if (arrayMode.doesConversion()) {
                if (structure) {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, ArrayifyToStructure, origin,
                        OpInfo(m_graph.registerStructure(structure)), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
                } else {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, Arrayify, origin,
                        OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
                }
            } else {
                if (structure) {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, CheckStructure, origin,
                        OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
                } else {
                    m_insertionSet.insertNode(
                        m_indexInBlock, SpecNone, CheckArray, origin,
                        OpInfo(arrayMode.asWord()), Edge(array, CellUse));
                }
            }
        }
        
        if (!storageCheck(arrayMode))
            return nullptr;
        
        if (arrayMode.usesButterfly()) {
            return m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, GetButterfly, origin, Edge(array, CellUse));
        }
        
        return m_insertionSet.insertNode(
            m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
            OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
    }

    void setSaneChainIfPossible(Node* node)
    {
        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
        Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
        Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
        if (arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
            && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
            && globalObject->arrayPrototypeChainIsSane()) {
            m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
            m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
            node->setArrayMode(node->arrayMode().withSpeculation(Array::SaneChain));
            node->clearFlags(NodeMustGenerate);
        }
    }
    
    void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
    {
        Node* node = m_currentNode;
        
        switch (node->arrayMode().type()) {
        case Array::ForceExit: {
            m_insertionSet.insertNode(
                m_indexInBlock, SpecNone, ForceOSRExit, node->origin);
            return;
        }
            
        case Array::SelectUsingPredictions:
        case Array::Unprofiled:
            RELEASE_ASSERT_NOT_REACHED();
            return;
            
        case Array::Generic:
            return;
            
        default: {
            Node* storage = checkArray(node->arrayMode(), node->origin, base.node(), index.node());
            if (!storage)
                return;
            
            storageChild = Edge(storage);
            return;
        } }
    }
    
    bool alwaysUnboxSimplePrimitives()
    {
#if USE(JSVALUE64)
        return false;
#else
        // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
        // reduces traffic.
        return true;
#endif
    }

    template<UseKind useKind>
    void observeUseKindOnNode(Node* node)
    {
        if (useKind == UntypedUse)
            return;
        observeUseKindOnNode(node, useKind);
    }

    void observeUseKindOnEdge(Edge edge)
    {
        observeUseKindOnNode(edge.node(), edge.useKind());
    }

    void observeUseKindOnNode(Node* node, UseKind useKind)
    {
        if (node->op() != GetLocal)
            return;
        
        // FIXME: The way this uses alwaysUnboxSimplePrimitives() is suspicious.
        // https://bugs.webkit.org/show_bug.cgi?id=121518
        
        VariableAccessData* variable = node->variableAccessData();
        switch (useKind) {
        case Int32Use:
        case KnownInt32Use:
            if (alwaysUnboxSimplePrimitives()
                || isInt32Speculation(variable->prediction()))
                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
            break;
        case NumberUse:
        case RealNumberUse:
        case DoubleRepUse:
        case DoubleRepRealUse:
            if (variable->doubleFormatState() == UsingDoubleFormat)
                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
            break;
        case BooleanUse:
        case KnownBooleanUse:
            if (alwaysUnboxSimplePrimitives()
                || isBooleanSpeculation(variable->prediction()))
                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
            break;
        case Int52RepUse:
            if (!isInt32Speculation(variable->prediction()) && isInt32OrInt52Speculation(variable->prediction()))
                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
            break;
        case CellUse:
        case KnownCellUse:
        case ObjectUse:
        case FunctionUse:
        case StringUse:
        case KnownStringUse:
        case SymbolUse:
        case BigIntUse:
        case StringObjectUse:
        case StringOrStringObjectUse:
            if (alwaysUnboxSimplePrimitives()
                || isCellSpeculation(variable->prediction()))
                m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
            break;
        default:
            break;
        }
    }
    
    template<UseKind useKind>
    void fixEdge(Edge& edge)
    {
        observeUseKindOnNode<useKind>(edge.node());
        edge.setUseKind(useKind);
    }
    
    unsigned indexForChecks()
    {
        unsigned index = m_indexInBlock;
        while (!m_block->at(index)->origin.exitOK)
            index--;
        return index;
    }
    
    NodeOrigin originForCheck(unsigned index)
    {
        return m_block->at(index)->origin.withSemantic(m_currentNode->origin.semantic);
    }
    
    void speculateForBarrier(Edge value)
    {
        // Currently, the DFG won't take advantage of this speculation. But, we want to do it in
        // the DFG anyway because if such a speculation would be wrong, we want to know before
        // we do an expensive compile.
        
        if (value->shouldSpeculateInt32()) {
            insertCheck<Int32Use>(value.node());
            return;
        }
            
        if (value->shouldSpeculateBoolean()) {
            insertCheck<BooleanUse>(value.node());
            return;
        }
            
        if (value->shouldSpeculateOther()) {
            insertCheck<OtherUse>(value.node());
            return;
        }
            
        if (value->shouldSpeculateNumber()) {
            insertCheck<NumberUse>(value.node());
            return;
        }
            
        if (value->shouldSpeculateNotCell()) {
            insertCheck<NotCellUse>(value.node());
            return;
        }
    }
    
    template<UseKind useKind>
    void insertCheck(Node* node)
    {
        observeUseKindOnNode<useKind>(node);
        unsigned index = indexForChecks();
        m_insertionSet.insertNode(index, SpecNone, Check, originForCheck(index), Edge(node, useKind));
    }

    void fixIntConvertingEdge(Edge& edge)
    {
        Node* node = edge.node();
        if (node->shouldSpeculateInt32OrBoolean()) {
            fixIntOrBooleanEdge(edge);
            return;
        }
        
        UseKind useKind;
        if (node->shouldSpeculateInt52())
            useKind = Int52RepUse;
        else if (node->shouldSpeculateNumber())
            useKind = DoubleRepUse;
        else
            useKind = NotCellUse;
        Node* newNode = m_insertionSet.insertNode(
            m_indexInBlock, SpecInt32Only, ValueToInt32, m_currentNode->origin,
            Edge(node, useKind));
        observeUseKindOnNode(node, useKind);
        
        edge = Edge(newNode, KnownInt32Use);
    }
    
    void fixIntOrBooleanEdge(Edge& edge)
    {
        Node* node = edge.node();
        if (!node->sawBooleans()) {
            fixEdge<Int32Use>(edge);
            return;
        }
        
        UseKind useKind;
        if (node->shouldSpeculateBoolean())
            useKind = BooleanUse;
        else
            useKind = UntypedUse;
        Node* newNode = m_insertionSet.insertNode(
            m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
            Edge(node, useKind));
        observeUseKindOnNode(node, useKind);
        
        edge = Edge(newNode, Int32Use);
    }
    
    void fixDoubleOrBooleanEdge(Edge& edge)
    {
        Node* node = edge.node();
        if (!node->sawBooleans()) {
            fixEdge<DoubleRepUse>(edge);
            return;
        }
        
        UseKind useKind;
        if (node->shouldSpeculateBoolean())
            useKind = BooleanUse;
        else
            useKind = UntypedUse;
        Node* newNode = m_insertionSet.insertNode(
            m_indexInBlock, SpecInt32Only, BooleanToNumber, m_currentNode->origin,
            Edge(node, useKind));
        observeUseKindOnNode(node, useKind);
        
        edge = Edge(newNode, DoubleRepUse);
    }
    
    void truncateConstantToInt32(Edge& edge)
    {
        Node* oldNode = edge.node();
        
        JSValue value = oldNode->asJSValue();
        if (value.isInt32())
            return;
        
        value = jsNumber(JSC::toInt32(value.asNumber()));
        ASSERT(value.isInt32());
        edge.setNode(m_insertionSet.insertNode(
            m_indexInBlock, SpecInt32Only, JSConstant, m_currentNode->origin,
            OpInfo(m_graph.freeze(value))));
    }
    
    void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
    {
        if (mode != SpeculateInt32AndTruncateConstants)
            return;
        
        ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
        if (node->child1()->hasConstant())
            truncateConstantToInt32(node->child1());
        else
            truncateConstantToInt32(node->child2());
    }

    bool attemptToMakeIntegerAdd(Node* node)
    {
        AddSpeculationMode mode = m_graph.addSpeculationMode(node, FixupPass);
        if (mode != DontSpeculateInt32) {
            truncateConstantsIfNecessary(node, mode);
            fixIntOrBooleanEdge(node->child1());
            fixIntOrBooleanEdge(node->child2());
            if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
                node->setArithMode(Arith::Unchecked);
            else
                node->setArithMode(Arith::CheckOverflow);
            return true;
        }
        
        if (m_graph.addShouldSpeculateInt52(node)) {
            fixEdge<Int52RepUse>(node->child1());
            fixEdge<Int52RepUse>(node->child2());
            node->setArithMode(Arith::CheckOverflow);
            node->setResult(NodeResultInt52);
            return true;
        }
        
        return false;
    }
    
    bool attemptToMakeGetArrayLength(Node* node)
    {
        if (!isInt32Speculation(node->prediction()))
            return false;
        CodeBlock* profiledBlock = m_graph.baselineCodeBlockFor(node->origin.semantic);
        ArrayProfile* arrayProfile = 
            profiledBlock->getArrayProfile(node->origin.semantic.bytecodeIndex());
        ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions, Array::Read);
        if (arrayProfile) {
            ConcurrentJSLocker locker(profiledBlock->m_lock);
            arrayProfile->computeUpdatedPrediction(locker, profiledBlock);
            arrayMode = ArrayMode::fromObserved(locker, arrayProfile, Array::Read, false);
            if (arrayMode.type() == Array::Unprofiled) {
                // For normal array operations, it makes sense to treat Unprofiled
                // accesses as ForceExit and get more data rather than using
                // predictions and then possibly ending up with a Generic. But here,
                // we treat anything that is Unprofiled as Generic and keep the
                // GetById. I.e. ForceExit = Generic. So, there is no harm - and only
                // profit - from treating the Unprofiled case as
                // SelectUsingPredictions.
                arrayMode = ArrayMode(Array::SelectUsingPredictions, Array::Read);
            }
        }
            
        arrayMode = arrayMode.refine(
            m_graph, node, node->child1()->prediction(), node->prediction());
            
        if (arrayMode.type() == Array::Generic) {
            // Check if the input is something that we can't get array length for, but for which we
            // could insert some conversions in order to transform it into something that we can do it
            // for.
            if (node->child1()->shouldSpeculateStringObject())
                attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
            else if (node->child1()->shouldSpeculateStringOrStringObject())
                attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
        }
            
        if (!arrayMode.supportsSelfLength())
            return false;
        
        convertToGetArrayLength(node, arrayMode);
        return true;
    }

    void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
    {
        node->setOp(GetArrayLength);
        node->clearFlags(NodeMustGenerate);
        fixEdge<KnownCellUse>(node->child1());
        node->setArrayMode(arrayMode);
            
        Node* storage = checkArray(arrayMode, node->origin, node->child1().node(), 0, lengthNeedsStorage);
        if (!storage)
            return;
            
        node->child2() = Edge(storage);
    }
    
    Node* prependGetArrayLength(NodeOrigin origin, Node* child, ArrayMode arrayMode)
    {
        Node* storage = checkArray(arrayMode, origin, child, 0, lengthNeedsStorage);
        return m_insertionSet.insertNode(
            m_indexInBlock, SpecInt32Only, GetArrayLength, origin,
            OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
    }

    void convertToHasIndexedProperty(Node* node)
    {
        node->setOp(HasIndexedProperty);

        {
            unsigned firstChild = m_graph.m_varArgChildren.size();
            unsigned numChildren = 3;
            m_graph.m_varArgChildren.append(node->child1());
            m_graph.m_varArgChildren.append(node->child2());
            m_graph.m_varArgChildren.append(Edge());
            node->setFlags(defaultFlags(HasIndexedProperty));
            node->children = AdjacencyList(AdjacencyList::Variable, firstChild, numChildren);
        }

        node->setArrayMode(
            node->arrayMode().refine(
                m_graph, node,
                m_graph.varArgChild(node, 0)->prediction(),
                m_graph.varArgChild(node, 1)->prediction(),
                SpecNone));
        node->setInternalMethodType(PropertySlot::InternalMethodType::HasProperty);

        blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
        auto arrayMode = node->arrayMode();
        // FIXME: OutOfBounds shouldn't preclude going sane chain because OOB is just false and cannot have effects.
        // See: https://bugs.webkit.org/show_bug.cgi?id=209456
        if (arrayMode.isJSArrayWithOriginalStructure() && arrayMode.speculation() == Array::InBounds)
            setSaneChainIfPossible(node);

        fixEdge<CellUse>(m_graph.varArgChild(node, 0));
        fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
    }

    void fixupNormalizeMapKey(Node* node)
    {
        if (node->child1()->shouldSpeculateBoolean()) {
            fixEdge<BooleanUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (node->child1()->shouldSpeculateInt32()) {
            fixEdge<Int32Use>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (node->child1()->shouldSpeculateSymbol()) {
            fixEdge<SymbolUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (node->child1()->shouldSpeculateObject()) {
            fixEdge<ObjectUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (node->child1()->shouldSpeculateString()) {
            fixEdge<StringUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        if (node->child1()->shouldSpeculateCell()) {
            fixEdge<CellUse>(node->child1());
            node->convertToIdentity();
            return;
        }

        fixEdge<UntypedUse>(node->child1());
    }

    bool attemptToMakeCallDOM(Node* node)
    {
        if (m_graph.hasExitSite(node->origin.semantic, BadType))
            return false;

        const DOMJIT::Signature* signature = node->signature();
        if (!signature)
            return false;

        {
            unsigned index = 0;
            bool shouldConvertToCallDOM = true;
            m_graph.doToChildren(node, [&](Edge& edge) {
                // Callee. Ignore this. DFGByteCodeParser already emit appropriate checks.
                if (!index)
                    return;

                if (index == 1) {
                    // DOM node case.
                    if (edge->shouldSpeculateNotCell())
                        shouldConvertToCallDOM = false;
                } else {
                    switch (signature->arguments[index - 2]) {
                    case SpecString:
                        if (edge->shouldSpeculateNotString())
                            shouldConvertToCallDOM = false;
                        break;
                    case SpecInt32Only:
                        if (edge->shouldSpeculateNotInt32())
                            shouldConvertToCallDOM = false;
                        break;
                    case SpecBoolean:
                        if (edge->shouldSpeculateNotBoolean())
                            shouldConvertToCallDOM = false;
                        break;
                    default:
                        RELEASE_ASSERT_NOT_REACHED();
                        break;
                    }
                }
                ++index;
            });
            if (!shouldConvertToCallDOM)
                return false;
        }

        Node* thisNode = m_graph.varArgChild(node, 1).node();
        Node* checkSubClass = m_insertionSet.insertNode(m_indexInBlock, SpecNone, CheckSubClass, node->origin, OpInfo(signature->classInfo), Edge(thisNode));
        node->convertToCallDOM(m_graph);
        fixupCheckSubClass(checkSubClass);
        fixupCallDOM(node);
        return true;
    }

    void fixupCheckSubClass(Node* node)
    {
        fixEdge<CellUse>(node->child1());
    }

    void fixupCallDOM(Node* node)
    {
        const DOMJIT::Signature* signature = node->signature();
        auto fixup = [&](Edge& edge, unsigned argumentIndex) {
            if (!edge)
                return;
            switch (signature->arguments[argumentIndex]) {
            case SpecString:
                fixEdge<StringUse>(edge);
                break;
            case SpecInt32Only:
                fixEdge<Int32Use>(edge);
                break;
            case SpecBoolean:
                fixEdge<BooleanUse>(edge);
                break;
            default:
                RELEASE_ASSERT_NOT_REACHED();
                break;
            }
        };
        fixEdge<CellUse>(node->child1()); // DOM.
        fixup(node->child2(), 0);
        fixup(node->child3(), 1);
    }

    void fixupArrayIndexOf(Node* node)
    {
        Edge& array = m_graph.varArgChild(node, 0);
        Edge& storage = m_graph.varArgChild(node, node->numChildren() == 3 ? 2 : 3);
        blessArrayOperation(array, Edge(), storage);
        ASSERT_WITH_MESSAGE(storage.node(), "blessArrayOperation for ArrayIndexOf must set Butterfly for storage edge.");

        Edge& searchElement = m_graph.varArgChild(node, 1);

        // Constant folding.
        switch (node->arrayMode().type()) {
        case Array::Double:
        case Array::Int32: {
            if (searchElement->shouldSpeculateCell()) {
                m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin, Edge(searchElement.node(), CellUse));
                m_graph.convertToConstant(node, jsNumber(-1));
                observeUseKindOnNode<CellUse>(searchElement.node());
                return;
            }

            if (searchElement->shouldSpeculateOther()) {
                m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin, Edge(searchElement.node(), OtherUse));
                m_graph.convertToConstant(node, jsNumber(-1));
                observeUseKindOnNode<OtherUse>(searchElement.node());
                return;
            }

            if (searchElement->shouldSpeculateBoolean()) {
                m_insertionSet.insertNode(m_indexInBlock, SpecNone, Check, node->origin, Edge(searchElement.node(), BooleanUse));
                m_graph.convertToConstant(node, jsNumber(-1));
                observeUseKindOnNode<BooleanUse>(searchElement.node());
                return;
            }
            break;
        }
        default:
            break;
        }

        fixEdge<KnownCellUse>(array);
        if (node->numChildren() == 4)
            fixEdge<Int32Use>(m_graph.varArgChild(node, 2));

        switch (node->arrayMode().type()) {
        case Array::Double: {
            if (searchElement->shouldSpeculateNumber())
                fixEdge<DoubleRepUse>(searchElement);
            return;
        }
        case Array::Int32: {
            if (searchElement->shouldSpeculateInt32())
                fixEdge<Int32Use>(searchElement);
            return;
        }
        case Array::Contiguous: {
            if (searchElement->shouldSpeculateString())
                fixEdge<StringUse>(searchElement);
            else if (searchElement->shouldSpeculateSymbol())
                fixEdge<SymbolUse>(searchElement);
            else if (searchElement->shouldSpeculateOther())
                fixEdge<OtherUse>(searchElement);
            else if (searchElement->shouldSpeculateObject())
                fixEdge<ObjectUse>(searchElement);
            return;
        }
        default:
            RELEASE_ASSERT_NOT_REACHED();
            return;
        }
    }

    void fixupCompareStrictEqAndSameValue(Node* node)
    {
        ASSERT(node->op() == SameValue || node->op() == CompareStrictEq);

        if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
            fixEdge<BooleanUse>(node->child1());
            fixEdge<BooleanUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (Node::shouldSpeculateInt32(node->child1().node(), node->child2().node())) {
            fixEdge<Int32Use>(node->child1());
            fixEdge<Int32Use>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (Node::shouldSpeculateInt52(node->child1().node(), node->child2().node())) {
            fixEdge<Int52RepUse>(node->child1());
            fixEdge<Int52RepUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
            fixEdge<DoubleRepUse>(node->child1());
            fixEdge<DoubleRepUse>(node->child2());
            // Do not convert SameValue to CompareStrictEq in this case since SameValue(NaN, NaN) and SameValue(-0, +0)
            // are not the same to CompareStrictEq(NaN, NaN) and CompareStrictEq(-0, +0).
            return;
        }
        if (Node::shouldSpeculateSymbol(node->child1().node(), node->child2().node())) {
            fixEdge<SymbolUse>(node->child1());
            fixEdge<SymbolUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
            fixEdge<BigIntUse>(node->child1());
            fixEdge<BigIntUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child1()->shouldSpeculateStringIdent() && node->child2()->shouldSpeculateStringIdent()) {
            fixEdge<StringIdentUse>(node->child1());
            fixEdge<StringIdentUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 7) || m_graph.m_plan.isFTL())) {
            fixEdge<StringUse>(node->child1());
            fixEdge<StringUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }

        if (node->op() == SameValue) {
            if (node->child1()->shouldSpeculateObject()) {
                fixEdge<ObjectUse>(node->child1());
                node->setOpAndDefaultFlags(CompareStrictEq);
                return;
            }
            if (node->child2()->shouldSpeculateObject()) {
                fixEdge<ObjectUse>(node->child2());
                node->setOpAndDefaultFlags(CompareStrictEq);
                return;
            }
        } else {
            WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
            if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
                if (node->child1()->shouldSpeculateObject()) {
                    m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
                    fixEdge<ObjectUse>(node->child1());
                    return;
                }
                if (node->child2()->shouldSpeculateObject()) {
                    m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
                    fixEdge<ObjectUse>(node->child2());
                    return;
                }
            } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
                fixEdge<ObjectUse>(node->child1());
                fixEdge<ObjectUse>(node->child2());
                return;
            }
        }

        if (node->child1()->shouldSpeculateSymbol()) {
            fixEdge<SymbolUse>(node->child1());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child2()->shouldSpeculateSymbol()) {
            fixEdge<SymbolUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child1()->shouldSpeculateMisc()) {
            fixEdge<MiscUse>(node->child1());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child2()->shouldSpeculateMisc()) {
            fixEdge<MiscUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child1()->shouldSpeculateStringIdent()
            && node->child2()->shouldSpeculateNotStringVar()) {
            fixEdge<StringIdentUse>(node->child1());
            fixEdge<NotStringVarUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child2()->shouldSpeculateStringIdent()
            && node->child1()->shouldSpeculateNotStringVar()) {
            fixEdge<StringIdentUse>(node->child2());
            fixEdge<NotStringVarUse>(node->child1());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child1()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || m_graph.m_plan.isFTL())) {
            fixEdge<StringUse>(node->child1());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
        if (node->child2()->shouldSpeculateString() && ((GPRInfo::numberOfRegisters >= 8) || m_graph.m_plan.isFTL())) {
            fixEdge<StringUse>(node->child2());
            node->setOpAndDefaultFlags(CompareStrictEq);
            return;
        }
    }

    void fixupChecksInBlock(BasicBlock* block)
    {
        if (!block)
            return;
        ASSERT(block->isReachable);
        m_block = block;
        unsigned indexForChecks = UINT_MAX;
        NodeOrigin originForChecks;
        for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
            Node* node = block->at(indexInBlock);

            // If this is a node at which we could exit, then save its index. If nodes after this one
            // cannot exit, then we will hoist checks to here.
            if (node->origin.exitOK) {
                indexForChecks = indexInBlock;
                originForChecks = node->origin;
            }

            originForChecks = originForChecks.withSemantic(node->origin.semantic);
            
            // First, try to relax the representational demands of each node, in order to have
            // fewer conversions.
            switch (node->op()) {
            case MovHint:
            case Check:
            case CheckVarargs:
                m_graph.doToChildren(
                    node,
                    [&] (Edge& edge) {
                        switch (edge.useKind()) {
                        case DoubleRepUse:
                        case DoubleRepRealUse:
                            if (edge->hasDoubleResult())
                                break;
            
                            if (edge->hasInt52Result())
                                edge.setUseKind(Int52RepUse);
                            else if (edge.useKind() == DoubleRepUse)
                                edge.setUseKind(NumberUse);
                            break;
            
                        case Int52RepUse:
                            // Nothing we can really do.
                            break;
            
                        case UntypedUse:
                        case NumberUse:
                            if (edge->hasDoubleResult())
                                edge.setUseKind(DoubleRepUse);
                            else if (edge->hasInt52Result())
                                edge.setUseKind(Int52RepUse);
                            break;
            
                        case RealNumberUse:
                            if (edge->hasDoubleResult())
                                edge.setUseKind(DoubleRepRealUse);
                            else if (edge->hasInt52Result())
                                edge.setUseKind(Int52RepUse);
                            break;
            
                        default:
                            break;
                        }
                    });
                break;
                
            case ValueToInt32:
                if (node->child1().useKind() == DoubleRepUse
                    && !node->child1()->hasDoubleResult()) {
                    node->child1().setUseKind(NumberUse);
                    break;
                }
                break;
                
            default:
                break;
            }

            // Now, insert type conversions if necessary.
            m_graph.doToChildren(
                node,
                [&] (Edge& edge) {
                    Node* result = nullptr;

                    switch (edge.useKind()) {
                    case DoubleRepUse:
                    case DoubleRepRealUse:
                    case DoubleRepAnyIntUse: {
                        if (edge->hasDoubleResult())
                            break;
            
                        ASSERT(indexForChecks != UINT_MAX);
                        if (edge->isNumberConstant()) {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecBytecodeDouble, DoubleConstant, originForChecks,
                                OpInfo(m_graph.freeze(jsDoubleNumber(edge->asNumber()))));
                        } else if (edge->hasInt52Result()) {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecAnyIntAsDouble, DoubleRep, originForChecks,
                                Edge(edge.node(), Int52RepUse));
                        } else {
                            UseKind useKind;
                            if (edge->shouldSpeculateDoubleReal())
                                useKind = RealNumberUse;
                            else if (edge->shouldSpeculateNumber())
                                useKind = NumberUse;
                            else
                                useKind = NotCellUse;

                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecBytecodeDouble, DoubleRep, originForChecks,
                                Edge(edge.node(), useKind));
                        }

                        edge.setNode(result);
                        break;
                    }
            
                    case Int52RepUse: {
                        if (edge->hasInt52Result())
                            break;
            
                        ASSERT(indexForChecks != UINT_MAX);
                        if (edge->isAnyIntConstant()) {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecInt52Any, Int52Constant, originForChecks,
                                OpInfo(edge->constant()));
                        } else if (edge->hasDoubleResult()) {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecInt52Any, Int52Rep, originForChecks,
                                Edge(edge.node(), DoubleRepAnyIntUse));
                        } else if (edge->shouldSpeculateInt32ForArithmetic()) {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecInt32Only, Int52Rep, originForChecks,
                                Edge(edge.node(), Int32Use));
                        } else {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecInt52Any, Int52Rep, originForChecks,
                                Edge(edge.node(), AnyIntUse));
                        }

                        edge.setNode(result);
                        break;
                    }

                    default: {
                        if (!edge->hasDoubleResult() && !edge->hasInt52Result())
                            break;
            
                        ASSERT(indexForChecks != UINT_MAX);
                        if (edge->hasDoubleResult()) {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecBytecodeDouble, ValueRep, originForChecks,
                                Edge(edge.node(), DoubleRepUse));
                        } else {
                            result = m_insertionSet.insertNode(
                                indexForChecks, SpecInt32Only | SpecAnyIntAsDouble, ValueRep,
                                originForChecks, Edge(edge.node(), Int52RepUse));
                        }

                        edge.setNode(result);
                        break;
                    } }

                    // It's remotely possible that this node cannot do type checks, but we now have a
                    // type check on this node. We don't have to handle the general form of this
                    // problem. It only arises when ByteCodeParser emits an immediate SetLocal, rather
                    // than a delayed one. So, we only worry about those checks that we may have put on
                    // a SetLocal. Note that "indexForChecks != indexInBlock" is just another way of
                    // saying "!node->origin.exitOK".
                    if (indexForChecks != indexInBlock && mayHaveTypeCheck(edge.useKind())) {
                        UseKind knownUseKind;
                        
                        switch (edge.useKind()) {
                        case Int32Use:
                            knownUseKind = KnownInt32Use;
                            break;
                        case CellUse:
                            knownUseKind = KnownCellUse;
                            break;
                        case BooleanUse:
                            knownUseKind = KnownBooleanUse;
                            break;
                        default:
                            // This can only arise if we have a Check node, and in that case, we can
                            // just remove the original check.
                            DFG_ASSERT(m_graph, node, node->op() == Check, node->op(), edge.useKind());
                            knownUseKind = UntypedUse;
                            break;
                        }

                        ASSERT(indexForChecks != UINT_MAX);
                        m_insertionSet.insertNode(
                            indexForChecks, SpecNone, Check, originForChecks, edge);

                        edge.setUseKind(knownUseKind);
                    }
                });
        }
        
        m_insertionSet.execute(block);
    }
    
    BasicBlock* m_block;
    unsigned m_indexInBlock;
    Node* m_currentNode;
    InsertionSet m_insertionSet;
    bool m_profitabilityChanged;
};
    
bool performFixup(Graph& graph)
{
    return runPhase<FixupPhase>(graph);
}

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)

