/*
 * Copyright (C) 2012-2015 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 "DFGCFGSimplificationPhase.h"

#if ENABLE(DFG_JIT)

#include "DFGBasicBlockInlines.h"
#include "DFGGraph.h"
#include "DFGPhase.h"
#include "JSCJSValueInlines.h"

namespace JSC { namespace DFG {

class CFGSimplificationPhase : public Phase {
public:
    CFGSimplificationPhase(Graph& graph)
        : Phase(graph, "CFG simplification")
    {
    }

    bool canMergeBlocks(BasicBlock* block, BasicBlock* targetBlock)
    {
        return targetBlock->predecessors.size() == 1 && targetBlock != block;
    }
    
    bool run()
    {
        // FIXME: We should make this work in SSA. https://bugs.webkit.org/show_bug.cgi?id=148260
        DFG_ASSERT(m_graph, nullptr, m_graph.m_form != SSA);
        
        const bool extremeLogging = false;

        bool outerChanged = false;
        bool innerChanged;
        
        do {
            innerChanged = false;
            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
                BasicBlock* block = m_graph.block(blockIndex);
                if (!block)
                    continue;
                ASSERT(block->isReachable);

                auto canMergeWithBlock = [&] (BasicBlock* targetBlock) {
                    return canMergeBlocks(block, targetBlock);
                };
            
                switch (block->terminal()->op()) {
                case Jump: {
                    // Successor with one predecessor -> merge.
                    if (canMergeWithBlock(block->successor(0))) {
                        ASSERT(block->successor(0)->predecessors[0] == block);
                        if (extremeLogging)
                            m_graph.dump();
                        m_graph.dethread();
                        mergeBlocks(block, block->successor(0), noBlocks());
                        innerChanged = outerChanged = true;
                        break;
                    }
                
                    // FIXME: Block only has a jump -> remove. This is tricky though because of
                    // liveness. What we really want is to slam in a phantom at the end of the
                    // block, after the terminal. But we can't right now. :-(
                    // Idea: what if I slam the ghosties into my successor? Nope, that's
                    // suboptimal, because if my successor has multiple predecessors then we'll
                    // be keeping alive things on other predecessor edges unnecessarily.
                    // What we really need is the notion of end-of-block ghosties!
                    // FIXME: Allow putting phantoms after terminals.
                    // https://bugs.webkit.org/show_bug.cgi?id=126778
                    break;
                }
                
                case Branch: {
                    // Branch on constant -> jettison the not-taken block and merge.
                    if (isKnownDirection(block->cfaBranchDirection)) {
                        bool condition = branchCondition(block->cfaBranchDirection);
                        BasicBlock* targetBlock = block->successorForCondition(condition);
                        BasicBlock* jettisonedBlock = block->successorForCondition(!condition);
                        if (canMergeWithBlock(targetBlock)) {
                            if (extremeLogging)
                                m_graph.dump();
                            m_graph.dethread();
                            if (targetBlock == jettisonedBlock)
                                mergeBlocks(block, targetBlock, noBlocks());
                            else
                                mergeBlocks(block, targetBlock, oneBlock(jettisonedBlock));
                        } else {
                            if (extremeLogging)
                                m_graph.dump();
                            m_graph.dethread();
                            
                            Node* terminal = block->terminal();
                            ASSERT(terminal->isTerminal());
                            NodeOrigin boundaryNodeOrigin = terminal->origin;

                            if (targetBlock != jettisonedBlock)
                                jettisonBlock(block, jettisonedBlock, boundaryNodeOrigin);

                            block->replaceTerminal(
                                m_graph, SpecNone, Jump, boundaryNodeOrigin,
                                OpInfo(targetBlock));
                            
                            ASSERT(block->terminal());
                        
                        }
                        innerChanged = outerChanged = true;
                        break;
                    }
                    
                    if (block->successor(0) == block->successor(1)) {
                        convertToJump(block, block->successor(0));
                        innerChanged = outerChanged = true;
                        break;
                    }

                    // Branch to same destination -> jump.
                    // FIXME: this will currently not be hit because of the lack of jump-only
                    // block simplification.
                    
                    break;
                }
                    
                case Switch: {
                    SwitchData* data = block->terminal()->switchData();
                    
                    // Prune out cases that end up jumping to default.
                    for (unsigned i = 0; i < data->cases.size(); ++i) {
                        if (data->cases[i].target.block == data->fallThrough.block) {
                            data->fallThrough.count += data->cases[i].target.count;
                            data->cases[i--] = data->cases.last();
                            data->cases.removeLast();
                        }
                    }
                    
                    // If there are no cases other than default then this turns
                    // into a jump.
                    if (data->cases.isEmpty()) {
                        convertToJump(block, data->fallThrough.block);
                        innerChanged = outerChanged = true;
                        break;
                    }
                    
                    // Switch on constant -> jettison all other targets and merge.
                    Node* terminal = block->terminal();
                    if (terminal->child1()->hasConstant()) {
                        FrozenValue* value = terminal->child1()->constant();
                        TriState found = TriState::False;
                        BasicBlock* targetBlock = nullptr;
                        for (unsigned i = data->cases.size(); found == TriState::False && i--;) {
                            found = data->cases[i].value.strictEqual(value);
                            if (found == TriState::True)
                                targetBlock = data->cases[i].target.block;
                        }
                        
                        if (found == TriState::Indeterminate)
                            break;
                        if (found == TriState::False)
                            targetBlock = data->fallThrough.block;
                        ASSERT(targetBlock);
                        
                        Vector<BasicBlock*, 1> jettisonedBlocks;
                        for (BasicBlock* successor : terminal->successors()) {
                            if (successor != targetBlock && !jettisonedBlocks.contains(successor))
                                jettisonedBlocks.append(successor);
                        }
                        
                        if (canMergeWithBlock(targetBlock)) {
                            if (extremeLogging)
                                m_graph.dump();
                            m_graph.dethread();
                            
                            mergeBlocks(block, targetBlock, jettisonedBlocks);
                        } else {
                            if (extremeLogging)
                                m_graph.dump();
                            m_graph.dethread();
                            
                            NodeOrigin boundaryNodeOrigin = terminal->origin;

                            for (unsigned i = jettisonedBlocks.size(); i--;)
                                jettisonBlock(block, jettisonedBlocks[i], boundaryNodeOrigin);
                            
                            block->replaceTerminal(
                                m_graph, SpecNone, Jump, boundaryNodeOrigin, OpInfo(targetBlock));
                        }
                        innerChanged = outerChanged = true;
                        break;
                    }
                    break;
                }
                    
                default:
                    break;
                }
            }
            
            if (innerChanged) {
                // Here's the reason for this pass:
                // Blocks: A, B, C, D, E, F
                // A -> B, C
                // B -> F
                // C -> D, E
                // D -> F
                // E -> F
                //
                // Assume that A's branch is determined to go to B. Then the rest of this phase
                // is smart enough to simplify down to:
                // A -> B
                // B -> F
                // C -> D, E
                // D -> F
                // E -> F
                //
                // We will also merge A and B. But then we don't have any other mechanism to
                // remove D, E as predecessors for F. Worse, the rest of this phase does not
                // know how to fix the Phi functions of F to ensure that they no longer refer
                // to variables in D, E. In general, we need a way to handle Phi simplification
                // upon:
                // 1) Removal of a predecessor due to branch simplification. The branch
                //    simplifier already does that.
                // 2) Invalidation of a predecessor because said predecessor was rendered
                //    unreachable. We do this here.
                //
                // This implies that when a block is unreachable, we must inspect its
                // successors' Phi functions to remove any references from them into the
                // removed block.
                
                m_graph.invalidateCFG();
                m_graph.resetReachability();
                m_graph.killUnreachableBlocks();
            }
            
            if (Options::validateGraphAtEachPhase())
                validate();
        } while (innerChanged);
        
        return outerChanged;
    }

private:
    void convertToJump(BasicBlock* block, BasicBlock* targetBlock)
    {
        ASSERT(targetBlock);
        ASSERT(targetBlock->isReachable);
        if (canMergeBlocks(block, targetBlock)) {
            m_graph.dethread();
            mergeBlocks(block, targetBlock, noBlocks());
        } else {
            Node* branch = block->terminal();
            ASSERT(branch->op() == Branch || branch->op() == Switch);

            block->replaceTerminal(
                m_graph, SpecNone, Jump, branch->origin, OpInfo(targetBlock));
        }
    }
    
    void keepOperandAlive(BasicBlock* block, BasicBlock* jettisonedBlock, NodeOrigin nodeOrigin, Operand operand)
    {
        Node* livenessNode = jettisonedBlock->variablesAtHead.operand(operand);
        if (!livenessNode)
            return;
        NodeType nodeType;
        if (livenessNode->flags() & NodeIsFlushed)
            nodeType = Flush;
        else {
            // This seems like it shouldn't be necessary because we could just rematerialize
            // PhantomLocals or something similar using bytecode liveness. However, in ThreadedCPS, it's
            // worth the sanity to maintain this eagerly. See
            // https://bugs.webkit.org/show_bug.cgi?id=144086
            nodeType = PhantomLocal;
        }
        block->appendNode(
            m_graph, SpecNone, nodeType, nodeOrigin, 
            OpInfo(livenessNode->variableAccessData()));
    }
    
    void jettisonBlock(BasicBlock* block, BasicBlock* jettisonedBlock, NodeOrigin boundaryNodeOrigin)
    {
        for (size_t i = 0; i < jettisonedBlock->variablesAtHead.size(); ++i)
            keepOperandAlive(block, jettisonedBlock, boundaryNodeOrigin, jettisonedBlock->variablesAtHead.operandForIndex(i));

        fixJettisonedPredecessors(block, jettisonedBlock);
    }
    
    void fixJettisonedPredecessors(BasicBlock* block, BasicBlock* jettisonedBlock)
    {
        jettisonedBlock->removePredecessor(block);
    }

    Vector<BasicBlock*, 1> noBlocks()
    {
        return Vector<BasicBlock*, 1>();
    }
    
    Vector<BasicBlock*, 1> oneBlock(BasicBlock* block)
    {
        Vector<BasicBlock*, 1> result;
        result.append(block);
        return result;
    }
    
    void mergeBlocks(
        BasicBlock* firstBlock, BasicBlock* secondBlock,
        Vector<BasicBlock*, 1> jettisonedBlocks)
    {
        RELEASE_ASSERT(canMergeBlocks(firstBlock, secondBlock));
        // This will add all of the nodes in secondBlock to firstBlock, but in so doing
        // it will also ensure that any GetLocals from the second block that refer to
        // SetLocals in the first block are relinked. If jettisonedBlock is not NoBlock,
        // then Phantoms are inserted for anything that the jettisonedBlock would have
        // kept alive.
        
        // Remove the terminal of firstBlock since we don't need it anymore. Well, we don't
        // really remove it; we actually turn it into a check.
        Node* terminal = firstBlock->terminal();
        ASSERT(terminal->isTerminal());
        NodeOrigin boundaryNodeOrigin = terminal->origin;
        terminal->remove(m_graph);
        ASSERT(terminal->refCount() == 1);
        
        for (unsigned i = jettisonedBlocks.size(); i--;) {
            BasicBlock* jettisonedBlock = jettisonedBlocks[i];
            
            // Time to insert ghosties for things that need to be kept alive in case we OSR
            // exit prior to hitting the firstBlock's terminal, and end up going down a
            // different path than secondBlock.
            for (size_t i = 0; i < jettisonedBlock->variablesAtHead.size(); ++i)
                keepOperandAlive(firstBlock, jettisonedBlock, boundaryNodeOrigin, jettisonedBlock->variablesAtHead.operandForIndex(i));
        }
        
        for (size_t i = 0; i < secondBlock->phis.size(); ++i)
            firstBlock->phis.append(secondBlock->phis[i]);

        for (size_t i = 0; i < secondBlock->size(); ++i)
            firstBlock->append(secondBlock->at(i));
        
        ASSERT(firstBlock->terminal()->isTerminal());
        
        // Fix the predecessors of my new successors. This is tricky, since we are going to reset
        // all predecessors anyway due to reachability analysis. But we need to fix the
        // predecessors eagerly to ensure that we know what they are in case the next block we
        // consider in this phase wishes to query the predecessors of one of the blocks we
        // affected.
        for (unsigned i = firstBlock->numSuccessors(); i--;) {
            BasicBlock* successor = firstBlock->successor(i);
            for (unsigned j = 0; j < successor->predecessors.size(); ++j) {
                if (successor->predecessors[j] == secondBlock)
                    successor->predecessors[j] = firstBlock;
            }
        }
        
        // Fix the predecessors of my former successors. Again, we'd rather not do this, but it's
        // an unfortunate necessity. See above comment.
        for (unsigned i = jettisonedBlocks.size(); i--;)
            fixJettisonedPredecessors(firstBlock, jettisonedBlocks[i]);
        
        firstBlock->valuesAtTail = secondBlock->valuesAtTail;
        firstBlock->cfaBranchDirection = secondBlock->cfaBranchDirection;
        
        m_graph.killBlock(secondBlock);
    }
};

bool performCFGSimplification(Graph& graph)
{
    return runPhase<CFGSimplificationPhase>(graph);
}

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)


