/*
 * Copyright (C) 2011, 2013 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. 
 */

#pragma once

#if ENABLE(DFG_JIT)

#include "DFGMinifiedID.h"
#include "DFGVariableEvent.h"
#include "DFGVariableEventStream.h"
#include "DataFormat.h"

namespace JSC { namespace DFG {

// === GenerationInfo ===
//
// This class is used to track the current status of live values during code generation.
// Can provide information as to whether a value is in machine registers, and if so which,
// whether a value has been spilled to the RegisterFile, and if so may be able to provide
// details of the format in memory (all values are spilled in a boxed form, but we may be
// able to track the type of box), and tracks how many outstanding uses of a value remain,
// so that we know when the value is dead and the machine registers associated with it
// may be released.
class GenerationInfo {
public:
    GenerationInfo()
        : m_node(0)
        , m_useCount(0)
        , m_registerFormat(DataFormatNone)
        , m_spillFormat(DataFormatNone)
        , m_canFill(false)
        , m_bornForOSR(false)
        , m_isConstant(false)
    {
    }

    void initConstant(Node* node, uint32_t useCount)
    {
        m_node = node;
        m_useCount = useCount;
        m_registerFormat = DataFormatNone;
        m_spillFormat = DataFormatNone;
        m_canFill = true;
        m_bornForOSR = false;
        m_isConstant = true;
        ASSERT(m_useCount);
    }
    void initGPR(Node* node, uint32_t useCount, GPRReg gpr, DataFormat format)
    {
        ASSERT(gpr != InvalidGPRReg);
        m_node = node;
        m_useCount = useCount;
        m_registerFormat = format;
        m_spillFormat = DataFormatNone;
        m_canFill = false;
        u.gpr = gpr;
        m_bornForOSR = false;
        m_isConstant = false;
        ASSERT(m_useCount);
    }
    void initInt32(Node* node, uint32_t useCount, GPRReg gpr)
    {
        initGPR(node, useCount, gpr, DataFormatInt32);
    }
    void initInt52(Node* node, uint32_t useCount, GPRReg reg, DataFormat format)
    {
        ASSERT(format == DataFormatInt52 || format == DataFormatStrictInt52);
        initGPR(node, useCount, reg, format);
    }
    void initInt52(Node* node, uint32_t useCount, GPRReg reg)
    {
        initGPR(node, useCount, reg, DataFormatInt52);
    }
    void initStrictInt52(Node* node, uint32_t useCount, GPRReg reg)
    {
        initGPR(node, useCount, reg, DataFormatStrictInt52);
    }
#if USE(JSVALUE64)
    void initJSValue(Node* node, uint32_t useCount, GPRReg gpr, DataFormat format = DataFormatJS)
    {
        ASSERT(format & DataFormatJS);
        initGPR(node, useCount, gpr, format);
    }
#elif USE(JSVALUE32_64)
    void initJSValue(Node* node, uint32_t useCount, GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
    {
        ASSERT(format & DataFormatJS);

        m_node = node;
        m_useCount = useCount;
        m_registerFormat = format;
        m_spillFormat = DataFormatNone;
        m_canFill = false;
        u.v.tagGPR = tagGPR;
        u.v.payloadGPR = payloadGPR;
        m_bornForOSR = false;
        m_isConstant = false;
        ASSERT(m_useCount);
    }
#endif
    void initCell(Node* node, uint32_t useCount, GPRReg gpr)
    {
        initGPR(node, useCount, gpr, DataFormatCell);
    }
    void initBoolean(Node* node, uint32_t useCount, GPRReg gpr)
    {
        initGPR(node, useCount, gpr, DataFormatBoolean);
    }
    void initDouble(Node* node, uint32_t useCount, FPRReg fpr)
    {
        ASSERT(fpr != InvalidFPRReg);
        m_node = node;
        m_useCount = useCount;
        m_registerFormat = DataFormatDouble;
        m_spillFormat = DataFormatNone;
        m_canFill = false;
        u.fpr = fpr;
        m_bornForOSR = false;
        m_isConstant = false;
        ASSERT(m_useCount);
    }
    void initStorage(Node* node, uint32_t useCount, GPRReg gpr)
    {
        initGPR(node, useCount, gpr, DataFormatStorage);
    }

    // Get the node that produced this value.
    Node* node() { return m_node; }
    
    void noticeOSRBirth(VariableEventStream& stream, Node* node, VirtualRegister virtualRegister)
    {
        if (m_node != node)
            return;
        if (!alive())
            return;
        if (m_bornForOSR)
            return;
        
        m_bornForOSR = true;
        
        if (m_isConstant)
            appendBirth(stream);
        else if (m_registerFormat != DataFormatNone)
            appendFill(BirthToFill, stream);
        else if (m_spillFormat != DataFormatNone)
            appendSpill(BirthToSpill, stream, virtualRegister);
    }

    // Mark the value as having been used (decrement the useCount).
    // Returns true if this was the last use of the value, and any
    // associated machine registers may be freed.
    bool use(VariableEventStream& stream)
    {
        ASSERT(m_useCount);
        bool result = !--m_useCount;
        
        if (result && m_bornForOSR) {
            ASSERT(m_node);
            stream.appendAndLog(VariableEvent::death(MinifiedID(m_node)));
        }
        
        return result;
    }

    // Used to check the operands of operations to see if they are on
    // their last use; in some cases it may be safe to reuse the same
    // machine register for the result of the operation.
    uint32_t useCount()
    {
        ASSERT(m_useCount);
        return m_useCount;
    }

    // Get the format of the value in machine registers (or 'none').
    DataFormat registerFormat() { return m_registerFormat; }
    // Get the format of the value as it is spilled in the JSStack (or 'none').
    DataFormat spillFormat() { return m_spillFormat; }
    
    bool isFormat(DataFormat expectedFormat)
    {
        return registerFormat() == expectedFormat || spillFormat() == expectedFormat;
    }
    
    bool isJSFormat(DataFormat expectedFormat)
    {
        return JSC::isJSFormat(registerFormat(), expectedFormat) || JSC::isJSFormat(spillFormat(), expectedFormat);
    }
    
    bool isJSInt32()
    {
        return isJSFormat(DataFormatJSInt32);
    }
    
    bool isInt52()
    {
        return isFormat(DataFormatInt52);
    }
    
    bool isStrictInt52()
    {
        return isFormat(DataFormatStrictInt52);
    }
    
    bool isJSDouble()
    {
        return isJSFormat(DataFormatJSDouble);
    }
    
    bool isJSCell()
    {
        return isJSFormat(DataFormatJSCell);
    }
    
    bool isJSBoolean()
    {
        return isJSFormat(DataFormatJSBoolean);
    }
    
    bool isUnknownJS()
    {
        return spillFormat() == DataFormatNone
            ? registerFormat() == DataFormatJS || registerFormat() == DataFormatNone
            : spillFormat() == DataFormatJS;
    }

    // Get the machine resister currently holding the value.
#if USE(JSVALUE64)
    GPRReg gpr() { ASSERT(m_registerFormat && m_registerFormat != DataFormatDouble); return u.gpr; }
    FPRReg fpr() { ASSERT(m_registerFormat == DataFormatDouble); return u.fpr; }
    JSValueRegs jsValueRegs() { ASSERT(m_registerFormat & DataFormatJS); return JSValueRegs(u.gpr); }
#elif USE(JSVALUE32_64)
    GPRReg gpr() { ASSERT(!(m_registerFormat & DataFormatJS) && m_registerFormat != DataFormatDouble); return u.gpr; }
    GPRReg tagGPR() { ASSERT(m_registerFormat & DataFormatJS); return u.v.tagGPR; }
    GPRReg payloadGPR() { ASSERT(m_registerFormat & DataFormatJS); return u.v.payloadGPR; }
    FPRReg fpr() { ASSERT(m_registerFormat == DataFormatDouble || m_registerFormat == DataFormatJSDouble); return u.fpr; }
    JSValueRegs jsValueRegs() { ASSERT(m_registerFormat & DataFormatJS); return JSValueRegs(u.v.tagGPR, u.v.payloadGPR); }
#endif

    // Check whether a value needs spilling in order to free up any associated machine registers.
    bool needsSpill()
    {
        // This should only be called on values that are currently in a register.
        ASSERT(m_registerFormat != DataFormatNone);
        // Constants do not need spilling, nor do values that have already been
        // spilled to the JSStack.
        return !m_canFill;
    }

    // Called when a VirtualRegister is being spilled to the JSStack for the first time.
    void spill(VariableEventStream& stream, VirtualRegister virtualRegister, DataFormat spillFormat)
    {
        // We shouldn't be spill values that don't need spilling.
        ASSERT(!m_canFill);
        ASSERT(m_spillFormat == DataFormatNone);
        // We should only be spilling values that are currently in machine registers.
        ASSERT(m_registerFormat != DataFormatNone);

        m_registerFormat = DataFormatNone;
        m_spillFormat = spillFormat;
        m_canFill = true;
        
        if (m_bornForOSR)
            appendSpill(Spill, stream, virtualRegister);
    }

    // Called on values that don't need spilling (constants and values that have
    // already been spilled), to mark them as no longer being in machine registers.
    void setSpilled(VariableEventStream& stream, VirtualRegister virtualRegister)
    {
        // Should only be called on values that don't need spilling, and are currently in registers.
        ASSERT(m_canFill && m_registerFormat != DataFormatNone);
        m_registerFormat = DataFormatNone;
        
        if (m_bornForOSR)
            appendSpill(Spill, stream, virtualRegister);
    }
    
    void killSpilled()
    {
        m_spillFormat = DataFormatNone;
        m_canFill = false;
    }
    
    void fillGPR(VariableEventStream& stream, GPRReg gpr, DataFormat format)
    {
        ASSERT(gpr != InvalidGPRReg);
        m_registerFormat = format;
        u.gpr = gpr;
        if (m_bornForOSR)
            appendFill(Fill, stream);
    }

    // Record that this value is filled into machine registers,
    // tracking which registers, and what format the value has.
#if USE(JSVALUE64)
    void fillJSValue(VariableEventStream& stream, GPRReg gpr, DataFormat format = DataFormatJS)
    {
        ASSERT(format & DataFormatJS);
        fillGPR(stream, gpr, format);
    }
#elif USE(JSVALUE32_64)
    void fillJSValue(VariableEventStream& stream, GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
    {
        ASSERT(format & DataFormatJS);
        m_registerFormat = format;
        u.v.tagGPR = tagGPR; // FIXME: for JSValues with known type (boolean, integer, cell etc.) no tagGPR is needed?
        u.v.payloadGPR = payloadGPR;
        
        if (m_bornForOSR)
            appendFill(Fill, stream);
    }
    void fillCell(VariableEventStream& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatCell);
    }
#endif
    void fillInt32(VariableEventStream& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatInt32);
    }
    void fillInt52(VariableEventStream& stream, GPRReg gpr, DataFormat format)
    {
        ASSERT(format == DataFormatInt52 || format == DataFormatStrictInt52);
        fillGPR(stream, gpr, format);
    }
    void fillInt52(VariableEventStream& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatInt52);
    }
    void fillStrictInt52(VariableEventStream& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatStrictInt52);
    }
    void fillBoolean(VariableEventStream& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatBoolean);
    }
    void fillDouble(VariableEventStream& stream, FPRReg fpr)
    {
        ASSERT(fpr != InvalidFPRReg);
        m_registerFormat = DataFormatDouble;
        u.fpr = fpr;
        
        if (m_bornForOSR)
            appendFill(Fill, stream);
    }
    void fillStorage(VariableEventStream& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatStorage);
    }

    bool alive()
    {
        return m_useCount;
    }

    ValueRecovery recovery(VirtualRegister spillSlot) const
    {
        if (m_isConstant)
            return ValueRecovery::constant(m_node->constant()->value());

        if (m_registerFormat == DataFormatDouble)
            return ValueRecovery::inFPR(u.fpr, DataFormatDouble);

#if USE(JSVALUE32_64)
        if (m_registerFormat & DataFormatJS) {
            if (m_registerFormat == DataFormatJS)
                return ValueRecovery::inPair(u.v.tagGPR, u.v.payloadGPR);
            return ValueRecovery::inGPR(u.v.payloadGPR, static_cast<DataFormat>(m_registerFormat & ~DataFormatJS));
        }
#endif
        if (m_registerFormat)
            return ValueRecovery::inGPR(u.gpr, m_registerFormat);

        ASSERT(m_spillFormat);

        return ValueRecovery::displacedInJSStack(spillSlot, m_spillFormat);
    }

