/*
 * Copyright (C) 2017 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 "AirInsertionSet.h"
#include <wtf/Insertion.h>
#include <wtf/Vector.h>

namespace JSC { namespace B3 { namespace Air {

class BasicBlock;
class Code;

// Phased insertions allow you to ascribe phases to the things inserted at an instruction boundary.
class PhaseInsertion : public Insertion {
public:
    PhaseInsertion() { }
    
    template<typename T>
    PhaseInsertion(size_t index, unsigned phase, T&& element)
        : Insertion(index, std::forward<T>(element))
        , m_phase(phase)
    {
    }
    
    unsigned phase() const { return m_phase; }
    
    bool operator<(const PhaseInsertion& other) const
    {
        if (index() != other.index())
            return index() < other.index();
        return m_phase < other.m_phase;
    }

private:
    unsigned m_phase { 0 };
};

class PhaseInsertionSet {
public:
    PhaseInsertionSet()
    {
    }
    
    template<typename T>
    void appendInsertion(T&& insertion)
    {
        m_insertions.append(std::forward<T>(insertion));
    }
    
    template<typename Inst>
    void insertInst(size_t index, unsigned phase, Inst&& inst)
    {
        appendInsertion(PhaseInsertion(index, phase, std::forward<Inst>(inst)));
    }
    
    template<typename... Arguments>
    void insert(size_t index, unsigned phase, Arguments&&... arguments)
    {
        insertInst(index, phase, Inst(std::forward<Arguments>(arguments)...));
    }
    
    void execute(BasicBlock*);

private:
    Vector<PhaseInsertion, 8> m_insertions;
};

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

#endif // ENABLE(B3_JIT)

