/*
 * Copyright (C) 2015-2016 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(B3_JIT)

#include "AirInst.h"
#include "B3SparseCollection.h"
#include <wtf/FastMalloc.h>
#include <wtf/Noncopyable.h>
#include <wtf/ScopedLambda.h>
#include <wtf/text/CString.h>

namespace JSC { namespace B3 { namespace Air {

class Code;
struct GenerationContext;

class Special {
    WTF_MAKE_NONCOPYABLE(Special);
    WTF_MAKE_FAST_ALLOCATED;
public:
    static const char* const dumpPrefix;
    
    Special();
    JS_EXPORT_PRIVATE virtual ~Special();

    Code& code() const { return *m_code; }

    CString name() const;

    virtual void forEachArg(Inst&, const ScopedLambda<Inst::EachArgCallback>&) = 0;
    virtual bool isValid(Inst&) = 0;
    virtual bool admitsStack(Inst&, unsigned argIndex) = 0;
    virtual bool admitsExtendedOffsetAddr(Inst&, unsigned argIndex) = 0;
    virtual Optional<unsigned> shouldTryAliasingDef(Inst&);

    // This gets called on for each Inst that uses this Special. Note that there is no way to
    // guarantee that a Special gets used from just one Inst, because Air might taildup late. So,
    // if you want to pass this information down to generate(), then you have to either:
    //
    // 1) Generate Air that starts with a separate Special per Patch Inst, and then merge
    //    usedRegister sets. This is probably not great, but it optimizes for the common case that
    //    Air didn't duplicate code or that such duplication didn't cause any interesting changes to
    //    register assignment.
    //
    // 2) Have the Special maintain a HashMap<Inst*, RegisterSet>. This works because the analysis
    //    that feeds into this call is performed just before code generation and there is no way
    //    for the Vector<>'s that contain the Insts to be reallocated. This allows generate() to
    //    consult the HashMap.
    //
    // 3) Hybrid: you could use (1) and fire up a HashMap if you see multiple calls.
    //
    // Note that it's not possible to rely on reportUsedRegisters() being called in the same order
    // as generate(). If we could rely on that, then we could just have each Special instance
    // maintain a Vector of RegisterSet's and then process that vector in the right order in
    // generate(). But, the ordering difference is unlikely to change since it would harm the
    // performance of the liveness analysis.
    //
    // Currently, we do (1) for B3 stackmaps.
    virtual void reportUsedRegisters(Inst&, const RegisterSet&) = 0;
    
    virtual MacroAssembler::Jump generate(Inst&, CCallHelpers&, GenerationContext&) = 0;

    virtual RegisterSet extraEarlyClobberedRegs(Inst&) = 0;
    virtual RegisterSet extraClobberedRegs(Inst&) = 0;
    
    // By default, this returns false.
    virtual bool isTerminal(Inst&);

    // By default, this returns true.
    virtual bool hasNonArgEffects(Inst&);

    // By default, this returns true.
    virtual bool hasNonArgNonControlEffects(Inst&);

    void dump(PrintStream&) const;
    void deepDump(PrintStream&) const;

protected:
    virtual void dumpImpl(PrintStream&) const = 0;
    virtual void deepDumpImpl(PrintStream&) const = 0;

private:
    friend class Code;
    friend class SparseCollection<Special>;

    unsigned m_index { UINT_MAX };
    Code* m_code { nullptr };
};

class DeepSpecialDump {
public:
    DeepSpecialDump(const Special* special)
        : m_special(special)
    {
    }

    void dump(PrintStream& out) const
    {
        if (m_special)
            m_special->deepDump(out);
        else
            out.print("<null>");
    }

private:
    const Special* m_special;
};

inline DeepSpecialDump deepDump(const Special* special)
{
    return DeepSpecialDump(special);
}

} } } // namespace JSC::B3::Air

#endif // ENABLE(B3_JIT)