private:
    void appendBirth(VariableEventStream& stream)
    {
        stream.appendAndLog(VariableEvent::birth(MinifiedID(m_node)));
    }
    
    void appendFill(VariableEventKind kind, VariableEventStream& stream)
    {
        ASSERT(m_bornForOSR);
        
        if (m_registerFormat == DataFormatDouble) {
            stream.appendAndLog(VariableEvent::fillFPR(kind, MinifiedID(m_node), u.fpr));
            return;
        }
#if USE(JSVALUE32_64)
        if (m_registerFormat & DataFormatJS) {
            stream.appendAndLog(VariableEvent::fillPair(kind, MinifiedID(m_node), u.v.tagGPR, u.v.payloadGPR));
            return;
        }
#endif
        stream.appendAndLog(VariableEvent::fillGPR(kind, MinifiedID(m_node), u.gpr, m_registerFormat));
    }
    
    void appendSpill(VariableEventKind kind, VariableEventStream& stream, VirtualRegister virtualRegister)
    {
        stream.appendAndLog(VariableEvent::spill(kind, MinifiedID(m_node), virtualRegister, m_spillFormat));
    }
    
    // The node whose result is stored in this virtual register.
    Node* m_node;
    uint32_t m_useCount;
    DataFormat m_registerFormat;
    DataFormat m_spillFormat;
    bool m_canFill;
    bool m_bornForOSR;
    bool m_isConstant;
    union {
        GPRReg gpr;
        FPRReg fpr;
#if USE(JSVALUE32_64)
        struct {
            GPRReg tagGPR;
            GPRReg payloadGPR;
        } v;
#endif
    } u;
};

} } // namespace JSC::DFG

#endif
