/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLConstantFolder.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/ir/SkSLBoolLiteral.h"
#include "src/sksl/ir/SkSLConstructorCompound.h"
#include "src/sksl/ir/SkSLFloatLiteral.h"
#include "src/sksl/ir/SkSLFunctionCall.h"
#include "src/sksl/ir/SkSLIntLiteral.h"

#include "include/sksl/DSLCore.h"

namespace SkSL {

static bool has_compile_time_constant_arguments(const ExpressionArray& arguments) {
    for (const std::unique_ptr<Expression>& arg : arguments) {
        const Expression* expr = ConstantFolder::GetConstantValueForVariable(*arg);
        if (!expr->isCompileTimeConstant()) {
            return false;
        }
    }
    return true;
}

template <typename T>
static std::unique_ptr<Expression> coalesce_n_way_vector(const Expression* arg0,
                                                         const Expression* arg1,
                                                         T startingState,
                                                         const std::function<T(T, T, T)>& coalesce,
                                                         const std::function<T(T)>& finalize) {
    // Takes up to two vector or scalar arguments and coalesces them in sequence:
    //     scalar = startingState;
    //     scalar = coalesce(scalar, arg0.x, arg1.x);
    //     scalar = coalesce(scalar, arg0.y, arg1.y);
    //     scalar = coalesce(scalar, arg0.z, arg1.z);
    //     scalar = coalesce(scalar, arg0.w, arg1.w);
    //     scalar = finalize(scalar);
    //
    // If an argument is null, zero is passed to the coalesce function. If the arguments are a mix
    // of scalars and vectors, the scalars is interpreted as a vector containing the same value for
    // every component.

    arg0 = ConstantFolder::GetConstantValueForVariable(*arg0);
    SkASSERT(arg0);

    const Type& vecType =          arg0->type().isVector()  ? arg0->type() :
                          (arg1 && arg1->type().isVector()) ? arg1->type() :
                                                              arg0->type();
    SkASSERT(arg0->type().componentType() == vecType.componentType());

    if (arg1) {
        arg1 = ConstantFolder::GetConstantValueForVariable(*arg1);
        SkASSERT(arg1);
        SkASSERT(arg1->type().componentType() == vecType.componentType());
    }

    T value = startingState;
    int arg0Index = 0;
    int arg1Index = 0;
    for (int index = 0; index < vecType.columns(); ++index) {
        const Expression* arg0Subexpr = arg0->getConstantSubexpression(arg0Index);
        arg0Index += arg0->type().isVector() ? 1 : 0;
        SkASSERT(arg0Subexpr);

        const Expression* arg1Subexpr = nullptr;
        if (arg1) {
            arg1Subexpr = arg1->getConstantSubexpression(arg1Index);
            arg1Index += arg1->type().isVector() ? 1 : 0;
            SkASSERT(arg1Subexpr);
        }

        value = coalesce(value,
                         arg0Subexpr->as<Literal<T>>().value(),
                         arg1Subexpr ? arg1Subexpr->as<Literal<T>>().value() : T{});

        if constexpr (std::is_floating_point<T>::value) {
            // If coalescing the intrinsic yields a non-finite value, do not optimize.
            if (!std::isfinite(value)) {
                return nullptr;
            }
        }
    }

    if (finalize) {
        value = finalize(value);
    }

    return Literal<T>::Make(arg0->fOffset, value, &vecType.componentType());
}

template <typename T>
static std::unique_ptr<Expression> coalesce_vector(const ExpressionArray& arguments,
                                                   T startingState,
                                                   const std::function<T(T, T)>& coalesce,
                                                   const std::function<T(T)>& finalize) {
    SkASSERT(arguments.size() == 1);
    if constexpr (std::is_same<T, bool>::value) {
        SkASSERT(arguments.front()->type().componentType().isBoolean());
    }
    if constexpr (std::is_same<T, float>::value) {
        SkASSERT(arguments.front()->type().componentType().isFloat());
    }

    return coalesce_n_way_vector<T>(arguments.front().get(), /*arg1=*/nullptr, startingState,
                                    [&coalesce](T a, T b, T) { return coalesce(a, b); },
                                    finalize);
}

template <typename T>
static std::unique_ptr<Expression> coalesce_pairwise_vectors(
        const ExpressionArray& arguments,
        T startingState,
        const std::function<T(T, T, T)>& coalesce,
        const std::function<T(T)>& finalize) {
    SkASSERT(arguments.size() == 2);
    const Type& type = arguments.front()->type().componentType();

    if (type.isFloat()) {
        return coalesce_n_way_vector<float>(arguments[0].get(), arguments[1].get(), startingState,
                                            coalesce, finalize);
    }

    SkDEBUGFAILF("unsupported type %s", type.description().c_str());
    return nullptr;
}

template <typename LITERAL, typename FN>
static std::unique_ptr<Expression> optimize_comparison_of_type(const Context& context,
                                                               const Expression& left,
                                                               const Expression& right,
                                                               const FN& compare) {
    const Type& type = left.type();
    SkASSERT(type.isVector());
    SkASSERT(type.componentType().isNumber());
    SkASSERT(type == right.type());

    ExpressionArray array;
    array.reserve_back(type.columns());

    for (int index = 0; index < type.columns(); ++index) {
        const Expression* leftSubexpr = left.getConstantSubexpression(index);
        const Expression* rightSubexpr = right.getConstantSubexpression(index);
        SkASSERT(leftSubexpr);
        SkASSERT(rightSubexpr);
        bool value = compare(leftSubexpr->as<LITERAL>().value(),
                             rightSubexpr->as<LITERAL>().value());
        array.push_back(BoolLiteral::Make(context, leftSubexpr->fOffset, value));
    }

    const Type& bvecType = context.fTypes.fBool->toCompound(context, type.columns(), /*rows=*/1);
    return ConstructorCompound::Make(context, left.fOffset, bvecType, std::move(array));
}

template <typename FN>
static std::unique_ptr<Expression> optimize_comparison(const Context& context,
                                                       const ExpressionArray& arguments,
                                                       const FN& compare) {
    SkASSERT(arguments.size() == 2);
    const Expression* left = ConstantFolder::GetConstantValueForVariable(*arguments[0]);
    const Expression* right = ConstantFolder::GetConstantValueForVariable(*arguments[1]);
    const Type& type = left->type().componentType();

    if (type.isFloat()) {
        return optimize_comparison_of_type<FloatLiteral>(context, *left, *right, compare);
    }
    if (type.isInteger()) {
        return optimize_comparison_of_type<IntLiteral>(context, *left, *right, compare);
    }
    SkDEBUGFAILF("unsupported type %s", type.description().c_str());
    return nullptr;
}

template <typename T0, typename T1 = T0, typename T2 = T0>
static std::unique_ptr<Expression> evaluate_n_way_intrinsic_of_type(
        const Context& context,
        const Expression* arg0,
        const Expression* arg1,
        const Expression* arg2,
        const std::function<T0(T0, T1, T2)>& eval) {
    // Takes up to three arguments and evaluates all of them, left-to-right, in tandem.
    // Equivalent to constructing a new compound value containing the results from:
    //     eval(arg0.x, arg1.x, arg2.x),
    //     eval(arg0.y, arg1.y, arg2.y),
    //     eval(arg0.z, arg1.z, arg2.z),
    //     eval(arg0.w, arg1.w, arg2.w)
    //
    // If an argument is null, zero is passed to the evaluation function. If the arguments are a mix
    // of scalars and compounds, scalars are interpreted as a compound containing the same value for
    // every component.
    arg0 = ConstantFolder::GetConstantValueForVariable(*arg0);
    SkASSERT(arg0);

    const Type& compoundType =          !arg0->type().isScalar()  ? arg0->type() :
                               (arg1 && !arg1->type().isScalar()) ? arg1->type() :
                               (arg2 && !arg2->type().isScalar()) ? arg2->type() :
                                                                    arg0->type();
    const Type& type = compoundType.componentType();
    SkASSERT(arg0->type().componentType() == type);

    if (arg1) {
        arg1 = ConstantFolder::GetConstantValueForVariable(*arg1);
        SkASSERT(arg1);
    }

    if (arg2) {
        arg2 = ConstantFolder::GetConstantValueForVariable(*arg2);
        SkASSERT(arg2);
    }

    ExpressionArray array;
    array.reserve_back(compoundType.columns());

    int arg0Index = 0;
    int arg1Index = 0;
    int arg2Index = 0;
    int slots = compoundType.slotCount();
    for (int index = 0; index < slots; ++index) {
        const Expression* arg0Subexpr = arg0->getConstantSubexpression(arg0Index);
        arg0Index += arg0->type().isScalar() ? 0 : 1;
        SkASSERT(arg0Subexpr);

        const Expression* arg1Subexpr = nullptr;
        if (arg1) {
            arg1Subexpr = arg1->getConstantSubexpression(arg1Index);
            arg1Index += arg1->type().isScalar() ? 0 : 1;
            SkASSERT(arg1Subexpr);
        }

        const Expression* arg2Subexpr = nullptr;
        if (arg2) {
            arg2Subexpr = arg2->getConstantSubexpression(arg2Index);
            arg2Index += arg2->type().isScalar() ? 0 : 1;
            SkASSERT(arg2Subexpr);
        }

        T0 value = eval(arg0Subexpr->as<Literal<T0>>().value(),
                        arg1Subexpr ? arg1Subexpr->as<Literal<T1>>().value() : T1{},
                        arg2Subexpr ? arg2Subexpr->as<Literal<T2>>().value() : T2{});

        if constexpr (std::is_floating_point<T0>::value) {
            // If evaluation of the intrinsic yields a non-finite value, do not optimize.
            if (!std::isfinite(value)) {
                return nullptr;
            }
        }

        array.push_back(Literal<T0>::Make(arg0Subexpr->fOffset, value, &type));
    }

    return ConstructorCompound::Make(context, arg0->fOffset, compoundType, std::move(array));
}

template <typename T>
static std::unique_ptr<Expression> evaluate_intrinsic(const Context& context,
                                                      const ExpressionArray& arguments,
                                                      const std::function<T(T)>& eval) {
    SkASSERT(arguments.size() == 1);

    if constexpr (std::is_same<T, bool>::value) {
        SkASSERT(arguments.front()->type().componentType().isBoolean());
    }
    if constexpr (std::is_same<T, float>::value) {
        SkASSERT(arguments.front()->type().componentType().isFloat());
    }
    if constexpr (std::is_same<T, SKSL_INT>::value) {
        SkASSERT(arguments.front()->type().componentType().isInteger());
    }

    return evaluate_n_way_intrinsic_of_type<T, T, T>(
            context, arguments.front().get(), /*arg1=*/nullptr, /*arg2=*/nullptr,
            [&eval](T a, T, T) { return eval(a); });
}

template <typename FN>
static std::unique_ptr<Expression> evaluate_intrinsic_numeric(const Context& context,
                                                              const ExpressionArray& arguments,
                                                              const FN& eval) {
    SkASSERT(arguments.size() == 1);
    const Type& type = arguments.front()->type().componentType();

    if (type.isFloat()) {
        return evaluate_intrinsic<float>(context, arguments, eval);
    }
    if (type.isInteger()) {
        return evaluate_intrinsic<SKSL_INT>(context, arguments, eval);
    }

    SkDEBUGFAILF("unsupported type %s", type.description().c_str());
    return nullptr;
}

template <typename FN>
static std::unique_ptr<Expression> evaluate_pairwise_intrinsic(const Context& context,
                                                               const ExpressionArray& arguments,
                                                               const FN& eval) {
    SkASSERT(arguments.size() == 2);
    const Type& type = arguments.front()->type().componentType();

    if (type.isFloat()) {
        return evaluate_n_way_intrinsic_of_type<float, float, float>(
                context, arguments[0].get(), arguments[1].get(), /*arg2=*/nullptr,
                [&eval](float a, float b, float) { return eval(a, b); });
    }
    if (type.isInteger()) {
        return evaluate_n_way_intrinsic_of_type<SKSL_INT, SKSL_INT, SKSL_INT>(
                context, arguments[0].get(), arguments[1].get(), /*arg2=*/nullptr,
                [&eval](SKSL_INT a, SKSL_INT b, SKSL_INT) { return eval(a, b); });
    }

    SkDEBUGFAILF("unsupported type %s", type.description().c_str());
    return nullptr;
}

template <typename FN>
static std::unique_ptr<Expression> evaluate_3_way_intrinsic(const Context& context,
                                                            const ExpressionArray& arguments,
                                                            const FN& eval) {
    SkASSERT(arguments.size() == 3);
    const Type& type = arguments.front()->type().componentType();

    if (type.isFloat()) {
        return evaluate_n_way_intrinsic_of_type<float, float, float>(
                context, arguments[0].get(), arguments[1].get(), arguments[2].get(), eval);
    }
    if (type.isInteger()) {
        return evaluate_n_way_intrinsic_of_type<SKSL_INT, SKSL_INT, SKSL_INT>(
                context, arguments[0].get(), arguments[1].get(), arguments[2].get(), eval);
    }

    SkDEBUGFAILF("unsupported type %s", type.description().c_str());
    return nullptr;
}

static std::unique_ptr<Expression> optimize_intrinsic_call(const Context& context,
                                                           IntrinsicKind intrinsic,
                                                           const ExpressionArray& arguments) {
    using namespace SkSL::dsl;
    switch (intrinsic) {
        // 8.1 : Angle and Trigonometry Functions
        case k_radians_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return a * 0.0174532925; });
        case k_degrees_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return a * 57.2957795; });
        case k_sin_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::sin(a); });
        case k_cos_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::cos(a); });
        case k_tan_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::tan(a); });
        case k_asin_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::asin(a); });
        case k_acos_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::acos(a); });
        case k_atan_IntrinsicKind:
            if (arguments.size() == 1) {
                return evaluate_intrinsic<float>(
                        context, arguments, [](float a) { return std::atan(a); });
            } else {
                SkASSERT(arguments.size() == 2);
                return evaluate_pairwise_intrinsic(
                        context, arguments, [](auto a, auto b) { return std::atan2(a, b); });
            }

        // 8.2 : Exponential Functions
        case k_pow_IntrinsicKind:
            return evaluate_pairwise_intrinsic(context, arguments,
                                               [](auto x, auto y) { return std::pow(x, y); });
        case k_exp_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::exp(a); });
        case k_log_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::log(a); });
        case k_exp2_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::exp2(a); });
        case k_log2_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::log2(a); });
        case k_sqrt_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::sqrt(a); });
        case k_inversesqrt_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return 1 / std::sqrt(a); });

        // 8.3 : Common Functions
        case k_abs_IntrinsicKind:
            return evaluate_intrinsic_numeric(context, arguments,
                                              [](auto a) { return std::abs(a); });
        case k_sign_IntrinsicKind:
            return evaluate_intrinsic_numeric(context, arguments,
                                              [](auto a) { return (a > 0) - (a < 0); });
        case k_floor_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::floor(a); });
        case k_ceil_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::ceil(a); });
        case k_fract_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return a - std::floor(a); });
        case k_mod_IntrinsicKind:
            return evaluate_pairwise_intrinsic(
                    context, arguments, [](auto x, auto y) { return x - y * std::floor(x / y); });

        case k_min_IntrinsicKind:
            return evaluate_pairwise_intrinsic(context, arguments,
                                               [](auto a, auto b) { return (a < b) ? a : b; });
        case k_max_IntrinsicKind:
            return evaluate_pairwise_intrinsic(context, arguments,
                                               [](auto a, auto b) { return (a > b) ? a : b; });
        case k_clamp_IntrinsicKind:
            return evaluate_3_way_intrinsic(context, arguments,
                    [](auto x, auto l, auto h) { return (x < l) ? l : (x > h) ? h : x; });
        case k_saturate_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return (a < 0) ? 0 : (a > 1) ? 1 : a; });
        case k_mix_IntrinsicKind:
            if (arguments[2]->type().componentType().isBoolean()) {
                const SkSL::Type& numericType = arguments[0]->type().componentType();
                const auto eval = [](auto x, auto y, bool a) { return a ? y : x; };

                if (numericType.isFloat()) {
                    return evaluate_n_way_intrinsic_of_type<float, float, bool>(
                        context, arguments[0].get(), arguments[1].get(), arguments[2].get(), eval);
                } else if (numericType.isInteger()) {
                    return evaluate_n_way_intrinsic_of_type<SKSL_INT, SKSL_INT, bool>(
                        context, arguments[0].get(), arguments[1].get(), arguments[2].get(), eval);
                } else if (numericType.isBoolean()) {
                    return evaluate_n_way_intrinsic_of_type<bool, bool, bool>(
                        context, arguments[0].get(), arguments[1].get(), arguments[2].get(), eval);
                }

                SkDEBUGFAILF("unsupported type %s", numericType.description().c_str());
                return nullptr;
            } else {
                return evaluate_3_way_intrinsic(context, arguments,
                                        [](auto x, auto y, auto a) { return x * (1 - a) + y * a; });
            }
        case k_step_IntrinsicKind:
            return evaluate_pairwise_intrinsic(context, arguments,
                                               [](auto e, auto x) { return (x < e) ? 0 : 1; });
        case k_smoothstep_IntrinsicKind:
            return evaluate_3_way_intrinsic(context, arguments, [](auto edge0, auto edge1, auto x) {
                auto t = (x - edge0) / (edge1 - edge0);
                t = (t < 0) ? 0 : (t > 1) ? 1 : t;
                return t * t * (3.0 - 2.0 * t);
            });

        // 8.4 : Geometric Functions
        case k_length_IntrinsicKind:
            return coalesce_vector<float>(arguments, /*startingState=*/0,
                                         [](float a, float b) { return a + (b * b); },
                                         [](float a) { return std::sqrt(a); });
        case k_distance_IntrinsicKind:
            return coalesce_pairwise_vectors<float>(
                    arguments, /*startingState=*/0,
                    [](float a, float b, float c) { b -= c; return a + (b * b); },
                    [](float a) { return std::sqrt(a); });
        case k_dot_IntrinsicKind:
            return coalesce_pairwise_vectors<float>(
                    arguments, /*startingState=*/0,
                    [](float a, float b, float c) { return a + (b * c); },
                    /*finalize=*/nullptr);
        case k_cross_IntrinsicKind: {
            auto Value = [&](int a, int n) -> float {
                return arguments[a]->getConstantSubexpression(n)->as<FloatLiteral>().value();
            };
            auto X = [&](int n) -> float { return Value(0, n); };
            auto Y = [&](int n) -> float { return Value(1, n); };
            SkASSERT(arguments[0]->type().columns() == 3);  // the vec2 form is not a real intrinsic
            return DSLType::Construct(&arguments[0]->type(),
                                      X(1) * Y(2) - Y(1) * X(2),
                                      X(2) * Y(0) - Y(2) * X(0),
                                      X(0) * Y(1) - Y(0) * X(1)).release();
        }
        case k_normalize_IntrinsicKind: {
            auto Vec = [&] { return DSLExpression{arguments[0]->clone()}; };
            return (Vec() / Length(Vec())).release();
        }
        case k_faceforward_IntrinsicKind: {
            auto N    = [&] { return DSLExpression{arguments[0]->clone()}; };
            auto I    = [&] { return DSLExpression{arguments[1]->clone()}; };
            auto NRef = [&] { return DSLExpression{arguments[2]->clone()}; };
            return (N() * Select(Dot(NRef(), I()) < 0, 1, -1)).release();
        }
        case k_reflect_IntrinsicKind: {
            auto I    = [&] { return DSLExpression{arguments[0]->clone()}; };
            auto N    = [&] { return DSLExpression{arguments[1]->clone()}; };
            return (I() - 2.0 * Dot(N(), I()) * N()).release();
        }
        case k_refract_IntrinsicKind: {
            auto I    = [&] { return DSLExpression{arguments[0]->clone()}; };
            auto N    = [&] { return DSLExpression{arguments[1]->clone()}; };
            auto Eta  = [&] { return DSLExpression{arguments[2]->clone()}; };

            std::unique_ptr<Expression> k =
                    (1 - Pow(Eta(), 2) * (1 - Pow(Dot(N(), I()), 2))).release();
            if (!k->is<FloatLiteral>()) {
                return nullptr;
            }
            float kValue = k->as<FloatLiteral>().value();
            return ((kValue < 0) ?
                       (0 * I()) :
                       (Eta() * I() - (Eta() * Dot(N(), I()) + std::sqrt(kValue)) * N())).release();
        }

        // 8.5 : Matrix Functions
        case k_matrixCompMult_IntrinsicKind:
            return evaluate_pairwise_intrinsic(context, arguments,
                                               [](auto x, auto y) { return x * y; });

        // Not supported until GLSL 1.40. Poly-filled by SkSL:
        case k_inverse_IntrinsicKind: {
            auto M = [&](int c, int r) -> float {
                int index = (arguments[0]->type().rows() * c) + r;
                return arguments[0]->getConstantSubexpression(index)->as<FloatLiteral>().value();
            };
            // Our matrix inverse is adapted from the logic in GLSLCodeGenerator::writeInverseHack.
            switch (arguments[0]->type().slotCount()) {
                case 4: {
                    float a00 = M(0, 0), a01 = M(0, 1);
                    float a10 = M(1, 0), a11 = M(1, 1);
                    float ind = 1 / (a00 * a11 - a01 * a10);  // inverse determinant
                    if (!std::isfinite(ind)) {
                        return nullptr;
                    }
                    return DSLType::Construct(&arguments[0]->type(),
                                               a11 * ind, -a01 * ind,
                                              -a10 * ind,  a00 * ind).release();
                }
                case 9: {
                    float a00 = M(0, 0), a01 = M(0, 1), a02 = M(0, 2);
                    float a10 = M(1, 0), a11 = M(1, 1), a12 = M(1, 2);
                    float a20 = M(2, 0), a21 = M(2, 1), a22 = M(2, 2);
                    float b01 =  a22 * a11 - a12 * a21;
                    float b11 = -a22 * a10 + a12 * a20;
                    float b21 =  a21 * a10 - a11 * a20;
                    float ind = 1 / (a00 * b01 + a01 * b11 + a02 * b21);  // inverse determinant
                    if (!std::isfinite(ind)) {
                        return nullptr;
                    }
                    return DSLType::Construct(&arguments[0]->type(),
                        b01 * ind, (-a22 * a01 + a02 * a21) * ind, ( a12 * a01 - a02 * a11) * ind,
                        b11 * ind, ( a22 * a00 - a02 * a20) * ind, (-a12 * a00 + a02 * a10) * ind,
                        b21 * ind, (-a21 * a00 + a01 * a20) * ind, ( a11 * a00 - a01 * a10) * ind)
                    .release();
                }
                case 16: {
                    float a00 = M(0, 0), a01 = M(0, 1), a02 = M(0, 2), a03 = M(0, 3);
                    float a10 = M(1, 0), a11 = M(1, 1), a12 = M(1, 2), a13 = M(1, 3);
                    float a20 = M(2, 0), a21 = M(2, 1), a22 = M(2, 2), a23 = M(2, 3);
                    float a30 = M(3, 0), a31 = M(3, 1), a32 = M(3, 2), a33 = M(3, 3);
                    float b00 = a00 * a11 - a01 * a10;
                    float b01 = a00 * a12 - a02 * a10;
                    float b02 = a00 * a13 - a03 * a10;
                    float b03 = a01 * a12 - a02 * a11;
                    float b04 = a01 * a13 - a03 * a11;
                    float b05 = a02 * a13 - a03 * a12;
                    float b06 = a20 * a31 - a21 * a30;
                    float b07 = a20 * a32 - a22 * a30;
                    float b08 = a20 * a33 - a23 * a30;
                    float b09 = a21 * a32 - a22 * a31;
                    float b10 = a21 * a33 - a23 * a31;
                    float b11 = a22 * a33 - a23 * a32;
                    float ind = 1 / (b00 * b11 - b01 * b10 + b02 * b09 +
                                     b03 * b08 - b04 * b07 + b05 * b06);  // inverse determinant
                    if (!std::isfinite(ind)) {
                        return nullptr;
                    }
                    return DSLType::Construct(&arguments[0]->type(),
                                              (a11 * b11 - a12 * b10 + a13 * b09) * ind,
                                              (a02 * b10 - a01 * b11 - a03 * b09) * ind,
                                              (a31 * b05 - a32 * b04 + a33 * b03) * ind,
                                              (a22 * b04 - a21 * b05 - a23 * b03) * ind,
                                              (a12 * b08 - a10 * b11 - a13 * b07) * ind,
                                              (a00 * b11 - a02 * b08 + a03 * b07) * ind,
                                              (a32 * b02 - a30 * b05 - a33 * b01) * ind,
                                              (a20 * b05 - a22 * b02 + a23 * b01) * ind,
                                              (a10 * b10 - a11 * b08 + a13 * b06) * ind,
                                              (a01 * b08 - a00 * b10 - a03 * b06) * ind,
                                              (a30 * b04 - a31 * b02 + a33 * b00) * ind,
                                              (a21 * b02 - a20 * b04 - a23 * b00) * ind,
                                              (a11 * b07 - a10 * b09 - a12 * b06) * ind,
                                              (a00 * b09 - a01 * b07 + a02 * b06) * ind,
                                              (a31 * b01 - a30 * b03 - a32 * b00) * ind,
                                              (a20 * b03 - a21 * b01 + a22 * b00) * ind).release();
                    break;
                }
            }
            SkDEBUGFAILF("unsupported type %s", arguments[0]->type().description().c_str());
            return nullptr;
            break;
        }

        // 8.6 : Vector Relational Functions
        case k_lessThan_IntrinsicKind:
            return optimize_comparison(context, arguments, [](auto a, auto b) { return a < b; });

        case k_lessThanEqual_IntrinsicKind:
            return optimize_comparison(context, arguments, [](auto a, auto b) { return a <= b; });

        case k_greaterThan_IntrinsicKind:
            return optimize_comparison(context, arguments, [](auto a, auto b) { return a > b; });

        case k_greaterThanEqual_IntrinsicKind:
            return optimize_comparison(context, arguments, [](auto a, auto b) { return a >= b; });

        case k_equal_IntrinsicKind:
            return optimize_comparison(context, arguments, [](auto a, auto b) { return a == b; });

        case k_notEqual_IntrinsicKind:
            return optimize_comparison(context, arguments, [](auto a, auto b) { return a != b; });

        case k_any_IntrinsicKind:
            return coalesce_vector<bool>(arguments, /*startingState=*/false,
                                         [](bool a, bool b) { return a || b; },
                                         /*finalize=*/nullptr);
        case k_all_IntrinsicKind:
            return coalesce_vector<bool>(arguments, /*startingState=*/true,
                                         [](bool a, bool b) { return a && b; },
                                         /*finalize=*/nullptr);
        case k_not_IntrinsicKind:
            return evaluate_intrinsic<bool>(context, arguments, [](bool a) { return !a; });

        // Additional intrinsics not required by GLSL ES2:
        case k_sinh_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::sinh(a); });
        case k_cosh_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::cosh(a); });
        case k_tanh_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::tanh(a); });
        case k_trunc_IntrinsicKind:
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::trunc(a); });
        case k_round_IntrinsicKind:      // GLSL `round` documents its rounding mode as unspecified
        case k_roundEven_IntrinsicKind:  // and is allowed to behave identically to `roundEven`.
            return evaluate_intrinsic<float>(context, arguments,
                                             [](float a) { return std::round(a / 2) * 2; });
        default:
            return nullptr;
    }
}

