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

#include "config.h"
#include "B3ReduceDoubleToFloat.h"

#if ENABLE(B3_JIT)

#include "B3BasicBlock.h"
#include "B3InsertionSetInlines.h"
#include "B3PhaseScope.h"
#include "B3UseCounts.h"
#include "B3ValueInlines.h"
#include <wtf/IndexSet.h>

namespace JSC { namespace B3 {

namespace {

namespace B3ReduceDoubleToFloatInternal {
static constexpr bool verbose = false;
}
bool printRemainingConversions = false;

class DoubleToFloatReduction {
public:
    DoubleToFloatReduction(Procedure& procedure)
        : m_procedure(procedure)
    {
    }

    void run()
    {
        if (!findCandidates())
            return;

        findPhisContainingFloat();

        simplify();

        cleanUp();
    }

private:
    // This step find values that are used as Double and cannot be converted to Float..
    // It flows the information backward through Phi-Upsilons.
    bool findCandidates()
    {
        bool foundConversionCandidate = false;
        Vector<Value*, 32> upsilons;

        // First, we find all values that are strictly used as double.
        // Those are values used by something else than DoubleToFloat.
        //
        // We don't know the state of Upsilons until their Phi has been
        // set. We just keep a list of them and update them next.
        for (BasicBlock* block : m_procedure) {
            for (Value* value : *block) {
                value->performSubstitution();

                if (value->opcode() == DoubleToFloat) {
                    foundConversionCandidate = true;

                    Value* child = value->child(0);
                    if (child->opcode() == FloatToDouble) {
                        // We don't really need to simplify this early but it simplifies debugging.
                        value->replaceWithIdentity(child->child(0));
                    }
                    continue;
                }

                if (value->opcode() == FloatToDouble)
                    foundConversionCandidate = true;

                if (value->opcode() == Upsilon) {
                    Value* child = value->child(0);
                    if (child->type() == Double)
                        upsilons.append(value);
                    continue;
                }

                for (Value* child : value->children()) {
                    if (child->type() == Double)
                        m_valuesUsedAsDouble.add(child);
                }
            }
        }

        if (!foundConversionCandidate)
            return false;

        // Now we just need to propagate through Phi-Upsilon.
        // A Upsilon can convert its input to float if its phi is never used as double.
        // If we modify a phi, we need to continue until all the Upsilon-Phi converge.
        bool changedPhiState;
        do {
            changedPhiState = false;
            for (Value* value : upsilons) {
                UpsilonValue* upsilon = value->as<UpsilonValue>();
                Value* phi = upsilon->phi();
                if (!m_valuesUsedAsDouble.contains(phi))
                    continue;

                Value* child = value->child(0);
                bool childChanged = m_valuesUsedAsDouble.add(child);
                if (childChanged && child->opcode() == Phi)
                    changedPhiState = true;
            }
        } while (changedPhiState);

        if (B3ReduceDoubleToFloatInternal::verbose) {
            dataLog("Conversion candidates:\n");
            for (BasicBlock* block : m_procedure) {
                for (Value* value : *block) {
                    if (value->type() == Double && !m_valuesUsedAsDouble.contains(value))
                        dataLog("    ", deepDump(m_procedure, value), "\n");
                }
            }
            dataLog("\n");
        }

        return true;
    }

    // This step finds Phis of type Double that effectively contains Float values.
    // It flows that information forward through Phi-Upsilons.
    void findPhisContainingFloat()
    {
        Vector<Value*, 32> upsilons;

        // The Double value that can be safely turned into a Float are:
        // - FloatToDouble
        // - ConstDouble with a value that converts to Float without losing precision.
        for (BasicBlock* block : m_procedure) {
            for (Value* value : *block) {
                if (value->opcode() != Upsilon)
                    continue;

                Value* child = value->child(0);
                if (child->type() != Double
                    || child->opcode() == FloatToDouble)
                    continue;

                if (child->hasDouble()) {
                    double constValue = child->asDouble();
                    if (isIdentical(static_cast<double>(static_cast<float>(constValue)), constValue))
                        continue;
                }

                if (child->opcode() == Phi) {
                    upsilons.append(value);
                    continue;
                }

                UpsilonValue* upsilon = value->as<UpsilonValue>();
                Value* phi = upsilon->phi();
                m_phisContainingDouble.add(phi);
            }
        }

        // Propagate the flags forward.
        bool changedPhiState;
        do {
            changedPhiState = false;
            for (Value* value : upsilons) {
                Value* child = value->child(0);
                if (m_phisContainingDouble.contains(child)) {
                    UpsilonValue* upsilon = value->as<UpsilonValue>();
                    Value* phi = upsilon->phi();
                    changedPhiState |= m_phisContainingDouble.add(phi);
                }
            }
        } while (changedPhiState);

        if (B3ReduceDoubleToFloatInternal::verbose) {
            dataLog("Phis containing float values:\n");
            for (BasicBlock* block : m_procedure) {
                for (Value* value : *block) {
                    if (value->opcode() == Phi
                        && value->type() == Double
                        && !m_phisContainingDouble.contains(value))
                        dataLog("    ", deepDump(m_procedure, value), "\n");
                }
            }
            dataLog("\n");
        }
    }

