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