bool FunctionCall::hasProperty(Property property) const {
    if (property == Property::kSideEffects &&
        (this->function().modifiers().fFlags & Modifiers::kHasSideEffects_Flag)) {
        return true;
    }
    for (const auto& arg : this->arguments()) {
        if (arg->hasProperty(property)) {
            return true;
        }
    }
    return false;
}

std::unique_ptr<Expression> FunctionCall::clone() const {
    ExpressionArray cloned;
    cloned.reserve_back(this->arguments().size());
    for (const std::unique_ptr<Expression>& arg : this->arguments()) {
        cloned.push_back(arg->clone());
    }
    return std::make_unique<FunctionCall>(
            fOffset, &this->type(), &this->function(), std::move(cloned));
}

String FunctionCall::description() const {
    String result = String(this->function().name()) + "(";
    String separator;
    for (const std::unique_ptr<Expression>& arg : this->arguments()) {
        result += separator;
        result += arg->description();
        separator = ", ";
    }
    result += ")";
    return result;
}

std::unique_ptr<Expression> FunctionCall::Convert(const Context& context,
                                                  int offset,
                                                  const FunctionDeclaration& function,
                                                  ExpressionArray arguments) {
    // Reject function calls with the wrong number of arguments.
    if (function.parameters().size() != arguments.size()) {
        String msg = "call to '" + function.name() + "' expected " +
                     to_string((int)function.parameters().size()) + " argument";
        if (function.parameters().size() != 1) {
            msg += "s";
        }
        msg += ", but found " + to_string(arguments.count());
        context.fErrors.error(offset, msg);
        return nullptr;
    }

    // GLSL ES 1.0 requires static recursion be rejected by the compiler. Also, our CPU back-end
    // cannot handle recursion (and is tied to strictES2Mode front-ends). The safest way to reject
    // all (potentially) recursive code is to disallow calls to functions before they're defined.
    if (context.fConfig->strictES2Mode() && !function.definition() && !function.isBuiltin()) {
        context.fErrors.error(offset, "call to undefined function '" + function.name() + "'");
        return nullptr;
    }

    // Resolve generic types.
    FunctionDeclaration::ParamTypes types;
    const Type* returnType;
    if (!function.determineFinalTypes(arguments, &types, &returnType)) {
        String msg = "no match for " + function.name() + "(";
        String separator;
        for (const std::unique_ptr<Expression>& arg : arguments) {
            msg += separator;
            msg += arg->type().displayName();
            separator = ", ";
        }
        msg += ")";
        context.fErrors.error(offset, msg);
        return nullptr;
    }

    for (size_t i = 0; i < arguments.size(); i++) {
        // Coerce each argument to the proper type.
        arguments[i] = types[i]->coerceExpression(std::move(arguments[i]), context);
        if (!arguments[i]) {
            return nullptr;
        }
        // Update the refKind on out-parameters, and ensure that they are actually assignable.
        const Modifiers& paramModifiers = function.parameters()[i]->modifiers();
        if (paramModifiers.fFlags & Modifiers::kOut_Flag) {
            const VariableRefKind refKind = paramModifiers.fFlags & Modifiers::kIn_Flag
                                                    ? VariableReference::RefKind::kReadWrite
                                                    : VariableReference::RefKind::kPointer;
            if (!Analysis::MakeAssignmentExpr(arguments[i].get(), refKind, &context.fErrors)) {
                return nullptr;
            }
        }
    }

    return Make(context, offset, returnType, function, std::move(arguments));
}

std::unique_ptr<Expression> FunctionCall::Make(const Context& context,
                                               int offset,
                                               const Type* returnType,
                                               const FunctionDeclaration& function,
                                               ExpressionArray arguments) {
    SkASSERT(function.parameters().size() == arguments.size());
    SkASSERT(function.definition() || function.isBuiltin() || !context.fConfig->strictES2Mode());

    if (context.fConfig->fSettings.fOptimize) {
        // We might be able to optimize built-in intrinsics.
        if (function.isIntrinsic() && has_compile_time_constant_arguments(arguments)) {
            // The function is an intrinsic and all inputs are compile-time constants. Optimize it.
            if (std::unique_ptr<Expression> expr =
                        optimize_intrinsic_call(context, function.intrinsicKind(), arguments)) {
                return expr;
            }
        }
    }

    return std::make_unique<FunctionCall>(offset, returnType, &function, std::move(arguments));
}

}  // namespace SkSL