    bool canBeTransformedToFloat(Value* value)
    {
        if (value->opcode() == FloatToDouble)
            return true;

        if (value->hasDouble())
            return true; // Double constant truncated to float.

        if (value->opcode() == Phi) {
            return value->type() == Float
                || (value->type() == Double && !m_phisContainingDouble.contains(value));
        }
        return false;
    }

    Value* transformToFloat(Value* value, unsigned valueIndex, InsertionSet& insertionSet)
    {
        ASSERT(canBeTransformedToFloat(value));
        if (value->opcode() == FloatToDouble)
            return value->child(0);

        if (value->hasDouble())
            return insertionSet.insert<ConstFloatValue>(valueIndex, value->origin(), static_cast<float>(value->asDouble()));

        if (value->opcode() == Phi) {
            ASSERT(value->type() == Double || value->type() == Float);
            if (value->type() == Double)
                convertPhi(value);
            return value;
        }
        RELEASE_ASSERT_NOT_REACHED();
        return nullptr;
    }

    void convertPhi(Value* phi)
    {
        ASSERT(phi->opcode() == Phi);
        ASSERT(phi->type() == Double);
        phi->setType(Float);
        m_convertedPhis.add(phi);
    }

    bool attemptTwoOperandsSimplify(Value* candidate, unsigned candidateIndex, InsertionSet& insertionSet)
    {
        Value* left = candidate->child(0);
        Value* right = candidate->child(1);
        if (!canBeTransformedToFloat(left) || !canBeTransformedToFloat(right))
            return false;

        if (left->hasDouble() && right->hasDouble()) {
            // If both inputs are constants, converting them to floats and performing
            // the same operation is incorrect. It may produce a different value
            // depending on the operation and the inputs. There are inputs where
            // casting to float and performing the operation would result in the
            // same value. Regardless, we don't prove when that is legal here since
            // it isn't profitable to do. We leave it to strength reduction to handle
            // reduce these cases.
            return false;
        }

        m_convertedValue.add(candidate);
        candidate->child(0) = transformToFloat(left, candidateIndex, insertionSet);
        candidate->child(1) = transformToFloat(right, candidateIndex, insertionSet);
        return true;
    }

    // Simplify Double operations into Float operations.
    void simplify()
    {
        Vector<Value*, 32> upsilonReferencingDoublePhi;

        InsertionSet insertionSet(m_procedure);
        for (BasicBlock* block : m_procedure) {
            for (unsigned index = 0; index < block->size(); ++index) {
                Value* value = block->at(index);

                switch (value->opcode()) {
                case Equal:
                case NotEqual:
                case LessThan:
                case GreaterThan:
                case LessEqual:
                case GreaterEqual:
                case EqualOrUnordered:
                    attemptTwoOperandsSimplify(value, index, insertionSet);
                    continue;
                case Upsilon: {
                    Value* child = value->child(0);
                    if (child->opcode() == Phi && child->type() == Double)
                        upsilonReferencingDoublePhi.append(value);
                    continue;
                }
                default:
                    break;
                }

                if (m_valuesUsedAsDouble.contains(value))
                    continue;

                switch (value->opcode()) {
                case Add:
                case Sub:
                case Mul:
                case Div:
                    if (attemptTwoOperandsSimplify(value, index, insertionSet))
                        value->setType(Float);
                    break;
                case Abs:
                case Ceil:
                case Floor:
                case Neg:
                case Sqrt: {
                    Value* child = value->child(0);
                    if (canBeTransformedToFloat(child)) {
                        value->child(0) = transformToFloat(child, index, insertionSet);
                        value->setType(Float);
                        m_convertedValue.add(value);
                    }
                    break;
                }
                case IToD: {
                    Value* iToF = insertionSet.insert<Value>(index, IToF, value->origin(), value->child(0));
                    value->setType(Float);
                    value->replaceWithIdentity(iToF);
                    m_convertedValue.add(value);
                    break;
                }
                case FloatToDouble:
                    // This happens if we round twice.
                    // Typically, this is indirect through Phi-Upsilons.
                    // The Upsilon rounds and the Phi rounds.
                    value->setType(Float);
                    value->replaceWithIdentity(value->child(0));
                    m_convertedValue.add(value);
                    break;
                case Phi:
                    // If a Phi is always converted to Float, we always make it into a float Phi-Upsilon.
                    // This is a simplistic view of things. Ideally we should keep type that will minimize
                    // the amount of conversion in the loop.
                    if (value->type() == Double)
                        convertPhi(value);
                    break;
                default:
                    break;
                }
            }
            insertionSet.execute(block);
        }

        if (!upsilonReferencingDoublePhi.isEmpty()) {
            // If a Phi contains Float values typed as Double, but is not used as Float
            // by a non-trivial operation, we did not convert it.
            //
            // We fix that now by converting the remaining phis that contains
            // float but where not converted to float.
            bool changedPhi;
            do {
                changedPhi = false;

                for (Value* value : upsilonReferencingDoublePhi) {
                    UpsilonValue* upsilon = value->as<UpsilonValue>();
                    Value* child = value->child(0);
                    Value* phi = upsilon->phi();
                    if (phi->type() == Float && child->type() == Double
                        && !m_phisContainingDouble.contains(child)) {
                        convertPhi(child);
                        changedPhi = true;
                    }
                }

            } while (changedPhi);
        }
    }

