/*
 * 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 "include/core/SkSpan.h"
#include "include/core/SkTypes.h"
#include "include/private/SkSLDefines.h"
#include "include/private/SkSLIRNode.h"
#include "include/private/SkSLProgramElement.h"
#include "include/private/SkSLStatement.h"
#include "include/private/base/SkTArray.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/analysis/SkSLProgramUsage.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
#include "src/sksl/ir/SkSLIfStatement.h"
#include "src/sksl/ir/SkSLNop.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLSwitchCase.h"
#include "src/sksl/ir/SkSLSwitchStatement.h"
#include "src/sksl/transform/SkSLProgramWriter.h"
#include "src/sksl/transform/SkSLTransform.h"

#include <memory>
#include <vector>

namespace SkSL {

class Expression;

static void eliminate_unreachable_code(SkSpan<std::unique_ptr<ProgramElement>> elements,
                                       ProgramUsage* usage) {
    class UnreachableCodeEliminator : public ProgramWriter {
    public:
        UnreachableCodeEliminator(ProgramUsage* usage) : fUsage(usage) {
            fFoundFunctionExit.push_back(false);
            fFoundBlockExit.push_back(false);
        }

        bool visitExpressionPtr(std::unique_ptr<Expression>& expr) override {
            // We don't need to look inside expressions at all.
            return false;
        }

        bool visitStatementPtr(std::unique_ptr<Statement>& stmt) override {
            if (fFoundFunctionExit.back() || fFoundBlockExit.back()) {
                // If we already found an exit in this section, anything beyond it is dead code.
                if (!stmt->is<Nop>()) {
                    // Eliminate the dead statement by substituting a Nop.
                    fUsage->remove(stmt.get());
                    stmt = Nop::Make();
                }
                return false;
            }

            switch (stmt->kind()) {
                case Statement::Kind::kReturn:
                case Statement::Kind::kDiscard:
                    // We found a function exit on this path.
                    fFoundFunctionExit.back() = true;
                    break;

                case Statement::Kind::kBreak:
                    // A `break` statement can either be breaking out of a loop or terminating an
                    // individual switch case. We treat both cases the same way: they only apply
                    // to the statements associated with the parent statement (i.e. enclosing loop
                    // block / preceding case label).
                case Statement::Kind::kContinue:
                    fFoundBlockExit.back() = true;
                    break;

                case Statement::Kind::kExpression:
                case Statement::Kind::kNop:
                case Statement::Kind::kVarDeclaration:
                    // These statements don't affect control flow.
                    break;

                case Statement::Kind::kBlock:
                    // Blocks are on the straight-line path and don't affect control flow.
                    return INHERITED::visitStatementPtr(stmt);

                case Statement::Kind::kDo: {
                    // Function-exits are allowed to propagate outside of a do-loop, because it
                    // always executes its body at least once.
                    fFoundBlockExit.push_back(false);
                    bool result = INHERITED::visitStatementPtr(stmt);
                    fFoundBlockExit.pop_back();
                    return result;
                }
                case Statement::Kind::kFor: {
                    // Function-exits are not allowed to propagate out, because a for-loop or while-
                    // loop could potentially run zero times.
                    fFoundFunctionExit.push_back(false);
                    fFoundBlockExit.push_back(false);
                    bool result = INHERITED::visitStatementPtr(stmt);
                    fFoundBlockExit.pop_back();
                    fFoundFunctionExit.pop_back();
                    return result;
                }
                case Statement::Kind::kIf: {
                    // This statement is conditional and encloses two inner sections of code.
                    // If both sides contain a function-exit or loop-exit, that exit is allowed to
                    // propagate out.
                    IfStatement& ifStmt = stmt->as<IfStatement>();

                    fFoundFunctionExit.push_back(false);
                    fFoundBlockExit.push_back(false);
                    bool result = (ifStmt.ifTrue() && this->visitStatementPtr(ifStmt.ifTrue()));
                    bool foundFunctionExitOnTrue = fFoundFunctionExit.back();
                    bool foundLoopExitOnTrue = fFoundBlockExit.back();
                    fFoundFunctionExit.pop_back();
                    fFoundBlockExit.pop_back();

                    fFoundFunctionExit.push_back(false);
                    fFoundBlockExit.push_back(false);
                    result |= (ifStmt.ifFalse() && this->visitStatementPtr(ifStmt.ifFalse()));
                    bool foundFunctionExitOnFalse = fFoundFunctionExit.back();
                    bool foundLoopExitOnFalse = fFoundBlockExit.back();
                    fFoundFunctionExit.pop_back();
                    fFoundBlockExit.pop_back();

                    fFoundFunctionExit.back() |= foundFunctionExitOnTrue &&
                                                 foundFunctionExitOnFalse;
                    fFoundBlockExit.back() |= foundLoopExitOnTrue &&
                                              foundLoopExitOnFalse;
                    return result;
                }
                case Statement::Kind::kSwitch: {
                    // In switch statements we consider unreachable code on a per-case basis.
                    SwitchStatement& sw = stmt->as<SwitchStatement>();
                    bool result = false;

                    // Tracks whether we found at least one case that doesn't lead to a return
                    // statement (potentially via fallthrough).
                    bool foundCaseWithoutReturn = false;
                    bool hasDefault = false;
                    for (std::unique_ptr<Statement>& c : sw.cases()) {
                        // We eliminate unreachable code within the statements of the individual
                        // case. Breaks are not allowed to propagate outside the case statement
                        // itself. Function returns are allowed to propagate out only if all cases
                        // have a return AND one of the cases is default (so that we know at least
                        // one of the branches will be taken). This is similar to how we handle if
                        // statements above.
                        fFoundFunctionExit.push_back(false);
                        fFoundBlockExit.push_back(false);

                        SwitchCase& sc = c->as<SwitchCase>();
                        result |= this->visitStatementPtr(sc.statement());

                        // When considering whether a case has a return we can propagate, we
                        // assume the following:
                        //     1. The default case is always placed last in a switch statement and
                        //        it is the last possible label reachable via fallthrough. Thus if
                        //        it does not contain a return statement, then we don't propagate a
                        //        function return.
                        //     2. In all other cases we prevent the return from propagating only if
                        //        we encounter a break statement. If no return or break is found,
                        //        we defer the decision to the fallthrough case. We won't propagate
                        //        a return unless we eventually encounter a default label.
                        //
                        // See resources/sksl/shared/SwitchWithEarlyReturn.sksl for test cases that
                        // exercise this.
                        if (sc.isDefault()) {
                            foundCaseWithoutReturn |= !fFoundFunctionExit.back();
                            hasDefault = true;
                        } else {
                            // We can only be sure that a case does not lead to a return if it
                            // doesn't fallthrough.
                            foundCaseWithoutReturn |=
                                    (!fFoundFunctionExit.back() && fFoundBlockExit.back());
                        }

                        fFoundFunctionExit.pop_back();
                        fFoundBlockExit.pop_back();
                    }

                    fFoundFunctionExit.back() |= !foundCaseWithoutReturn && hasDefault;
                    return result;
                }
                case Statement::Kind::kSwitchCase:
                    // We should never hit this case as switch cases are handled in the previous
                    // case.
                    SkUNREACHABLE;
            }

            return false;
        }

        ProgramUsage* fUsage;
        SkSTArray<32, bool> fFoundFunctionExit;
        SkSTArray<32, bool> fFoundBlockExit;

        using INHERITED = ProgramWriter;
    };

    for (std::unique_ptr<ProgramElement>& pe : elements) {
        if (pe->is<FunctionDefinition>()) {
            UnreachableCodeEliminator visitor{usage};
            visitor.visitStatementPtr(pe->as<FunctionDefinition>().body());
        }
    }
}

void Transform::EliminateUnreachableCode(Module& module, ProgramUsage* usage) {
    return eliminate_unreachable_code(SkSpan(module.fElements), usage);
}

void Transform::EliminateUnreachableCode(Program& program) {
    return eliminate_unreachable_code(SkSpan(program.fOwnedElements), program.fUsage.get());
}

}  // namespace SkSL
