/*
 * 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 "DFGMinifiedIDInlines.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, 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(nullptr)
        , 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(VariableEventStreamBuilder& 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(VariableEventStreamBuilder& 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(VariableEventStreamBuilder& 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(VariableEventStreamBuilder& 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(VariableEventStreamBuilder& 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(VariableEventStreamBuilder& stream, GPRReg gpr, DataFormat format = DataFormatJS)
    {
        ASSERT(format & DataFormatJS);
        fillGPR(stream, gpr, format);
    }
#elif USE(JSVALUE32_64)
    void fillJSValue(VariableEventStreamBuilder& 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(VariableEventStreamBuilder& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatCell);
    }
#endif
    void fillInt32(VariableEventStreamBuilder& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatInt32);
    }
    void fillInt52(VariableEventStreamBuilder& stream, GPRReg gpr, DataFormat format)
    {
        ASSERT(format == DataFormatInt52 || format == DataFormatStrictInt52);
        fillGPR(stream, gpr, format);
    }
    void fillInt52(VariableEventStreamBuilder& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatInt52);
    }
    void fillStrictInt52(VariableEventStreamBuilder& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatStrictInt52);
    }
    void fillBoolean(VariableEventStreamBuilder& stream, GPRReg gpr)
    {
        fillGPR(stream, gpr, DataFormatBoolean);
    }
    void fillDouble(VariableEventStreamBuilder& stream, FPRReg fpr)
    {
        ASSERT(fpr != InvalidFPRReg);
        m_registerFormat = DataFormatDouble;
        u.fpr = fpr;
        
        if (m_bornForOSR)
            appendFill(Fill, stream);
    }
    void fillStorage(VariableEventStreamBuilder& 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(VariableEventStreamBuilder& stream)
    {
        stream.appendAndLog(VariableEvent::birth(MinifiedID(m_node)));
    }
    
    void appendFill(VariableEventKind kind, VariableEventStreamBuilder& 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, VariableEventStreamBuilder& 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
