/**
 * Copyright (c) 2021-2026 Huawei Device Co., Ltd.
 * 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 "compiler/optimizer/ir/graph_visitor.h"
#include "compiler/optimizer/ir/graph.h"
#include "compiler/optimizer/ir/graph_checker_macros.h"

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CHECKER_DO_IF_NOT_VISITOR(visitor, cond, func) CHECKER_DO_IF_NOT_VISITOR_INTERNAL(visitor, InstChecker *, cond, func)

namespace ark::compiler {

class InstChecker : public GraphVisitor {
public:
    explicit InstChecker(const Graph *graph) : graph_(graph) {}

    const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override
    {
        return graph_->GetBlocksRPO();
    }

    template<typename... Args>
    static bool CheckType(DataType::Type type, Args... types) {
        return ((types == type) || ...);
    }

    static DataType::Type GetInputType(Inst* inst, size_t input)
    {
        return inst->GetInput(input).GetInst()->GetType();
    }

    static bool Run(const Graph *graph)
    {
        auto checker = InstChecker(graph);
        checker.VisitGraph();
        return checker.GetStatus();
    }

    bool GetStatus() const
    {
        return success_;
    }

    void SetStatus(bool status)
    {
        success_ = status;
    }

    const Graph *GetGraph() const
    {
        return graph_;
    }

    static void VisitNeg([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAbs([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSqrt([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitNot([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAdd([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSub([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMul([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMulOverflowCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitDiv([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMod([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMin([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMax([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitShl([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitShr([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAShr([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAnd([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitOr([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitXor([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitExtractBitfield([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCompare([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCmp([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCompareAnyType([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitGetAnyTypeName([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitCastAnyTypeValue([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCastValueToAnyType([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCast([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitBitcast([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitConstant([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::INT32, DataType::INT64, DataType::FLOAT32, DataType::FLOAT64, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitParameter([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitNullPtr([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitLoadUniqueObject([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitNewArray([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitNewObject([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitInitObject([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitInitEmptyString([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitInitString([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitLoadArray([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        if (inst->GetInputsCount() > 2) {
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::POINTER),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
        }
    }
    static void VisitLoadCompressedStringChar([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::UINT16),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreArray([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadObject([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadObjectDynamic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoad([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::POINTER, DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadNative([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::POINTER, DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::POINTER, DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStore([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::POINTER, DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreNative([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::POINTER, DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::POINTER, DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitResolveObjectField([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::UINT32),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitLoadResolvedObjectField([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::UINT32),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreObject([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreObjectDynamic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(4U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 4U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 3), DataType::ANY),
              std::cerr << "Wrong input 3 type '" << DataType::ToString(GetInputType(inst, 3)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreResolvedObjectField([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::UINT32),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitResolveObjectFieldStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitLoadResolvedObjectFieldStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitUnresolvedStoreStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitStoreResolvedObjectFieldStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLenArray([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadString([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitLoadFromConstantPool([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadConstArray([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitLoadConstantPool([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadLexicalEnv([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitFillConstArray([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitLoadType([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitUnresolvedLoadType([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitCheckCast([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::REFERENCE),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitIsInstance([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::REFERENCE),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitInitClass([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitLoadClass([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitLoadAndInitClass([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitUnresolvedLoadAndInitClass([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitLoadRuntimeClass([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitGetInstanceClass([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadImmediate([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitFunctionImmediate([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitLoadObjFromConst([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitGetGlobalVarAddress([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitNullCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitBoundsCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitRefTypeCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::REFERENCE),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitZeroCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitNegativeCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitNotPositiveCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitObjByIndexCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitAnyTypeCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitHclassCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitStringFlatCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitDeoptimize([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitDeoptimizeIf([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY, DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitDeoptimizeCompare([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY, DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::ANY, DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitDeoptimizeCompareImm([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::ANY, DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL, DataType::REFERENCE, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitIsMustDeoptimize([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitReturnVoid([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitReturn([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitReturnInlined([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitThrow([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitCallStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitResolveStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
        CHECKER_ASSERT(inst->GetInput(0).GetInst()->IsSaveState());
    }
    static void VisitCallResolvedStatic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCallVirtual([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitResolveVirtual([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitCallResolvedVirtual([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCallDynamic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::ANY, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCallIndirect([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCall([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMultiArray([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::REFERENCE),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMonitor([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitIntrinsic([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitCallNative([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitWrapObjectNative([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitBuiltin([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::VOID),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitResolveByName([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitAddI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSubI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::POINTER),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMulI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitDivI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitModI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitShlI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitShrI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAShrI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAndI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitOrI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitXorI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMAdd([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMSub([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitMNeg([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitOrNot([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAndNot([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitXorNot([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::BOOL),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAndSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitOrSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitXorSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAndNotSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitOrNotSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitXorNotSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAddSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSubSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitNegSR([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitBoundsCheckI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitLoadArrayI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadCompressedStringCharI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::UINT16),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreArrayI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadArrayPair([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadArrayPairI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadPairPart([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLoadObjectPair([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreArrayPair([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(4U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 4U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 3), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 3 type '" << DataType::ToString(GetInputType(inst, 3)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreArrayPairI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitStoreObjectPair([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::REFERENCE),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitReturnI([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitPhi([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::REFERENCE, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSpillFill([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitSaveState([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
    }
    static void VisitSafePoint([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
    }
    static void VisitSaveStateDeoptimize([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
    }
    static void VisitSaveStateOsr([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
    }
    static void VisitSelect([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(4U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 4U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 3), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 3 type '" << DataType::ToString(GetInputType(inst, 3)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSelectTransform([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(4U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 4U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 3), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 3 type '" << DataType::ToString(GetInputType(inst, 3)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSelectImm([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSelectImmTransform([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 2), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 2 type '" << DataType::ToString(GetInputType(inst, 2)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAddOverflow([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitSubOverflow([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitAddOverflowCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitSubOverflowCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(3U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 3U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(2).GetInst()->IsSaveState());
    }
    static void VisitNegOverflowAndZeroCheck([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
        CHECKER_ASSERT(inst->GetInput(1).GetInst()->IsSaveState());
    }
    static void VisitIf([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(2U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 2U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 1), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 1 type '" << DataType::ToString(GetInputType(inst, 1)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitIfImm([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitNOP([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitTry([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_ASSERT(!inst->HasUsers());
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitCatchPhi([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::REFERENCE, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
    }
    static void VisitLiveIn([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(0U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 0U);
    }
    static void VisitLiveOut([[maybe_unused]] GraphVisitor *v, [[maybe_unused]] Inst *inst)
    {
        CHECKER_DO_IF_NOT_VISITOR(v, CheckType(inst->GetType(), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER),
            std::cerr << "Wrong dst type '" << DataType::ToString(inst->GetType()) << "' for inst:\n" << *inst << std::endl);
        CHECKER_LE(1U, inst->GetInputsCount());
        CHECKER_LE(inst->GetInputsCount(), 1U);
          CHECKER_DO_IF_NOT_VISITOR(v, CheckType(GetInputType(inst, 0), DataType::BOOL, DataType::INT8, DataType::INT16, DataType::INT32, DataType::INT64, DataType::UINT8, DataType::UINT16, DataType::UINT32, DataType::UINT64, DataType::FLOAT32, DataType::FLOAT64, DataType::REFERENCE, DataType::POINTER, DataType::ANY),
              std::cerr << "Wrong input 0 type '" << DataType::ToString(GetInputType(inst, 0)) << "' for inst:\n" << *inst << std::endl);
    }

#include "optimizer/ir/visitor.inc"

private:
    const Graph *graph_{nullptr};
    bool success_ {true};
};

#undef CHECKER_DO_IF_NOT_VISITOR

}  // namespace ark::compiler
