1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#ifndef GRAPH_TEST_H
17b1994897Sopenharmony_ci#define GRAPH_TEST_H
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ci#include "bytecode_optimizer/ir_interface.h"
20b1994897Sopenharmony_ci#include "bytecode_optimizer/runtime_adapter.h"
21b1994897Sopenharmony_ci#include "libpandafile/class_data_accessor.h"
22b1994897Sopenharmony_ci#include "libpandafile/class_data_accessor-inl.h"
23b1994897Sopenharmony_ci#include "libpandafile/code_data_accessor-inl.h"
24b1994897Sopenharmony_ci#include "libpandafile/file.h"
25b1994897Sopenharmony_ci#include "libpandafile/method_data_accessor.h"
26b1994897Sopenharmony_ci#include "libpandabase/mem/arena_allocator.h"
27b1994897Sopenharmony_ci#include "libpandabase/mem/pool_manager.h"
28b1994897Sopenharmony_ci#include "optimizer/ir/graph.h"
29b1994897Sopenharmony_ci#include "optimizer/ir/runtime_interface.h"
30b1994897Sopenharmony_ci#include "optimizer/ir_builder/ir_builder.h"
31b1994897Sopenharmony_ci
32b1994897Sopenharmony_cinamespace panda::compiler {
33b1994897Sopenharmony_ciclass GraphTest {
34b1994897Sopenharmony_cipublic:
35b1994897Sopenharmony_ci    GraphTest()
36b1994897Sopenharmony_ci    {
37b1994897Sopenharmony_ci        PoolManager::Initialize(PoolType::MALLOC);
38b1994897Sopenharmony_ci    }
39b1994897Sopenharmony_ci
40b1994897Sopenharmony_ci    ~GraphTest()
41b1994897Sopenharmony_ci    {
42b1994897Sopenharmony_ci        PoolManager::Finalize();
43b1994897Sopenharmony_ci    }
44b1994897Sopenharmony_ci
45b1994897Sopenharmony_ci    static bool HasTryCatch(const panda_file::File &panda_file, panda_file::File::EntityId code_id)
46b1994897Sopenharmony_ci    {
47b1994897Sopenharmony_ci        panda_file::CodeDataAccessor cda(panda_file, code_id);
48b1994897Sopenharmony_ci        return cda.GetTriesSize() != 0;
49b1994897Sopenharmony_ci    }
50b1994897Sopenharmony_ci
51b1994897Sopenharmony_ci    template <class Callback>
52b1994897Sopenharmony_ci    void TestBuildGraphFromFile(const std::string &pfile_name, const Callback &cb, bool skip_try_catch = false)
53b1994897Sopenharmony_ci    {
54b1994897Sopenharmony_ci        auto pfile = panda_file::OpenPandaFile(pfile_name);
55b1994897Sopenharmony_ci        for (uint32_t id : pfile->GetClasses()) {
56b1994897Sopenharmony_ci            panda_file::File::EntityId record_id {id};
57b1994897Sopenharmony_ci            if (pfile->IsExternal(record_id)) {
58b1994897Sopenharmony_ci                continue;
59b1994897Sopenharmony_ci            }
60b1994897Sopenharmony_ci
61b1994897Sopenharmony_ci            panda_file::ClassDataAccessor cda {*pfile, record_id};
62b1994897Sopenharmony_ci            cda.EnumerateMethods([&pfile, &cb, &skip_try_catch](panda_file::MethodDataAccessor &mda) {
63b1994897Sopenharmony_ci                if (mda.IsExternal()) {
64b1994897Sopenharmony_ci                    return;
65b1994897Sopenharmony_ci                }
66b1994897Sopenharmony_ci
67b1994897Sopenharmony_ci                // `skip_try_catch` is required for tests like draw_cfg_test. Currently try-catch optimizations
68b1994897Sopenharmony_ci                // are disabled, and building graphs directly from abc files containing try-catch blocks may fail.
69b1994897Sopenharmony_ci                if (skip_try_catch && HasTryCatch(*pfile, mda.GetCodeId().value())) {
70b1994897Sopenharmony_ci                    return;
71b1994897Sopenharmony_ci                }
72b1994897Sopenharmony_ci
73b1994897Sopenharmony_ci                ArenaAllocator allocator {SpaceType::SPACE_TYPE_COMPILER};
74b1994897Sopenharmony_ci                ArenaAllocator local_allocator {SpaceType::SPACE_TYPE_COMPILER, nullptr, true};
75b1994897Sopenharmony_ci
76b1994897Sopenharmony_ci                auto method_ptr = reinterpret_cast<compiler::RuntimeInterface::MethodPtr>(
77b1994897Sopenharmony_ci                    mda.GetMethodId().GetOffset());
78b1994897Sopenharmony_ci                panda::BytecodeOptimizerRuntimeAdapter adapter(mda.GetPandaFile());
79b1994897Sopenharmony_ci                auto *graph = allocator.New<Graph>(&allocator, &local_allocator, Arch::NONE, method_ptr, &adapter,
80b1994897Sopenharmony_ci                                                    false, nullptr, true, true);
81b1994897Sopenharmony_ci                graph->RunPass<panda::compiler::IrBuilder>();
82b1994897Sopenharmony_ci
83b1994897Sopenharmony_ci                auto method_name = std::string(utf::Mutf8AsCString(pfile->GetStringData(mda.GetNameId()).data));
84b1994897Sopenharmony_ci                auto pos = method_name.find_last_of("#");
85b1994897Sopenharmony_ci                if (pos != std::string::npos) {
86b1994897Sopenharmony_ci                    method_name = method_name.substr(pos + 1);
87b1994897Sopenharmony_ci                }
88b1994897Sopenharmony_ci                cb(graph, method_name);
89b1994897Sopenharmony_ci            });
90b1994897Sopenharmony_ci        }
91b1994897Sopenharmony_ci    }
92b1994897Sopenharmony_ci};
93b1994897Sopenharmony_ci
94b1994897Sopenharmony_ci} // namespace panda::compiler
95b1994897Sopenharmony_ci
96b1994897Sopenharmony_ci#endif  // GRAPH_TEST_H