/*
 * Copyright (C) 2011 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 "DFGVirtualRegisterAllocationPhase.h"

#if ENABLE(DFG_JIT)

#include "DFGGraph.h"
#include "DFGScoreBoard.h"

namespace JSC { namespace DFG {

class VirtualRegisterAllocationPhase : public Phase {
public:
    VirtualRegisterAllocationPhase(Graph& graph)
        : Phase(graph, "virtual register allocation")
    {
    }
    
    bool run()
    {
#if DFG_ENABLE(DEBUG_VERBOSE)
        dataLogF("Preserved vars: ");
        m_graph.m_preservedVars.dump(WTF::dataFile());
        dataLogF("\n");
#endif
        ScoreBoard scoreBoard(m_graph, m_graph.m_preservedVars);
        scoreBoard.assertClear();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        bool needsNewLine = false;
#endif
        for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
            if (!block)
                continue;
            if (!block->isReachable)
                continue;
            for (size_t indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
                NodeIndex nodeIndex = block->at(indexInBlock);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
                if (needsNewLine)
                    dataLogF("\n");
                dataLogF("   @%u:", nodeIndex);
                needsNewLine = true;
#endif
                Node& node = m_graph[nodeIndex];
        
                if (!node.shouldGenerate() || node.op() == Phi || node.op() == Flush)
                    continue;
                
                if (node.op() == GetLocal)
                    ASSERT(!m_graph[node.child1()].hasResult());
                
                // First, call use on all of the current node's children, then
                // allocate a VirtualRegister for this node. We do so in this
                // order so that if a child is on its last use, and a
                // VirtualRegister is freed, then it may be reused for node.
                if (node.flags() & NodeHasVarArgs) {
                    for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
                        scoreBoard.useIfHasResult(m_graph.m_varArgChildren[childIdx]);
                } else {
                    scoreBoard.useIfHasResult(node.child1());
                    scoreBoard.useIfHasResult(node.child2());
                    scoreBoard.useIfHasResult(node.child3());
                }

                if (!node.hasResult())
                    continue;

                VirtualRegister virtualRegister = scoreBoard.allocate();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
                dataLogF(" Assigning virtual register %u to node %u.",
                        virtualRegister, nodeIndex);
#endif
                node.setVirtualRegister(virtualRegister);
                // 'mustGenerate' nodes have their useCount artificially elevated,
                // call use now to account for this.
                if (node.mustGenerate())
                    scoreBoard.use(nodeIndex);
            }
            scoreBoard.assertClear();
        }
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        if (needsNewLine)
            dataLogF("\n");
#endif

        // 'm_numCalleeRegisters' is the number of locals and temporaries allocated
        // for the function (and checked for on entry). Since we perform a new and
        // different allocation of temporaries, more registers may now be required.
        unsigned calleeRegisters = scoreBoard.highWatermark() + m_graph.m_parameterSlots;
        size_t inlineCallFrameCount = codeBlock()->inlineCallFrames().size();
        for (size_t i = 0; i < inlineCallFrameCount; i++) {
            InlineCallFrame& inlineCallFrame = codeBlock()->inlineCallFrames()[i];
            CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(&inlineCallFrame);
            unsigned requiredCalleeRegisters = inlineCallFrame.stackOffset + codeBlock->m_numCalleeRegisters;
            if (requiredCalleeRegisters > calleeRegisters)
                calleeRegisters = requiredCalleeRegisters;
        }
        if ((unsigned)codeBlock()->m_numCalleeRegisters < calleeRegisters)
            codeBlock()->m_numCalleeRegisters = calleeRegisters;
#if DFG_ENABLE(DEBUG_VERBOSE)
        dataLogF("Num callee registers: %u\n", calleeRegisters);
#endif
        
        return true;
    }
};

bool performVirtualRegisterAllocation(Graph& graph)
{
    SamplingRegion samplingRegion("DFG Virtual Register Allocation Phase");
    return runPhase<VirtualRegisterAllocationPhase>(graph);
}

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)
