// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/tint/transform/simplify_pointers.h"

#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

#include "src/tint/program_builder.h"
#include "src/tint/sem/block_statement.h"
#include "src/tint/sem/function.h"
#include "src/tint/sem/statement.h"
#include "src/tint/sem/variable.h"
#include "src/tint/transform/unshadow.h"

TINT_INSTANTIATE_TYPEINFO(tint::transform::SimplifyPointers);

namespace tint::transform {

namespace {

/// PointerOp describes either possible indirection or address-of action on an
/// expression.
struct PointerOp {
    /// Positive: Number of times the `expr` was dereferenced (*expr)
    /// Negative: Number of times the `expr` was 'addressed-of' (&expr)
    /// Zero: no pointer op on `expr`
    int indirections = 0;
    /// The expression being operated on
    const ast::Expression* expr = nullptr;
};

}  // namespace

/// The PIMPL state for the SimplifyPointers transform
struct SimplifyPointers::State {
    /// The clone context
    CloneContext& ctx;

    /// Constructor
    /// @param context the clone context
    explicit State(CloneContext& context) : ctx(context) {}

    /// Traverses the expression `expr` looking for non-literal array indexing
    /// expressions that would affect the computed address of a pointer
    /// expression. The function-like argument `cb` is called for each found.
    /// @param expr the expression to traverse
    /// @param cb a function-like object with the signature
    /// `void(const ast::Expression*)`, which is called for each array index
    /// expression
    template <typename F>
    static void CollectSavedArrayIndices(const ast::Expression* expr, F&& cb) {
        if (auto* a = expr->As<ast::IndexAccessorExpression>()) {
            CollectSavedArrayIndices(a->object, cb);
            if (!a->index->Is<ast::LiteralExpression>()) {
                cb(a->index);
            }
            return;
        }

        if (auto* m = expr->As<ast::MemberAccessorExpression>()) {
            CollectSavedArrayIndices(m->structure, cb);
            return;
        }

        if (auto* u = expr->As<ast::UnaryOpExpression>()) {
            CollectSavedArrayIndices(u->expr, cb);
            return;
        }

        // Note: Other ast::Expression types can be safely ignored as they cannot be
        // used to generate a reference or pointer.
        // See https://gpuweb.github.io/gpuweb/wgsl/#forming-references-and-pointers
    }

    /// Reduce walks the expression chain, collapsing all address-of and
    /// indirection ops into a PointerOp.
    /// @param in the expression to walk
    /// @returns the reduced PointerOp
    PointerOp Reduce(const ast::Expression* in) const {
        PointerOp op{0, in};
        while (true) {
            if (auto* unary = op.expr->As<ast::UnaryOpExpression>()) {
                switch (unary->op) {
                    case ast::UnaryOp::kIndirection:
                        op.indirections++;
                        op.expr = unary->expr;
                        continue;
                    case ast::UnaryOp::kAddressOf:
                        op.indirections--;
                        op.expr = unary->expr;
                        continue;
                    default:
                        break;
                }
            }
            if (auto* user = ctx.src->Sem().Get<sem::VariableUser>(op.expr)) {
                auto* var = user->Variable();
                if (var->Is<sem::LocalVariable>() &&       //
                    var->Declaration()->Is<ast::Let>() &&  //
                    var->Type()->Is<sem::Pointer>()) {
                    op.expr = var->Declaration()->constructor;
                    continue;
                }
            }
            return op;
        }
    }

