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

#ifndef DFGVariableAccessData_h
#define DFGVariableAccessData_h

#include "DFGDoubleFormatState.h"
#include "DFGFlushFormat.h"
#include "DFGFlushedAt.h"
#include "DFGNodeFlags.h"
#include "Operands.h"
#include "SpeculatedType.h"
#include "VirtualRegister.h"
#include <wtf/Platform.h>
#include <wtf/UnionFind.h>
#include <wtf/Vector.h>

namespace JSC { namespace DFG {

enum DoubleBallot { VoteValue, VoteDouble };

class VariableAccessData : public UnionFind<VariableAccessData> {
public:
    VariableAccessData()
        : m_local(static_cast<VirtualRegister>(std::numeric_limits<int>::min()))
        , m_prediction(SpecNone)
        , m_argumentAwarePrediction(SpecNone)
        , m_flags(0)
        , m_isCaptured(false)
        , m_shouldNeverUnbox(false)
        , m_isArgumentsAlias(false)
        , m_structureCheckHoistingFailed(false)
        , m_checkArrayHoistingFailed(false)
        , m_isProfitableToUnbox(false)
        , m_isLoadedFrom(false)
        , m_doubleFormatState(EmptyDoubleFormatState)
    {
        clearVotes();
    }
    
    VariableAccessData(VirtualRegister local, bool isCaptured)
        : m_local(local)
        , m_prediction(SpecNone)
        , m_argumentAwarePrediction(SpecNone)
        , m_flags(0)
        , m_isCaptured(isCaptured)
        , m_shouldNeverUnbox(isCaptured)
        , m_isArgumentsAlias(false)
        , m_structureCheckHoistingFailed(false)
        , m_checkArrayHoistingFailed(false)
        , m_isProfitableToUnbox(false)
        , m_doubleFormatState(EmptyDoubleFormatState)
    {
        clearVotes();
    }
    
    VirtualRegister local()
    {
        ASSERT(m_local == find()->m_local);
        return m_local;
    }
    
    VirtualRegister& machineLocal()
    {
        ASSERT(find() == this);
        return m_machineLocal;
    }

    bool mergeIsCaptured(bool isCaptured)
    {
        return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | isCaptured)
            | checkAndSet(m_isCaptured, m_isCaptured | isCaptured);
    }
    
    bool isCaptured()
    {
        return m_isCaptured;
    }
    
    bool mergeIsProfitableToUnbox(bool isProfitableToUnbox)
    {
        return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | isProfitableToUnbox);
    }
    
    bool isProfitableToUnbox()
    {
        return m_isProfitableToUnbox;
    }
    
    bool mergeShouldNeverUnbox(bool shouldNeverUnbox)
    {
        bool newShouldNeverUnbox = m_shouldNeverUnbox | shouldNeverUnbox;
        if (newShouldNeverUnbox == m_shouldNeverUnbox)
            return false;
        m_shouldNeverUnbox = newShouldNeverUnbox;
        return true;
    }
    
    // Returns true if it would be unsound to store the value in an unboxed fashion.
    // If this returns false, it simply means that it is sound to unbox; it doesn't
    // mean that we have actually done so.
    bool shouldNeverUnbox()
    {
        ASSERT(!(m_isCaptured && !m_shouldNeverUnbox));
        return m_shouldNeverUnbox;
    }
    
    // Returns true if we should be unboxing the value provided that the predictions
    // and double format vote say so. This may return false even if shouldNeverUnbox()
    // returns false, since this incorporates heuristics of profitability.
    bool shouldUnboxIfPossible()
    {
        return !shouldNeverUnbox() && isProfitableToUnbox();
    }

