bool run()
 {
     m_graph.m_dominators.computeIfNecessary(m_graph);
     m_graph.m_naturalLoops.computeIfNecessary(m_graph);
     
     for (unsigned loopIndex = m_graph.m_naturalLoops.numLoops(); loopIndex--;) {
         const NaturalLoop& loop = m_graph.m_naturalLoops.loop(loopIndex);
         BasicBlock* existingPreHeader = 0;
         bool needsNewPreHeader = false;
         for (unsigned predecessorIndex = loop.header()->predecessors.size(); predecessorIndex--;) {
             BasicBlock* predecessor = loop.header()->predecessors[predecessorIndex];
             if (m_graph.m_dominators.dominates(loop.header(), predecessor))
                 continue;
             if (!existingPreHeader) {
                 existingPreHeader = predecessor;
                 continue;
             }
             if (existingPreHeader == predecessor)
                 continue;
             needsNewPreHeader = true;
             break;
         }
         if (!needsNewPreHeader)
             continue;
         
         createPreHeader(m_graph, m_insertionSet, loop.header());
     }
     
     return m_insertionSet.execute();
 }
 bool run()
 {
     m_graph.m_dominators.computeIfNecessary(m_graph);
     m_graph.m_naturalLoops.computeIfNecessary(m_graph);
     
     for (unsigned loopIndex = m_graph.m_naturalLoops.numLoops(); loopIndex--;) {
         const NaturalLoop& loop = m_graph.m_naturalLoops.loop(loopIndex);
         BasicBlock* existingPreHeader = 0;
         bool needsNewPreHeader = false;
         for (unsigned predecessorIndex = loop.header()->predecessors.size(); predecessorIndex--;) {
             BasicBlock* predecessor = loop.header()->predecessors[predecessorIndex];
             if (m_graph.m_dominators.dominates(loop.header(), predecessor))
                 continue;
             if (!existingPreHeader) {
                 existingPreHeader = predecessor;
                 continue;
             }
             // We won't have duplicate entries in the predecessors list.
             DFG_ASSERT(m_graph, nullptr, existingPreHeader != predecessor);
             needsNewPreHeader = true;
             break;
         }
         
         // This phase should only be run on a DFG where unreachable blocks have been pruned.
         // We also don't allow loops back to root. This means that every loop header has got
         // to have a pre-header.
         DFG_ASSERT(m_graph, nullptr, existingPreHeader);
         
         // We are looking at the predecessors of a loop header. A loop header has to have
         // some predecessor other than the pre-header. We must have broken critical edges
         // because that is the DFG SSA convention. Therefore, each predecessor of the loop
         // header must have only one successor.
         DFG_ASSERT(m_graph, nullptr, existingPreHeader->terminal()->op() == Jump);
         
         if (!needsNewPreHeader)
             continue;
         
         createPreHeader(m_graph, m_insertionSet, loop.header());
     }
     
     return m_insertionSet.execute();
 }
    bool run()
    {
        RELEASE_ASSERT(m_graph.m_plan.mode == FTLForOSREntryMode);
        RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
        
        unsigned bytecodeIndex = m_graph.m_plan.osrEntryBytecodeIndex;
        RELEASE_ASSERT(bytecodeIndex);
        RELEASE_ASSERT(bytecodeIndex != UINT_MAX);
        
        // Needed by createPreHeader().
        m_graph.ensureDominators();
        
        CodeBlock* baseline = m_graph.m_profiledBlock;
        
        BasicBlock* target = 0;
        for (unsigned blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            unsigned nodeIndex = 0;
            Node* firstNode = block->at(0);
            while (firstNode->isSemanticallySkippable())
                firstNode = block->at(++nodeIndex);
            if (firstNode->op() == LoopHint
                && firstNode->origin.semantic == CodeOrigin(bytecodeIndex)) {
                target = block;
                break;
            }
        }

        if (!target) {
            // This is a terrible outcome. It shouldn't often happen but it might
            // happen and so we should defend against it. If it happens, then this
            // compilation is a failure.
            return false;
        }
        
        BlockInsertionSet insertionSet(m_graph);
        
        // We say that the execution count of the entry block is 1, because we know for sure
        // that this must be the case. Under our definition of executionCount, "1" means "once
        // per invocation". We could have said NaN here, since that would ask any clients of
        // executionCount to use best judgement - but that seems unnecessary since we know for
        // sure what the executionCount should be in this case.
        BasicBlock* newRoot = insertionSet.insert(0, 1);

        // We'd really like to use an unset origin, but ThreadedCPS won't allow that.
        NodeOrigin origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), false);
        
        Vector<Node*> locals(baseline->m_numCalleeLocals);
        for (int local = 0; local < baseline->m_numCalleeLocals; ++local) {
            Node* previousHead = target->variablesAtHead.local(local);
            if (!previousHead)
                continue;
            VariableAccessData* variable = previousHead->variableAccessData();
            locals[local] = newRoot->appendNode(
                m_graph, variable->prediction(), ExtractOSREntryLocal, origin,
                OpInfo(variable->local().offset()));
            
            newRoot->appendNode(
                m_graph, SpecNone, MovHint, origin, OpInfo(variable->local().offset()),
                Edge(locals[local]));
        }

        // Now use the origin of the target, since it's not OK to exit, and we will probably hoist
        // type checks to here.
        origin = target->at(0)->origin;
        
        for (int argument = 0; argument < baseline->numParameters(); ++argument) {
            Node* oldNode = target->variablesAtHead.argument(argument);
            if (!oldNode) {
                // Just for sanity, always have a SetArgument even if it's not needed.
                oldNode = m_graph.m_arguments[argument];
            }
            Node* node = newRoot->appendNode(
                m_graph, SpecNone, SetArgument, origin,
                OpInfo(oldNode->variableAccessData()));
            m_graph.m_arguments[argument] = node;
        }

        for (int local = 0; local < baseline->m_numCalleeLocals; ++local) {
            Node* previousHead = target->variablesAtHead.local(local);
            if (!previousHead)
                continue;
            VariableAccessData* variable = previousHead->variableAccessData();
            Node* node = locals[local];
            newRoot->appendNode(
                m_graph, SpecNone, SetLocal, origin, OpInfo(variable), Edge(node));
        }
        
        newRoot->appendNode(
            m_graph, SpecNone, Jump, origin,
            OpInfo(createPreHeader(m_graph, insertionSet, target)));
        
        insertionSet.execute();
        m_graph.resetReachability();
        m_graph.killUnreachableBlocks();
        return true;
    }
    bool run()
    {
        RELEASE_ASSERT(m_graph.m_plan.mode == FTLForOSREntryMode);
        RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);

        unsigned bytecodeIndex = m_graph.m_plan.osrEntryBytecodeIndex;
        RELEASE_ASSERT(bytecodeIndex);
        RELEASE_ASSERT(bytecodeIndex != UINT_MAX);

        // Needed by createPreHeader().
        m_graph.m_dominators.computeIfNecessary(m_graph);

        CodeBlock* baseline = m_graph.m_profiledBlock;

        BasicBlock* target = 0;
        for (unsigned blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            unsigned nodeIndex = 0;
            Node* firstNode = block->at(0);
            while (firstNode->isSemanticallySkippable())
                firstNode = block->at(++nodeIndex);
            if (firstNode->op() == LoopHint
                    && firstNode->origin.semantic == CodeOrigin(bytecodeIndex)) {
                target = block;
                break;
            }
        }

        if (!target) {
            // This is a terrible outcome. It shouldn't often happen but it might
            // happen and so we should defend against it. If it happens, then this
            // compilation is a failure.
            return false;
        }

        BlockInsertionSet insertionSet(m_graph);

        BasicBlock* newRoot = insertionSet.insert(0, QNaN);
        NodeOrigin origin = target->at(0)->origin;

        Vector<Node*> locals(baseline->m_numCalleeRegisters);
        for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) {
            Node* previousHead = target->variablesAtHead.local(local);
            if (!previousHead)
                continue;
            VariableAccessData* variable = previousHead->variableAccessData();
            locals[local] = newRoot->appendNode(
                                m_graph, variable->prediction(), ExtractOSREntryLocal, origin,
                                OpInfo(variable->local().offset()));

            newRoot->appendNode(
                m_graph, SpecNone, MovHint, origin, OpInfo(variable->local().offset()),
                Edge(locals[local]));
        }

        for (int argument = 0; argument < baseline->numParameters(); ++argument) {
            Node* oldNode = target->variablesAtHead.argument(argument);
            if (!oldNode) {
                // Just for sanity, always have a SetArgument even if it's not needed.
                oldNode = m_graph.m_arguments[argument];
            }
            Node* node = newRoot->appendNode(
                             m_graph, SpecNone, SetArgument, origin,
                             OpInfo(oldNode->variableAccessData()));
            m_graph.m_arguments[argument] = node;
        }

        for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) {
            Node* previousHead = target->variablesAtHead.local(local);
            if (!previousHead)
                continue;
            VariableAccessData* variable = previousHead->variableAccessData();
            Node* node = locals[local];
            newRoot->appendNode(
                m_graph, SpecNone, SetLocal, origin, OpInfo(variable), Edge(node));
        }

        newRoot->appendNode(
            m_graph, SpecNone, Jump, origin,
            OpInfo(createPreHeader(m_graph, insertionSet, target)));

        insertionSet.execute();
        m_graph.resetReachability();
        m_graph.killUnreachableBlocks();
        return true;
    }