    // We are in an inconsistent state where we have
    // DoubleToFloat nodes over values producing float and Phis that are
    // float for Upsilons that are Double.
    //
    // This steps puts us back in a consistent state.
    void cleanUp()
    {
        InsertionSet insertionSet(m_procedure);

        for (BasicBlock* block : m_procedure) {
            for (unsigned index = 0; index < block->size(); ++index) {
                Value* value = block->at(index);
                if (value->opcode() == DoubleToFloat && value->child(0)->type() == Float) {
                    value->replaceWithIdentity(value->child(0));
                    continue;
                }

                if (value->opcode() == Upsilon) {
                    UpsilonValue* upsilon = value->as<UpsilonValue>();
                    Value* child = value->child(0);
                    Value* phi = upsilon->phi();

                    if (phi->type() == Float) {
                        if (child->type() == Double) {
                            Value* newChild = nullptr;
                            if (child->opcode() == FloatToDouble)
                                newChild = child->child(0);
                            else if (child->hasDouble())
                                newChild = insertionSet.insert<ConstFloatValue>(index, child->origin(), static_cast<float>(child->asDouble()));
                            else
                                newChild = insertionSet.insert<Value>(index, DoubleToFloat, upsilon->origin(), child);
                            upsilon->child(0) = newChild;
                        }
                        continue;
                    }
                }

                if (!m_convertedValue.contains(value)) {
                    // Phis can be converted from Double to Float if the value they contain
                    // is not more precise than a Float.
                    // If the value is needed as Double, it has to be converted back.
                    for (Value*& child : value->children()) {
                        if (m_convertedPhis.contains(child))
                            child = insertionSet.insert<Value>(index, FloatToDouble, value->origin(), child);
                    }
                }
            }
            insertionSet.execute(block);
        }
    }

    Procedure& m_procedure;

    // Set of all the Double values that are actually used as Double.
    // Converting any of them to Float would lose precision.
    IndexSet<Value*> m_valuesUsedAsDouble;

    // Set of all the Phi of type Double that really contains a Double.
    // Any Double Phi not in the set can be converted to Float without losing precision.
    IndexSet<Value*> m_phisContainingDouble;

    // Any value that was converted from producing a Double to producing a Float.
    // This set does not include Phi-Upsilons.
    IndexSet<Value*> m_convertedValue;

    // Any value that previously produced Double and now produce Float.
    IndexSet<Value*> m_convertedPhis;
};

void printGraphIfConverting(Procedure& procedure)
{
    if (!printRemainingConversions)
        return;

    UseCounts useCount(procedure);

    Vector<Value*> doubleToFloat;
    Vector<Value*> floatToDouble;

    for (BasicBlock* block : procedure) {
        for (Value* value : *block) {
            if (!useCount.numUses(value))
                continue;

            if (value->opcode() == DoubleToFloat)
                doubleToFloat.append(value);
            if (value->opcode() == FloatToDouble)
                floatToDouble.append(value);
        }
    }

    if (doubleToFloat.isEmpty() && floatToDouble.isEmpty())
        return;

    dataLog("Procedure with Float-Double conversion:\n", procedure, "\n");
    dataLog("Converting nodes:\n");
    for (Value* value : doubleToFloat)
        dataLog("    ", deepDump(procedure, value), "\n");
    for (Value* value : floatToDouble)
        dataLog("    ", deepDump(procedure, value), "\n");

}

} // anonymous namespace.

void reduceDoubleToFloat(Procedure& procedure)
{
    PhaseScope phaseScope(procedure, "reduceDoubleToFloat");

    if (B3ReduceDoubleToFloatInternal::verbose)
        dataLog("Before DoubleToFloatReduction:\n", procedure, "\n");

    DoubleToFloatReduction doubleToFloatReduction(procedure);
    doubleToFloatReduction.run();

    if (B3ReduceDoubleToFloatInternal::verbose)
        dataLog("After DoubleToFloatReduction:\n", procedure, "\n");

    printGraphIfConverting(procedure);
}

} } // namespace JSC::B3

#endif // ENABLE(B3_JIT)