    /// Performs the transformation
    void Run() {
        // A map of saved expressions to their saved variable name
        std::unordered_map<const ast::Expression*, Symbol> saved_vars;

        // Register the ast::Expression transform handler.
        // This performs two different transformations:
        // * Identifiers that resolve to the pointer-typed `let` declarations are
        // replaced with the recursively inlined initializer expression for the
        // `let` declaration.
        // * Sub-expressions inside the pointer-typed `let` initializer expression
        // that have been hoisted to a saved variable are replaced with the saved
        // variable identifier.
        ctx.ReplaceAll([&](const ast::Expression* expr) -> const ast::Expression* {
            // Look to see if we need to swap this Expression with a saved variable.
            auto it = saved_vars.find(expr);
            if (it != saved_vars.end()) {
                return ctx.dst->Expr(it->second);
            }

            // Reduce the expression, folding away chains of address-of / indirections
            auto op = Reduce(expr);

            // Clone the reduced root expression
            expr = ctx.CloneWithoutTransform(op.expr);

            // And reapply the minimum number of address-of / indirections
            for (int i = 0; i < op.indirections; i++) {
                expr = ctx.dst->Deref(expr);
            }
            for (int i = 0; i > op.indirections; i--) {
                expr = ctx.dst->AddressOf(expr);
            }
            return expr;
        });

        // Find all the pointer-typed `let` declarations.
        // Note that these must be function-scoped, as module-scoped `let`s are not
        // permitted.
        for (auto* node : ctx.src->ASTNodes().Objects()) {
            if (auto* let = node->As<ast::VariableDeclStatement>()) {
                if (!let->variable->Is<ast::Let>()) {
                    continue;  // Not a `let` declaration. Ignore.
                }

                auto* var = ctx.src->Sem().Get(let->variable);
                if (!var->Type()->Is<sem::Pointer>()) {
                    continue;  // Not a pointer type. Ignore.
                }

                // We're dealing with a pointer-typed `let` declaration.

                // Scan the initializer expression for array index expressions that need
                // to be hoist to temporary "saved" variables.
                std::vector<const ast::VariableDeclStatement*> saved;
                CollectSavedArrayIndices(
                    var->Declaration()->constructor, [&](const ast::Expression* idx_expr) {
                        // We have a sub-expression that needs to be saved.
                        // Create a new variable
                        auto saved_name = ctx.dst->Symbols().New(
                            ctx.src->Symbols().NameFor(var->Declaration()->symbol) + "_save");
                        auto* decl = ctx.dst->Decl(ctx.dst->Let(saved_name, ctx.Clone(idx_expr)));
                        saved.emplace_back(decl);
                        // Record the substitution of `idx_expr` to the saved variable
                        // with the symbol `saved_name`. This will be used by the
                        // ReplaceAll() handler above.
                        saved_vars.emplace(idx_expr, saved_name);
                    });

                // Find the place to insert the saved declarations.
                // Special care needs to be made for lets declared as the initializer
                // part of for-loops. In this case the block will hold the for-loop
                // statement, not the let.
                if (!saved.empty()) {
                    auto* stmt = ctx.src->Sem().Get(let);
                    auto* block = stmt->Block();
                    // Find the statement owned by the block (either the let decl or a
                    // for-loop)
                    while (block != stmt->Parent()) {
                        stmt = stmt->Parent();
                    }
                    // Declare the stored variables just before stmt. Order here is
                    // important as order-of-operations needs to be preserved.
                    // CollectSavedArrayIndices() visits the LHS of an index accessor
                    // before the index expression.
                    for (auto* decl : saved) {
                        // Note that repeated calls to InsertBefore() with the same `before`
                        // argument will result in nodes to inserted in the order the
                        // calls are made (last call is inserted last).
                        ctx.InsertBefore(block->Declaration()->statements, stmt->Declaration(),
                                         decl);
                    }
                }

                // As the original `let` declaration will be fully inlined, there's no
                // need for the original declaration to exist. Remove it.
                RemoveStatement(ctx, let);
            }
        }
        ctx.Clone();
    }
};

SimplifyPointers::SimplifyPointers() = default;

SimplifyPointers::~SimplifyPointers() = default;

void SimplifyPointers::Run(CloneContext& ctx, const DataMap&, DataMap&) const {
    State(ctx).Run();
}

}  // namespace tint::transform