    bool mergeStructureCheckHoistingFailed(bool failed)
    {
        return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed | failed);
    }
    
    bool mergeCheckArrayHoistingFailed(bool failed)
    {
        return checkAndSet(m_checkArrayHoistingFailed, m_checkArrayHoistingFailed | failed);
    }
    
    bool structureCheckHoistingFailed()
    {
        return m_structureCheckHoistingFailed;
    }
    
    bool checkArrayHoistingFailed()
    {
        return m_checkArrayHoistingFailed;
    }
    
    bool mergeIsArgumentsAlias(bool isArgumentsAlias)
    {
        return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias | isArgumentsAlias);
    }
    
    bool isArgumentsAlias()
    {
        return m_isArgumentsAlias;
    }
    
    bool mergeIsLoadedFrom(bool isLoadedFrom)
    {
        return checkAndSet(m_isLoadedFrom, m_isLoadedFrom | isLoadedFrom);
    }
    
    void setIsLoadedFrom(bool isLoadedFrom)
    {
        m_isLoadedFrom = isLoadedFrom;
    }
    
    bool isLoadedFrom()
    {
        return m_isLoadedFrom;
    }
    
    bool predict(SpeculatedType prediction)
    {
        VariableAccessData* self = find();
        bool result = mergeSpeculation(self->m_prediction, prediction);
        if (result)
            mergeSpeculation(m_argumentAwarePrediction, m_prediction);
        return result;
    }
    
    SpeculatedType nonUnifiedPrediction()
    {
        return m_prediction;
    }
    
    SpeculatedType prediction()
    {
        return find()->m_prediction;
    }
    
    SpeculatedType argumentAwarePrediction()
    {
        return find()->m_argumentAwarePrediction;
    }
    
    bool mergeArgumentAwarePrediction(SpeculatedType prediction)
    {
        return mergeSpeculation(find()->m_argumentAwarePrediction, prediction);
    }
    
    void clearVotes()
    {
        ASSERT(find() == this);
        m_votes[0] = 0;
        m_votes[1] = 0;
    }
    
    void vote(unsigned ballot)
    {
        ASSERT(ballot < 2);
        m_votes[ballot]++;
    }
    
    double voteRatio()
    {
        ASSERT(find() == this);
        return static_cast<double>(m_votes[1]) / m_votes[0];
    }
    
    bool shouldUseDoubleFormatAccordingToVote()
    {
        // We don't support this facility for arguments, yet.
        // FIXME: make this work for arguments.
        if (local().isArgument())
            return false;
        
        // If the variable is not a number prediction, then this doesn't
        // make any sense.
        if (!isFullNumberSpeculation(prediction())) {
            // FIXME: we may end up forcing a local in inlined argument position to be a double even
            // if it is sometimes not even numeric, since this never signals the fact that it doesn't
            // want doubles. https://bugs.webkit.org/show_bug.cgi?id=109511
            return false;
        }
        
        // If the variable is predicted to hold only doubles, then it's a
        // no-brainer: it should be formatted as a double.
        if (isDoubleSpeculation(prediction()))
            return true;
        
        // If the variable is known to be used as an integer, then be safe -
        // don't force it to be a double.
        if (flags() & NodeBytecodeUsesAsInt)
            return false;
        
        // If the variable has been voted to become a double, then make it a
        // double.
        if (voteRatio() >= Options::doubleVoteRatioForDoubleFormat())
            return true;
        
        return false;
    }
    
    DoubleFormatState doubleFormatState()
    {
        return find()->m_doubleFormatState;
    }
    
    bool shouldUseDoubleFormat()
    {
        ASSERT(isRoot());
        bool doubleState = m_doubleFormatState == UsingDoubleFormat;
        ASSERT(!(doubleState && shouldNeverUnbox()));
        ASSERT(!(doubleState && isCaptured()));
        return doubleState && isProfitableToUnbox();
    }
    
    bool tallyVotesForShouldUseDoubleFormat()
    {
        ASSERT(isRoot());
        
        if (local().isArgument() || shouldNeverUnbox())
            return DFG::mergeDoubleFormatState(m_doubleFormatState, NotUsingDoubleFormat);
        
        if (m_doubleFormatState == CantUseDoubleFormat)
            return false;
        
        bool newValueOfShouldUseDoubleFormat = shouldUseDoubleFormatAccordingToVote();
        if (!newValueOfShouldUseDoubleFormat) {
            // We monotonically convert to double. Hence, if the fixpoint leads us to conclude that we should
            // switch back to int, we instead ignore this and stick with double.
            return false;
        }
        
        if (m_doubleFormatState == UsingDoubleFormat)
            return false;
        
        return DFG::mergeDoubleFormatState(m_doubleFormatState, UsingDoubleFormat);
    }
    
    bool mergeDoubleFormatState(DoubleFormatState doubleFormatState)
    {
        return DFG::mergeDoubleFormatState(find()->m_doubleFormatState, doubleFormatState);
    }
    
    bool makePredictionForDoubleFormat()
    {
        ASSERT(isRoot());
        
        if (m_doubleFormatState != UsingDoubleFormat)
            return false;
        
        return mergeSpeculation(m_prediction, SpecDouble);
    }
    
    NodeFlags flags() const { return m_flags; }
    
    bool mergeFlags(NodeFlags newFlags)
    {
        return checkAndSet(m_flags, m_flags | newFlags);
    }
    
    FlushFormat flushFormat()
    {
        ASSERT(find() == this);
        
        if (!shouldUnboxIfPossible())
            return FlushedJSValue;
        
        if (shouldUseDoubleFormat())
            return FlushedDouble;
        
        SpeculatedType prediction = argumentAwarePrediction();
        if (isInt32Speculation(prediction))
            return FlushedInt32;
        
        if (enableInt52() && !m_local.isArgument() && isMachineIntSpeculation(prediction))
            return FlushedInt52;
        
        if (isCellSpeculation(prediction))
            return FlushedCell;
        
        if (isBooleanSpeculation(prediction))
            return FlushedBoolean;
        
        return FlushedJSValue;
    }
    
    FlushedAt flushedAt()
    {
        return FlushedAt(flushFormat(), machineLocal());
    }
    
private:
    // This is slightly space-inefficient, since anything we're unified with
    // will have the same operand and should have the same prediction. But
    // putting them here simplifies the code, and we don't expect DFG space
    // usage for variable access nodes do be significant.

    VirtualRegister m_local;
    VirtualRegister m_machineLocal;
    SpeculatedType m_prediction;
    SpeculatedType m_argumentAwarePrediction;
    NodeFlags m_flags;

    bool m_isCaptured;
    bool m_shouldNeverUnbox;
    bool m_isArgumentsAlias;
    bool m_structureCheckHoistingFailed;
    bool m_checkArrayHoistingFailed;
    bool m_isProfitableToUnbox;
    bool m_isLoadedFrom;

    float m_votes[2]; // Used primarily for double voting but may be reused for other purposes.
    DoubleFormatState m_doubleFormatState;
};

} } // namespace JSC::DFG

#endif // DFGVariableAccessData_h
