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