/*
 * Copyright (C) 2011-2019 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

#include "DFGCompilationMode.h"

#if ENABLE(DFG_JIT)

#include "Options.h"
#include <limits.h>
#include <wtf/text/StringImpl.h>

namespace JSC { namespace DFG {

struct Node;

typedef uint32_t BlockIndex;
static constexpr BlockIndex NoBlock = UINT_MAX;

// Use RefChildren if the child ref counts haven't already been adjusted using
// other means and either of the following is true:
// - The node you're creating is MustGenerate.
// - The place where you're inserting a reference to the node you're creating
//   will not also do RefChildren.
enum RefChildrenMode {
    RefChildren,
    DontRefChildren
};

// Use RefNode if you know that the node will be used from another node, and you
// will not already be ref'ing the node to account for that use.
enum RefNodeMode {
    RefNode,
    DontRefNode
};

enum SwitchKind {
    SwitchImm,
    SwitchChar,
    SwitchString,
    SwitchCell
};

inline bool verboseCompilationEnabled(CompilationMode mode = DFGMode)
{
    return Options::verboseCompilation() || Options::dumpGraphAtEachPhase() || (isFTL(mode) && Options::verboseFTLCompilation());
}

inline bool logCompilationChanges(CompilationMode mode = DFGMode)
{
    return verboseCompilationEnabled(mode) || Options::logCompilationChanges();
}

inline bool shouldDumpGraphAtEachPhase(CompilationMode mode)
{
    if (isFTL(mode))
        return Options::dumpGraphAtEachPhase() || Options::dumpDFGFTLGraphAtEachPhase();
    return Options::dumpGraphAtEachPhase() || Options::dumpDFGGraphAtEachPhase();
}

inline bool validationEnabled()
{
#if !ASSERT_DISABLED
    return true;
#else
    return Options::validateGraph() || Options::validateGraphAtEachPhase();
#endif
}

inline bool enableInt52()
{
#if USE(JSVALUE64)
    return true;
#else
    return false;
#endif
}

// The prediction propagator effectively does four passes, with the last pass
// being done by the separate FixuPhase.
enum PredictionPass {
    // We're converging in a straight-forward forward flow fixpoint. This is the
    // most conventional part of the propagator - it makes only monotonic decisions
    // based on value profiles and rare case profiles. It ignores baseline JIT rare
    // case profiles. The goal here is to develop a good guess of which variables
    // are likely to be purely numerical, which generally doesn't require knowing
    // the rare case profiles.
    PrimaryPass,
    
    // At this point we know what is numerical and what isn't. Non-numerical inputs
    // to arithmetic operations will not have useful information in the Baseline JIT
    // rare case profiles because Baseline may take slow path on non-numerical
    // inputs even if the DFG could handle the input on the fast path. Boolean
    // inputs are the most obvious example. This pass of prediction propagation will
    // use Baseline rare case profiles for purely numerical operations and it will
    // ignore them for everything else. The point of this pass is to develop a good
    // guess of which variables are likely to be doubles.
    //
    // This pass is intentionally weird and goes against what is considered good
    // form when writing a static analysis: a new data flow of booleans will cause
    // us to ignore rare case profiles except that by then, we will have already
    // propagated double types based on our prior assumption that we shouldn't
    // ignore rare cases. This probably won't happen because the PrimaryPass is
    // almost certainly going to establish what is and isn't numerical. But it's
    // conceivable that during this pass we will discover a new boolean data flow.
    // This ends up being sound because the prediction propagator could literally
    // make any guesses it wants and still be sound (worst case, we OSR exit more
    // often or use too general of types are run a bit slower). This will converge
    // because we force monotonicity on the types of nodes and variables. So, the
    // worst thing that can happen is that we violate basic laws of theoretical
    // decency.
    RareCasePass,
    
    // At this point we know what is numerical and what isn't, and we also know what
    // is a double and what isn't. So, we start forcing variables to be double.
    // Doing so may have a cascading effect so this is a fixpoint. It's monotonic
    // in the sense that once a variable is forced double, it cannot be forced in
    // the other direction.
    DoubleVotingPass,
    
    // This pass occurs once we have converged. At this point we are just installing
    // type checks based on the conclusions we have already reached. It's important
    // for this pass to reach the same conclusions that DoubleVotingPass reached.
    FixupPass
};

enum StructureRegistrationState { HaveNotStartedRegistering, AllStructuresAreRegistered };

enum StructureRegistrationResult { StructureRegisteredNormally, StructureRegisteredAndWatched };

enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };

// Describes the form you can expect the entire graph to be in.
enum GraphForm {
    // LoadStore form means that basic blocks may freely use GetLocal, SetLocal,
    // and Flush for accessing local variables and indicating where their live
    // ranges ought to be. Data flow between local accesses is implicit. Liveness
    // is only explicit at block heads (variablesAtHead). This is only used by
    // the DFG simplifier and is only preserved by same.
    //
    // For example, LoadStore form gives no easy way to determine which SetLocal's
    // flow into a GetLocal. As well, LoadStore form implies no restrictions on
    // redundancy: you can freely emit multiple GetLocals, or multiple SetLocals
    // (or any combination thereof) to the same local in the same block. LoadStore
    // form does not require basic blocks to declare how they affect or use locals,
    // other than implicitly by using the local ops and by preserving
    // variablesAtHead. Finally, LoadStore allows flexibility in how liveness of
    // locals is extended; for example you can replace a GetLocal with a Phantom
    // and so long as the Phantom retains the GetLocal's children (i.e. the Phi
    // most likely) then it implies that the local is still live but that it need
    // not be stored to the stack necessarily. This implies that Phantom can
    // reference nodes that have no result, as long as those nodes are valid
    // GetLocal children (i.e. Phi, SetLocal, SetArgumentDefinitely, SetArgumentMaybe).
    //
    // LoadStore form also implies that Phis need not have children. By default,
    // they end up having no children if you enter LoadStore using the canonical
    // way (call Graph::dethread).
    //
    // LoadStore form is suitable for CFG transformations, as well as strength
    // reduction, folding, and CSE.
    LoadStore,
    
    // ThreadedCPS form means that basic blocks list up-front which locals they
    // expect to be live at the head, and which locals they make available at the
    // tail. ThreadedCPS form also implies that:
    //
    // - GetLocals and SetLocals are not redundant within a basic block.
    //
    // - All GetLocals and Flushes are linked directly to the last access point
    //   of the variable, which must not be another GetLocal.
    //
    // - Phantom(Phi) is not legal, but PhantomLocal is.
    //
    // ThreadedCPS form is suitable for data flow analysis (CFA, prediction
    // propagation), register allocation, and code generation.
    ThreadedCPS,
    
    // SSA form. See DFGSSAConversionPhase.h for a description.
    SSA
};

// Describes the state of the UnionFind structure of VariableAccessData's.
enum UnificationState {
    // BasicBlock-local accesses to variables are appropriately unified with each other.
    LocallyUnified,
    
    // Unification has been performed globally.
    GloballyUnified
};

// Describes how reference counts in the graph behave.
enum RefCountState {
    // Everything has refCount() == 1.
    EverythingIsLive,

    // Set after DCE has run.
    ExactRefCount
};

enum OperandSpeculationMode { AutomaticOperandSpeculation, ManualOperandSpeculation };

enum ProofStatus { NeedsCheck, IsProved };

inline bool isProved(ProofStatus proofStatus)
{
    ASSERT(proofStatus == IsProved || proofStatus == NeedsCheck);
    return proofStatus == IsProved;
}

inline ProofStatus proofStatusForIsProved(bool isProved)
{
    return isProved ? IsProved : NeedsCheck;
}

enum KillStatus { DoesNotKill, DoesKill };

inline bool doesKill(KillStatus killStatus)
{
    ASSERT(killStatus == DoesNotKill || killStatus == DoesKill);
    return killStatus == DoesKill;
}

inline KillStatus killStatusForDoesKill(bool doesKill)
{
    return doesKill ? DoesKill : DoesNotKill;
}

enum class PlanStage {
    Initial,
    AfterFixup
};

// If possible, this will acquire a lock to make sure that if multiple threads
// start crashing at the same time, you get coherent dump output. Use this only
// when you're forcing a crash with diagnostics.
void startCrashing();

JS_EXPORT_PRIVATE bool isCrashing();

struct NodeAndIndex {
    NodeAndIndex()
        : node(nullptr)
        , index(UINT_MAX)
    {
    }
    
    NodeAndIndex(Node* node, unsigned index)
        : node(node)
        , index(index)
    {
        ASSERT(!node == (index == UINT_MAX));
    }
    
    bool operator!() const
    {
        return !node;
    }
    
    Node* node;
    unsigned index;
};

// A less-than operator for strings that is useful for generating string switches. Sorts by <
// relation on characters. Ensures that if a is a prefix of b, then a < b.
bool stringLessThan(StringImpl& a, StringImpl& b);

} } // namespace JSC::DFG

namespace WTF {

void printInternal(PrintStream&, JSC::DFG::OptimizationFixpointState);
void printInternal(PrintStream&, JSC::DFG::GraphForm);
void printInternal(PrintStream&, JSC::DFG::UnificationState);
void printInternal(PrintStream&, JSC::DFG::RefCountState);
void printInternal(PrintStream&, JSC::DFG::ProofStatus);

} // namespace WTF

#endif // ENABLE(DFG_JIT)

namespace JSC { namespace DFG {

// Put things here that must be defined even if ENABLE(DFG_JIT) is false.

enum CapabilityLevel {
    CannotCompile,
    CanCompile,
    CanCompileAndInline,
    CapabilityLevelNotSet
};

inline bool canCompile(CapabilityLevel level)
{
    switch (level) {
    case CanCompile:
    case CanCompileAndInline:
        return true;
    default:
        return false;
    }
}

inline bool canInline(CapabilityLevel level)
{
    switch (level) {
    case CanCompileAndInline:
        return true;
    default:
        return false;
    }
}

inline CapabilityLevel leastUpperBound(CapabilityLevel a, CapabilityLevel b)
{
    switch (a) {
    case CannotCompile:
        return CannotCompile;
    case CanCompile:
        switch (b) {
        case CanCompile:
        case CanCompileAndInline:
            return CanCompile;
        default:
            return CannotCompile;
        }
    case CanCompileAndInline:
        return b;
    case CapabilityLevelNotSet:
        ASSERT_NOT_REACHED();
        return CannotCompile;
    }
    ASSERT_NOT_REACHED();
    return CannotCompile;
}

// Unconditionally disable DFG disassembly support if the DFG is not compiled in.
inline bool shouldDumpDisassembly(CompilationMode mode = DFGMode)
{
#if ENABLE(DFG_JIT)
    return Options::dumpDisassembly() || Options::dumpDFGDisassembly() || (isFTL(mode) && Options::dumpFTLDisassembly());
#else
    UNUSED_PARAM(mode);
    return false;
#endif
}

} } // namespace JSC::DFG

namespace WTF {

void printInternal(PrintStream&, JSC::DFG::CapabilityLevel);

} // namespace WTF
