1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 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#include <elf.h> 17b1994897Sopenharmony_ci#include "unit_test.h" 18b1994897Sopenharmony_ci#include "aot/aot_manager.h" 19b1994897Sopenharmony_ci#include "aot/aot_builder/aot_builder.h" 20b1994897Sopenharmony_ci#include "aot/compiled_method.h" 21b1994897Sopenharmony_ci#include "compiler/code_info/code_info_builder.h" 22b1994897Sopenharmony_ci#include "os/exec.h" 23b1994897Sopenharmony_ci#include "assembly-parser.h" 24b1994897Sopenharmony_ci#include "utils/string_helpers.h" 25b1994897Sopenharmony_ci#include "events/events.h" 26b1994897Sopenharmony_ci#include "mem/gc/gc_types.h" 27b1994897Sopenharmony_ci#include "runtime/include/file_manager.h" 28b1994897Sopenharmony_ci 29b1994897Sopenharmony_ci#include <regex> 30b1994897Sopenharmony_ci 31b1994897Sopenharmony_ciusing panda::panda_file::File; 32b1994897Sopenharmony_ci 33b1994897Sopenharmony_cinamespace panda::compiler { 34b1994897Sopenharmony_ciclass AotTest : public AsmTest { 35b1994897Sopenharmony_cipublic: 36b1994897Sopenharmony_ci AotTest() 37b1994897Sopenharmony_ci { 38b1994897Sopenharmony_ci std::string exe_path = GetExecPath(); 39b1994897Sopenharmony_ci auto pos = exe_path.rfind('/'); 40b1994897Sopenharmony_ci paoc_path_ = exe_path.substr(0, pos) + "/../bin/ark_aot"; 41b1994897Sopenharmony_ci aotdump_path_ = exe_path.substr(0, pos) + "/../bin/ark_aotdump"; 42b1994897Sopenharmony_ci } 43b1994897Sopenharmony_ci 44b1994897Sopenharmony_ci std::string GetPaocDirectory() const 45b1994897Sopenharmony_ci { 46b1994897Sopenharmony_ci auto pos = paoc_path_.rfind('/'); 47b1994897Sopenharmony_ci return paoc_path_.substr(0, pos); 48b1994897Sopenharmony_ci } 49b1994897Sopenharmony_ci 50b1994897Sopenharmony_ci const char *GetArchAsArgString() const 51b1994897Sopenharmony_ci { 52b1994897Sopenharmony_ci switch (target_arch) { 53b1994897Sopenharmony_ci case Arch::AARCH32: 54b1994897Sopenharmony_ci return "arm"; 55b1994897Sopenharmony_ci case Arch::AARCH64: 56b1994897Sopenharmony_ci return "arm64"; 57b1994897Sopenharmony_ci case Arch::X86: 58b1994897Sopenharmony_ci return "x86"; 59b1994897Sopenharmony_ci case Arch::X86_64: 60b1994897Sopenharmony_ci return "x86_64"; 61b1994897Sopenharmony_ci default: 62b1994897Sopenharmony_ci UNREACHABLE(); 63b1994897Sopenharmony_ci } 64b1994897Sopenharmony_ci } 65b1994897Sopenharmony_ci 66b1994897Sopenharmony_ci void RunAotdump(const std::string &aot_filename) 67b1994897Sopenharmony_ci { 68b1994897Sopenharmony_ci TmpFile tmpfile("aotdump.tmp"); 69b1994897Sopenharmony_ci 70b1994897Sopenharmony_ci auto res = os::exec::Exec(aotdump_path_.c_str(), "--show-code=disasm", "--output-file", tmpfile.GetFileName(), 71b1994897Sopenharmony_ci aot_filename.c_str()); 72b1994897Sopenharmony_ci ASSERT_TRUE(res) << "aotdump failed with error: " << res.Error().ToString(); 73b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0) << "aotdump return error code: " << res.Value(); 74b1994897Sopenharmony_ci } 75b1994897Sopenharmony_ci 76b1994897Sopenharmony_ci std::string paoc_path_; 77b1994897Sopenharmony_ci std::string aotdump_path_; 78b1994897Sopenharmony_ciprotected: 79b1994897Sopenharmony_ci Arch target_arch = Arch::AARCH64; 80b1994897Sopenharmony_ci}; 81b1994897Sopenharmony_ci 82b1994897Sopenharmony_ci#ifdef PANDA_COMPILER_TARGET_AARCH64 83b1994897Sopenharmony_ciTEST_F(AotTest, PaocBootPandaFiles) 84b1994897Sopenharmony_ci{ 85b1994897Sopenharmony_ci // Test basic functionality only in host mode. 86b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 87b1994897Sopenharmony_ci return; 88b1994897Sopenharmony_ci } 89b1994897Sopenharmony_ci TmpFile panda_fname("test.pf"); 90b1994897Sopenharmony_ci TmpFile aot_fname("./test.an"); 91b1994897Sopenharmony_ci static const std::string location = "/data/local/tmp"; 92b1994897Sopenharmony_ci static const std::string panda_file_path = location + "/" + panda_fname.GetFileName(); 93b1994897Sopenharmony_ci 94b1994897Sopenharmony_ci auto source = R"( 95b1994897Sopenharmony_ci .function void dummy() { 96b1994897Sopenharmony_ci return.void 97b1994897Sopenharmony_ci } 98b1994897Sopenharmony_ci )"; 99b1994897Sopenharmony_ci 100b1994897Sopenharmony_ci { 101b1994897Sopenharmony_ci pandasm::Parser parser; 102b1994897Sopenharmony_ci auto res = parser.Parse(source); 103b1994897Sopenharmony_ci ASSERT_TRUE(res); 104b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname.GetFileName(), res.Value())); 105b1994897Sopenharmony_ci } 106b1994897Sopenharmony_ci 107b1994897Sopenharmony_ci // Correct path to arkstdlib.abc 108b1994897Sopenharmony_ci { 109b1994897Sopenharmony_ci auto pandastdlib_path = GetPaocDirectory() + "/../pandastdlib/arkstdlib.abc"; 110b1994897Sopenharmony_ci auto res = os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_fname.GetFileName(), "--paoc-output", 111b1994897Sopenharmony_ci aot_fname.GetFileName(), "--paoc-location", location.c_str(), "--paoc-arch", 112b1994897Sopenharmony_ci GetArchAsArgString(), "--boot-panda-files", pandastdlib_path.c_str()); 113b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 114b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0) << "Aot compiler failed with code " << res.Value(); 115b1994897Sopenharmony_ci RunAotdump(aot_fname.GetFileName()); 116b1994897Sopenharmony_ci } 117b1994897Sopenharmony_ci} 118b1994897Sopenharmony_ci 119b1994897Sopenharmony_ciTEST_F(AotTest, PaocLocation) 120b1994897Sopenharmony_ci{ 121b1994897Sopenharmony_ci // Test basic functionality only in host mode. 122b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 123b1994897Sopenharmony_ci return; 124b1994897Sopenharmony_ci } 125b1994897Sopenharmony_ci TmpFile panda_fname("test.pf"); 126b1994897Sopenharmony_ci TmpFile aot_fname("./test.an"); 127b1994897Sopenharmony_ci static const std::string location = "/data/local/tmp"; 128b1994897Sopenharmony_ci static const std::string panda_file_path = location + "/" + panda_fname.GetFileName(); 129b1994897Sopenharmony_ci 130b1994897Sopenharmony_ci auto source = R"( 131b1994897Sopenharmony_ci .function u32 add(u64 a0, u64 a1) { 132b1994897Sopenharmony_ci add a0, a1 133b1994897Sopenharmony_ci return 134b1994897Sopenharmony_ci } 135b1994897Sopenharmony_ci )"; 136b1994897Sopenharmony_ci 137b1994897Sopenharmony_ci { 138b1994897Sopenharmony_ci pandasm::Parser parser; 139b1994897Sopenharmony_ci auto res = parser.Parse(source); 140b1994897Sopenharmony_ci ASSERT_TRUE(res); 141b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname.GetFileName(), res.Value())); 142b1994897Sopenharmony_ci } 143b1994897Sopenharmony_ci 144b1994897Sopenharmony_ci { 145b1994897Sopenharmony_ci auto pandastdlib_path = GetPaocDirectory() + "/../pandastdlib/arkstdlib.abc"; 146b1994897Sopenharmony_ci auto res = os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_fname.GetFileName(), "--paoc-output", 147b1994897Sopenharmony_ci aot_fname.GetFileName(), "--paoc-location", location.c_str(), "--paoc-arch=x86_64", 148b1994897Sopenharmony_ci "--gc-type=epsilon", "--paoc-use-cha=false"); 149b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 150b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0) << "Aot compiler failed with code " << res.Value(); 151b1994897Sopenharmony_ci } 152b1994897Sopenharmony_ci 153b1994897Sopenharmony_ci AotManager aot_manager; 154b1994897Sopenharmony_ci { 155b1994897Sopenharmony_ci auto res = 156b1994897Sopenharmony_ci aot_manager.AddFile(aot_fname.GetFileName(), nullptr, static_cast<uint32_t>(mem::GCType::EPSILON_GC)); 157b1994897Sopenharmony_ci ASSERT_TRUE(res) << res.Error(); 158b1994897Sopenharmony_ci } 159b1994897Sopenharmony_ci 160b1994897Sopenharmony_ci auto aot_file = aot_manager.GetFile(aot_fname.GetFileName()); 161b1994897Sopenharmony_ci ASSERT_TRUE(aot_file); 162b1994897Sopenharmony_ci ASSERT_EQ(aot_file->GetFilesCount(), 1); 163b1994897Sopenharmony_ci ASSERT_TRUE(aot_file->FindPandaFile(panda_file_path)); 164b1994897Sopenharmony_ci} 165b1994897Sopenharmony_ci#endif // PANDA_COMPILER_TARGET_AARCH64 166b1994897Sopenharmony_ci 167b1994897Sopenharmony_ciTEST_F(AotTest, BuildAndLoad) 168b1994897Sopenharmony_ci{ 169b1994897Sopenharmony_ci if (RUNTIME_ARCH == Arch::AARCH32) { 170b1994897Sopenharmony_ci // TODO(msherstennikov): for some reason dlopen cannot open aot file in qemu-arm 171b1994897Sopenharmony_ci return; 172b1994897Sopenharmony_ci } 173b1994897Sopenharmony_ci uint32_t tid = os::thread::GetCurrentThreadId(); 174b1994897Sopenharmony_ci std::string tmpfile = helpers::string::Format("/tmp/tmpfile_%04x.pn", tid); 175b1994897Sopenharmony_ci static constexpr const char *tmpfile_pf = "test.pf"; 176b1994897Sopenharmony_ci static constexpr const char *cmdline = "cmdline"; 177b1994897Sopenharmony_ci static constexpr uint32_t method1_id = 42; 178b1994897Sopenharmony_ci static constexpr uint32_t method2_id = 43; 179b1994897Sopenharmony_ci const std::string class_name("Foo"); 180b1994897Sopenharmony_ci std::string method_name(class_name + "::method"); 181b1994897Sopenharmony_ci std::array<uint8_t, 4> x86_add = { 182b1994897Sopenharmony_ci 0x8d, 0x04, 0x37, // lea eax,[rdi+rdi*1] 183b1994897Sopenharmony_ci 0xc3 // ret 184b1994897Sopenharmony_ci }; 185b1994897Sopenharmony_ci 186b1994897Sopenharmony_ci AotBuilder aot_builder; 187b1994897Sopenharmony_ci aot_builder.SetArch(RUNTIME_ARCH); 188b1994897Sopenharmony_ci aot_builder.SetGcType(2); 189b1994897Sopenharmony_ci RuntimeInterfaceMock iruntime; 190b1994897Sopenharmony_ci aot_builder.SetRuntime(&iruntime); 191b1994897Sopenharmony_ci 192b1994897Sopenharmony_ci aot_builder.StartFile(tmpfile_pf, 0x12345678); 193b1994897Sopenharmony_ci 194b1994897Sopenharmony_ci auto thread = MTManagedThread::GetCurrent(); 195b1994897Sopenharmony_ci if (thread != nullptr) { 196b1994897Sopenharmony_ci thread->ManagedCodeBegin(); 197b1994897Sopenharmony_ci } 198b1994897Sopenharmony_ci auto runtime = Runtime::GetCurrent(); 199b1994897Sopenharmony_ci auto etx = runtime->GetClassLinker()->GetExtension(runtime->GetLanguageContext(runtime->GetRuntimeType())); 200b1994897Sopenharmony_ci auto klass = etx->CreateClass(reinterpret_cast<const uint8_t *>(class_name.data()), 0, 0, 201b1994897Sopenharmony_ci AlignUp(sizeof(Class), OBJECT_POINTER_SIZE)); 202b1994897Sopenharmony_ci if (thread != nullptr) { 203b1994897Sopenharmony_ci thread->ManagedCodeEnd(); 204b1994897Sopenharmony_ci } 205b1994897Sopenharmony_ci 206b1994897Sopenharmony_ci klass->SetFileId(panda_file::File::EntityId(13)); 207b1994897Sopenharmony_ci aot_builder.StartClass(*klass); 208b1994897Sopenharmony_ci 209b1994897Sopenharmony_ci Method method1(klass, nullptr, File::EntityId(method1_id), File::EntityId(), 0, 1, nullptr); 210b1994897Sopenharmony_ci { 211b1994897Sopenharmony_ci CodeInfoBuilder code_builder(RUNTIME_ARCH, GetAllocator()); 212b1994897Sopenharmony_ci ArenaVector<uint8_t> data(GetAllocator()->Adapter()); 213b1994897Sopenharmony_ci code_builder.Encode(&data); 214b1994897Sopenharmony_ci CompiledMethod compiled_method1(RUNTIME_ARCH, &method1); 215b1994897Sopenharmony_ci compiled_method1.SetCode(Span(reinterpret_cast<const uint8_t *>(method_name.data()), method_name.size() + 1)); 216b1994897Sopenharmony_ci compiled_method1.SetCodeInfo(Span(data).ToConst()); 217b1994897Sopenharmony_ci aot_builder.AddMethod(compiled_method1, 0); 218b1994897Sopenharmony_ci } 219b1994897Sopenharmony_ci 220b1994897Sopenharmony_ci Method method2(klass, nullptr, File::EntityId(method2_id), File::EntityId(), 0, 1, nullptr); 221b1994897Sopenharmony_ci { 222b1994897Sopenharmony_ci CodeInfoBuilder code_builder(RUNTIME_ARCH, GetAllocator()); 223b1994897Sopenharmony_ci ArenaVector<uint8_t> data(GetAllocator()->Adapter()); 224b1994897Sopenharmony_ci code_builder.Encode(&data); 225b1994897Sopenharmony_ci CompiledMethod compiled_method2(RUNTIME_ARCH, &method2); 226b1994897Sopenharmony_ci compiled_method2.SetCode(Span(reinterpret_cast<const uint8_t *>(x86_add.data()), x86_add.size())); 227b1994897Sopenharmony_ci compiled_method2.SetCodeInfo(Span(data).ToConst()); 228b1994897Sopenharmony_ci aot_builder.AddMethod(compiled_method2, 1); 229b1994897Sopenharmony_ci } 230b1994897Sopenharmony_ci 231b1994897Sopenharmony_ci aot_builder.EndClass(); 232b1994897Sopenharmony_ci uint32_t hash = GetHash32String(reinterpret_cast<const uint8_t *>(class_name.data())); 233b1994897Sopenharmony_ci aot_builder.InsertEntityPairHeader(hash, 13); 234b1994897Sopenharmony_ci aot_builder.InsertClassHashTableSize(1); 235b1994897Sopenharmony_ci aot_builder.EndFile(); 236b1994897Sopenharmony_ci 237b1994897Sopenharmony_ci aot_builder.Write(cmdline, tmpfile.c_str()); 238b1994897Sopenharmony_ci 239b1994897Sopenharmony_ci AotManager aot_manager; 240b1994897Sopenharmony_ci auto res = aot_manager.AddFile(tmpfile.c_str(), nullptr, static_cast<uint32_t>(mem::GCType::STW_GC)); 241b1994897Sopenharmony_ci ASSERT_TRUE(res) << res.Error(); 242b1994897Sopenharmony_ci 243b1994897Sopenharmony_ci auto aot_file = aot_manager.GetFile(tmpfile.c_str()); 244b1994897Sopenharmony_ci ASSERT_TRUE(aot_file); 245b1994897Sopenharmony_ci ASSERT_TRUE(strcmp(cmdline, aot_file->GetCommandLine()) == 0U); 246b1994897Sopenharmony_ci ASSERT_TRUE(strcmp(tmpfile.c_str(), aot_file->GetFileName()) == 0U); 247b1994897Sopenharmony_ci ASSERT_EQ(aot_file->GetFilesCount(), 1U); 248b1994897Sopenharmony_ci 249b1994897Sopenharmony_ci auto pfile = aot_manager.FindPandaFile(tmpfile_pf); 250b1994897Sopenharmony_ci ASSERT_NE(pfile, nullptr); 251b1994897Sopenharmony_ci auto cls = pfile->GetClass(13); 252b1994897Sopenharmony_ci ASSERT_TRUE(cls.IsValid()); 253b1994897Sopenharmony_ci 254b1994897Sopenharmony_ci { 255b1994897Sopenharmony_ci auto code = cls.FindMethodCodeEntry(0); 256b1994897Sopenharmony_ci ASSERT_FALSE(code == nullptr); 257b1994897Sopenharmony_ci ASSERT_EQ(method_name, reinterpret_cast<const char *>(code)); 258b1994897Sopenharmony_ci } 259b1994897Sopenharmony_ci 260b1994897Sopenharmony_ci { 261b1994897Sopenharmony_ci auto code = cls.FindMethodCodeEntry(1); 262b1994897Sopenharmony_ci ASSERT_FALSE(code == nullptr); 263b1994897Sopenharmony_ci ASSERT_EQ(std::memcmp(x86_add.data(), code, x86_add.size()), 0); 264b1994897Sopenharmony_ci#ifdef PANDA_TARGET_AMD64 265b1994897Sopenharmony_ci auto func_add = (int (*)(int, int))code; 266b1994897Sopenharmony_ci ASSERT_EQ(func_add(2, 3), 5); 267b1994897Sopenharmony_ci#endif 268b1994897Sopenharmony_ci } 269b1994897Sopenharmony_ci} 270b1994897Sopenharmony_ci 271b1994897Sopenharmony_ciTEST_F(AotTest, PaocSpecifyMethods) 272b1994897Sopenharmony_ci{ 273b1994897Sopenharmony_ci#ifndef PANDA_EVENTS_ENABLED 274b1994897Sopenharmony_ci GTEST_SKIP(); 275b1994897Sopenharmony_ci#endif 276b1994897Sopenharmony_ci 277b1994897Sopenharmony_ci // Test basic functionality only in host mode. 278b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 279b1994897Sopenharmony_ci return; 280b1994897Sopenharmony_ci } 281b1994897Sopenharmony_ci TmpFile panda_fname("test.pf"); 282b1994897Sopenharmony_ci TmpFile paoc_output_name("events-out.csv"); 283b1994897Sopenharmony_ci 284b1994897Sopenharmony_ci static const std::string location = "/data/local/tmp"; 285b1994897Sopenharmony_ci static const std::string panda_file_path = location + "/" + panda_fname.GetFileName(); 286b1994897Sopenharmony_ci 287b1994897Sopenharmony_ci auto source = R"( 288b1994897Sopenharmony_ci .record A {} 289b1994897Sopenharmony_ci .record B {} 290b1994897Sopenharmony_ci 291b1994897Sopenharmony_ci .function i32 A.f1() { 292b1994897Sopenharmony_ci ldai 10 293b1994897Sopenharmony_ci return 294b1994897Sopenharmony_ci } 295b1994897Sopenharmony_ci 296b1994897Sopenharmony_ci .function i32 B.f1() { 297b1994897Sopenharmony_ci ldai 20 298b1994897Sopenharmony_ci return 299b1994897Sopenharmony_ci } 300b1994897Sopenharmony_ci 301b1994897Sopenharmony_ci .function i32 A.f2() { 302b1994897Sopenharmony_ci ldai 10 303b1994897Sopenharmony_ci return 304b1994897Sopenharmony_ci } 305b1994897Sopenharmony_ci 306b1994897Sopenharmony_ci .function i32 B.f2() { 307b1994897Sopenharmony_ci ldai 20 308b1994897Sopenharmony_ci return 309b1994897Sopenharmony_ci } 310b1994897Sopenharmony_ci 311b1994897Sopenharmony_ci .function i32 main() { 312b1994897Sopenharmony_ci ldai 0 313b1994897Sopenharmony_ci return 314b1994897Sopenharmony_ci } 315b1994897Sopenharmony_ci )"; 316b1994897Sopenharmony_ci 317b1994897Sopenharmony_ci { 318b1994897Sopenharmony_ci pandasm::Parser parser; 319b1994897Sopenharmony_ci auto res = parser.Parse(source); 320b1994897Sopenharmony_ci ASSERT_TRUE(res); 321b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname.GetFileName(), res.Value())); 322b1994897Sopenharmony_ci } 323b1994897Sopenharmony_ci 324b1994897Sopenharmony_ci { 325b1994897Sopenharmony_ci // paoc will try compiling all the methods from the panda-file that matches `--compiler-regex` 326b1994897Sopenharmony_ci auto res = 327b1994897Sopenharmony_ci os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_fname.GetFileName(), 328b1994897Sopenharmony_ci "--compiler-regex", "B::f1", 329b1994897Sopenharmony_ci "--paoc-mode=jit", "--events-output=csv", 330b1994897Sopenharmony_ci "--events-file", paoc_output_name.GetFileName()); 331b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 332b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0); 333b1994897Sopenharmony_ci 334b1994897Sopenharmony_ci std::ifstream infile(paoc_output_name.GetFileName()); 335b1994897Sopenharmony_ci std::regex rgx("Compilation,B::f1.*,COMPILED"); 336b1994897Sopenharmony_ci for (std::string line; std::getline(infile, line);) { 337b1994897Sopenharmony_ci if (line.rfind("Compilation", 0) == 0) { 338b1994897Sopenharmony_ci ASSERT_TRUE(std::regex_match(line, rgx)); 339b1994897Sopenharmony_ci } 340b1994897Sopenharmony_ci } 341b1994897Sopenharmony_ci } 342b1994897Sopenharmony_ci} 343b1994897Sopenharmony_ci 344b1994897Sopenharmony_ciTEST_F(AotTest, PaocMultipleFiles) 345b1994897Sopenharmony_ci{ 346b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 347b1994897Sopenharmony_ci GTEST_SKIP(); 348b1994897Sopenharmony_ci } 349b1994897Sopenharmony_ci 350b1994897Sopenharmony_ci TmpFile aot_fname("./test.an"); 351b1994897Sopenharmony_ci TmpFile panda_fname1("test1.pf"); 352b1994897Sopenharmony_ci TmpFile panda_fname2("test2.pf"); 353b1994897Sopenharmony_ci 354b1994897Sopenharmony_ci { 355b1994897Sopenharmony_ci auto source = R"( 356b1994897Sopenharmony_ci .function f64 main() { 357b1994897Sopenharmony_ci fldai.64 3.1415926 358b1994897Sopenharmony_ci return.64 359b1994897Sopenharmony_ci } 360b1994897Sopenharmony_ci )"; 361b1994897Sopenharmony_ci 362b1994897Sopenharmony_ci pandasm::Parser parser; 363b1994897Sopenharmony_ci auto res = parser.Parse(source); 364b1994897Sopenharmony_ci ASSERT_TRUE(res); 365b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname1.GetFileName(), res.Value())); 366b1994897Sopenharmony_ci } 367b1994897Sopenharmony_ci 368b1994897Sopenharmony_ci { 369b1994897Sopenharmony_ci auto source = R"( 370b1994897Sopenharmony_ci .record MyMath { 371b1994897Sopenharmony_ci } 372b1994897Sopenharmony_ci 373b1994897Sopenharmony_ci .function f64 MyMath.getPi() <static> { 374b1994897Sopenharmony_ci fldai.64 3.1415926 375b1994897Sopenharmony_ci return.64 376b1994897Sopenharmony_ci } 377b1994897Sopenharmony_ci )"; 378b1994897Sopenharmony_ci 379b1994897Sopenharmony_ci pandasm::Parser parser; 380b1994897Sopenharmony_ci auto res = parser.Parse(source); 381b1994897Sopenharmony_ci ASSERT_TRUE(res); 382b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname2.GetFileName(), res.Value())); 383b1994897Sopenharmony_ci } 384b1994897Sopenharmony_ci 385b1994897Sopenharmony_ci { 386b1994897Sopenharmony_ci std::stringstream panda_files; 387b1994897Sopenharmony_ci panda_files << panda_fname1.GetFileName() << ',' << panda_fname2.GetFileName(); 388b1994897Sopenharmony_ci auto res = os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_files.str().c_str(), "--paoc-output", 389b1994897Sopenharmony_ci aot_fname.GetFileName(), "--gc-type=epsilon", "--paoc-use-cha=false"); 390b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 391b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0); 392b1994897Sopenharmony_ci } 393b1994897Sopenharmony_ci 394b1994897Sopenharmony_ci { 395b1994897Sopenharmony_ci AotManager aot_manager; 396b1994897Sopenharmony_ci auto res = 397b1994897Sopenharmony_ci aot_manager.AddFile(aot_fname.GetFileName(), nullptr, static_cast<uint32_t>(mem::GCType::EPSILON_GC)); 398b1994897Sopenharmony_ci ASSERT_TRUE(res) << res.Error(); 399b1994897Sopenharmony_ci 400b1994897Sopenharmony_ci auto aot_file = aot_manager.GetFile(aot_fname.GetFileName()); 401b1994897Sopenharmony_ci ASSERT_TRUE(aot_file); 402b1994897Sopenharmony_ci ASSERT_EQ(aot_file->GetFilesCount(), 2U); 403b1994897Sopenharmony_ci } 404b1994897Sopenharmony_ci RunAotdump(aot_fname.GetFileName()); 405b1994897Sopenharmony_ci} 406b1994897Sopenharmony_ci 407b1994897Sopenharmony_ciTEST_F(AotTest, PaocGcType) 408b1994897Sopenharmony_ci{ 409b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 410b1994897Sopenharmony_ci GTEST_SKIP(); 411b1994897Sopenharmony_ci } 412b1994897Sopenharmony_ci 413b1994897Sopenharmony_ci TmpFile aot_fname("./test.pn"); 414b1994897Sopenharmony_ci TmpFile panda_fname("test.pf"); 415b1994897Sopenharmony_ci 416b1994897Sopenharmony_ci { 417b1994897Sopenharmony_ci auto source = R"( 418b1994897Sopenharmony_ci .function f64 main() { 419b1994897Sopenharmony_ci fldai.64 3.1415926 420b1994897Sopenharmony_ci return.64 421b1994897Sopenharmony_ci } 422b1994897Sopenharmony_ci )"; 423b1994897Sopenharmony_ci 424b1994897Sopenharmony_ci pandasm::Parser parser; 425b1994897Sopenharmony_ci auto res = parser.Parse(source); 426b1994897Sopenharmony_ci ASSERT_TRUE(res); 427b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname.GetFileName(), res.Value())); 428b1994897Sopenharmony_ci } 429b1994897Sopenharmony_ci 430b1994897Sopenharmony_ci { 431b1994897Sopenharmony_ci auto res = os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_fname.GetFileName(), "--paoc-output", 432b1994897Sopenharmony_ci aot_fname.GetFileName(), "--gc-type=epsilon", "--paoc-use-cha=false"); 433b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 434b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0); 435b1994897Sopenharmony_ci } 436b1994897Sopenharmony_ci 437b1994897Sopenharmony_ci { 438b1994897Sopenharmony_ci // Wrong gc-type 439b1994897Sopenharmony_ci AotManager aot_manager; 440b1994897Sopenharmony_ci auto res = aot_manager.AddFile(aot_fname.GetFileName(), nullptr, static_cast<uint32_t>(mem::GCType::STW_GC)); 441b1994897Sopenharmony_ci ASSERT_FALSE(res) << res.Error(); 442b1994897Sopenharmony_ci std::string expected_string = "Wrong AotHeader gc-type: epsilon vs stw"; 443b1994897Sopenharmony_ci ASSERT_NE(res.Error().find(expected_string), std::string::npos); 444b1994897Sopenharmony_ci } 445b1994897Sopenharmony_ci 446b1994897Sopenharmony_ci { 447b1994897Sopenharmony_ci AotManager aot_manager; 448b1994897Sopenharmony_ci auto res = 449b1994897Sopenharmony_ci aot_manager.AddFile(aot_fname.GetFileName(), nullptr, static_cast<uint32_t>(mem::GCType::EPSILON_GC)); 450b1994897Sopenharmony_ci ASSERT_TRUE(res) << res.Error(); 451b1994897Sopenharmony_ci 452b1994897Sopenharmony_ci auto aot_file = aot_manager.GetFile(aot_fname.GetFileName()); 453b1994897Sopenharmony_ci ASSERT_TRUE(aot_file); 454b1994897Sopenharmony_ci ASSERT_EQ(aot_file->GetFilesCount(), 1U); 455b1994897Sopenharmony_ci } 456b1994897Sopenharmony_ci RunAotdump(aot_fname.GetFileName()); 457b1994897Sopenharmony_ci} 458b1994897Sopenharmony_ci 459b1994897Sopenharmony_ciTEST_F(AotTest, FileManagerLoadAbc) 460b1994897Sopenharmony_ci{ 461b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 462b1994897Sopenharmony_ci GTEST_SKIP(); 463b1994897Sopenharmony_ci } 464b1994897Sopenharmony_ci 465b1994897Sopenharmony_ci TmpFile aot_fname("./test.an"); 466b1994897Sopenharmony_ci TmpFile panda_fname("./test.pf"); 467b1994897Sopenharmony_ci 468b1994897Sopenharmony_ci { 469b1994897Sopenharmony_ci auto source = R"( 470b1994897Sopenharmony_ci .function f64 main() { 471b1994897Sopenharmony_ci fldai.64 3.1415926 472b1994897Sopenharmony_ci return.64 473b1994897Sopenharmony_ci } 474b1994897Sopenharmony_ci )"; 475b1994897Sopenharmony_ci 476b1994897Sopenharmony_ci pandasm::Parser parser; 477b1994897Sopenharmony_ci auto res = parser.Parse(source); 478b1994897Sopenharmony_ci ASSERT_TRUE(res); 479b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname.GetFileName(), res.Value())); 480b1994897Sopenharmony_ci } 481b1994897Sopenharmony_ci 482b1994897Sopenharmony_ci { 483b1994897Sopenharmony_ci auto runtime = Runtime::GetCurrent(); 484b1994897Sopenharmony_ci auto gc_type_id = static_cast<uint32_t>( 485b1994897Sopenharmony_ci Runtime::GetGCType(runtime->GetOptions(), plugins::RuntimeTypeToLang(runtime->GetRuntimeType()))); 486b1994897Sopenharmony_ci auto gc_type_name = "--gc-type=epsilon"; 487b1994897Sopenharmony_ci if (gc_type_id == 2) { 488b1994897Sopenharmony_ci gc_type_name = "--gc-type=stw"; 489b1994897Sopenharmony_ci } else if (gc_type_id == 4) { 490b1994897Sopenharmony_ci gc_type_name = "--gc-type=gen-gc"; 491b1994897Sopenharmony_ci } else { 492b1994897Sopenharmony_ci ASSERT_EQ(gc_type_id, 1) << "Invalid GC type\n"; 493b1994897Sopenharmony_ci } 494b1994897Sopenharmony_ci auto res = os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_fname.GetFileName(), "--paoc-output", 495b1994897Sopenharmony_ci aot_fname.GetFileName(), gc_type_name, "--paoc-use-cha=false"); 496b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 497b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0); 498b1994897Sopenharmony_ci } 499b1994897Sopenharmony_ci 500b1994897Sopenharmony_ci { 501b1994897Sopenharmony_ci auto res = FileManager::LoadAbcFile(panda_fname.GetFileName(), panda_file::File::READ_ONLY); 502b1994897Sopenharmony_ci ASSERT_TRUE(res); 503b1994897Sopenharmony_ci auto aot_manager = Runtime::GetCurrent()->GetClassLinker()->GetAotManager(); 504b1994897Sopenharmony_ci auto aot_file = aot_manager->GetFile(aot_fname.GetFileName()); 505b1994897Sopenharmony_ci ASSERT_TRUE(aot_file); 506b1994897Sopenharmony_ci ASSERT_EQ(aot_file->GetFilesCount(), 1); 507b1994897Sopenharmony_ci } 508b1994897Sopenharmony_ci RunAotdump(aot_fname.GetFileName()); 509b1994897Sopenharmony_ci} 510b1994897Sopenharmony_ci 511b1994897Sopenharmony_ciTEST_F(AotTest, FileManagerLoadAn) 512b1994897Sopenharmony_ci{ 513b1994897Sopenharmony_ci if (RUNTIME_ARCH == Arch::AARCH32) { 514b1994897Sopenharmony_ci // TODO(msherstennikov): for some reason dlopen cannot open aot file in qemu-arm 515b1994897Sopenharmony_ci return; 516b1994897Sopenharmony_ci } 517b1994897Sopenharmony_ci uint32_t tid = os::thread::GetCurrentThreadId(); 518b1994897Sopenharmony_ci std::string tmpfile = helpers::string::Format("test.an", tid); 519b1994897Sopenharmony_ci static constexpr const char *tmpfile_pf = "test.pf"; 520b1994897Sopenharmony_ci static constexpr const char *cmdline = "cmdline"; 521b1994897Sopenharmony_ci static constexpr uint32_t method1_id = 42; 522b1994897Sopenharmony_ci static constexpr uint32_t method2_id = 43; 523b1994897Sopenharmony_ci const std::string class_name("Foo"); 524b1994897Sopenharmony_ci std::string method_name(class_name + "::method"); 525b1994897Sopenharmony_ci std::array<uint8_t, 4> x86_add = { 526b1994897Sopenharmony_ci 0x8d, 0x04, 0x37, // lea eax,[rdi+rdi*1] 527b1994897Sopenharmony_ci 0xc3 // ret 528b1994897Sopenharmony_ci }; 529b1994897Sopenharmony_ci 530b1994897Sopenharmony_ci AotBuilder aot_builder; 531b1994897Sopenharmony_ci aot_builder.SetArch(RUNTIME_ARCH); 532b1994897Sopenharmony_ci RuntimeInterfaceMock iruntime; 533b1994897Sopenharmony_ci aot_builder.SetRuntime(&iruntime); 534b1994897Sopenharmony_ci auto runtime = Runtime::GetCurrent(); 535b1994897Sopenharmony_ci auto gc_type = Runtime::GetGCType(runtime->GetOptions(), plugins::RuntimeTypeToLang(runtime->GetRuntimeType())); 536b1994897Sopenharmony_ci aot_builder.SetGcType(static_cast<uint32_t>(gc_type)); 537b1994897Sopenharmony_ci 538b1994897Sopenharmony_ci aot_builder.StartFile(tmpfile_pf, 0x12345678); 539b1994897Sopenharmony_ci 540b1994897Sopenharmony_ci auto thread = MTManagedThread::GetCurrent(); 541b1994897Sopenharmony_ci if (thread != nullptr) { 542b1994897Sopenharmony_ci thread->ManagedCodeBegin(); 543b1994897Sopenharmony_ci } 544b1994897Sopenharmony_ci auto etx = runtime->GetClassLinker()->GetExtension(runtime->GetLanguageContext(runtime->GetRuntimeType())); 545b1994897Sopenharmony_ci auto klass = etx->CreateClass(reinterpret_cast<const uint8_t *>(class_name.data()), 0, 0, 546b1994897Sopenharmony_ci AlignUp(sizeof(Class), OBJECT_POINTER_SIZE)); 547b1994897Sopenharmony_ci if (thread != nullptr) { 548b1994897Sopenharmony_ci thread->ManagedCodeEnd(); 549b1994897Sopenharmony_ci } 550b1994897Sopenharmony_ci 551b1994897Sopenharmony_ci klass->SetFileId(panda_file::File::EntityId(13)); 552b1994897Sopenharmony_ci aot_builder.StartClass(*klass); 553b1994897Sopenharmony_ci 554b1994897Sopenharmony_ci Method method1(klass, nullptr, File::EntityId(method1_id), File::EntityId(), 0, 1, nullptr); 555b1994897Sopenharmony_ci { 556b1994897Sopenharmony_ci CodeInfoBuilder code_builder(RUNTIME_ARCH, GetAllocator()); 557b1994897Sopenharmony_ci ArenaVector<uint8_t> data(GetAllocator()->Adapter()); 558b1994897Sopenharmony_ci code_builder.Encode(&data); 559b1994897Sopenharmony_ci CompiledMethod compiled_method1(RUNTIME_ARCH, &method1); 560b1994897Sopenharmony_ci compiled_method1.SetCode(Span(reinterpret_cast<const uint8_t *>(method_name.data()), method_name.size() + 1)); 561b1994897Sopenharmony_ci compiled_method1.SetCodeInfo(Span(data).ToConst()); 562b1994897Sopenharmony_ci aot_builder.AddMethod(compiled_method1, 0); 563b1994897Sopenharmony_ci } 564b1994897Sopenharmony_ci 565b1994897Sopenharmony_ci Method method2(klass, nullptr, File::EntityId(method2_id), File::EntityId(), 0, 1, nullptr); 566b1994897Sopenharmony_ci { 567b1994897Sopenharmony_ci CodeInfoBuilder code_builder(RUNTIME_ARCH, GetAllocator()); 568b1994897Sopenharmony_ci ArenaVector<uint8_t> data(GetAllocator()->Adapter()); 569b1994897Sopenharmony_ci code_builder.Encode(&data); 570b1994897Sopenharmony_ci CompiledMethod compiled_method2(RUNTIME_ARCH, &method2); 571b1994897Sopenharmony_ci compiled_method2.SetCode(Span(reinterpret_cast<const uint8_t *>(x86_add.data()), x86_add.size())); 572b1994897Sopenharmony_ci compiled_method2.SetCodeInfo(Span(data).ToConst()); 573b1994897Sopenharmony_ci aot_builder.AddMethod(compiled_method2, 1); 574b1994897Sopenharmony_ci } 575b1994897Sopenharmony_ci 576b1994897Sopenharmony_ci aot_builder.EndClass(); 577b1994897Sopenharmony_ci uint32_t hash = GetHash32String(reinterpret_cast<const uint8_t *>(class_name.data())); 578b1994897Sopenharmony_ci aot_builder.InsertEntityPairHeader(hash, 13); 579b1994897Sopenharmony_ci aot_builder.InsertClassHashTableSize(1); 580b1994897Sopenharmony_ci aot_builder.EndFile(); 581b1994897Sopenharmony_ci 582b1994897Sopenharmony_ci aot_builder.Write(cmdline, tmpfile.c_str()); 583b1994897Sopenharmony_ci { 584b1994897Sopenharmony_ci auto res = FileManager::LoadAnFile(tmpfile.c_str()); 585b1994897Sopenharmony_ci ASSERT_TRUE(res) << "Fail to load an file"; 586b1994897Sopenharmony_ci } 587b1994897Sopenharmony_ci 588b1994897Sopenharmony_ci auto aot_manager = Runtime::GetCurrent()->GetClassLinker()->GetAotManager(); 589b1994897Sopenharmony_ci auto aot_file = aot_manager->GetFile(tmpfile.c_str()); 590b1994897Sopenharmony_ci ASSERT_TRUE(aot_file); 591b1994897Sopenharmony_ci ASSERT_TRUE(strcmp(cmdline, aot_file->GetCommandLine()) == 0U); 592b1994897Sopenharmony_ci ASSERT_TRUE(strcmp(tmpfile.c_str(), aot_file->GetFileName()) == 0U); 593b1994897Sopenharmony_ci ASSERT_EQ(aot_file->GetFilesCount(), 1U); 594b1994897Sopenharmony_ci 595b1994897Sopenharmony_ci auto pfile = aot_manager->FindPandaFile(tmpfile_pf); 596b1994897Sopenharmony_ci ASSERT_NE(pfile, nullptr); 597b1994897Sopenharmony_ci auto cls = pfile->GetClass(13); 598b1994897Sopenharmony_ci ASSERT_TRUE(cls.IsValid()); 599b1994897Sopenharmony_ci 600b1994897Sopenharmony_ci { 601b1994897Sopenharmony_ci auto code = cls.FindMethodCodeEntry(0); 602b1994897Sopenharmony_ci ASSERT_FALSE(code == nullptr); 603b1994897Sopenharmony_ci ASSERT_EQ(method_name, reinterpret_cast<const char *>(code)); 604b1994897Sopenharmony_ci } 605b1994897Sopenharmony_ci 606b1994897Sopenharmony_ci { 607b1994897Sopenharmony_ci auto code = cls.FindMethodCodeEntry(1); 608b1994897Sopenharmony_ci ASSERT_FALSE(code == nullptr); 609b1994897Sopenharmony_ci ASSERT_EQ(std::memcmp(x86_add.data(), code, x86_add.size()), 0); 610b1994897Sopenharmony_ci#ifdef PANDA_TARGET_AMD64 611b1994897Sopenharmony_ci auto func_add = (int (*)(int, int))code; 612b1994897Sopenharmony_ci ASSERT_EQ(func_add(2, 3), 5); 613b1994897Sopenharmony_ci#endif 614b1994897Sopenharmony_ci } 615b1994897Sopenharmony_ci} 616b1994897Sopenharmony_ci 617b1994897Sopenharmony_ciTEST_F(AotTest, PaocClusters) 618b1994897Sopenharmony_ci{ 619b1994897Sopenharmony_ci // Test basic functionality only in host mode. 620b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 621b1994897Sopenharmony_ci return; 622b1994897Sopenharmony_ci } 623b1994897Sopenharmony_ci 624b1994897Sopenharmony_ci TmpFile paoc_clusters("clusters.json"); 625b1994897Sopenharmony_ci std::ofstream(paoc_clusters.GetFileName()) << 626b1994897Sopenharmony_ci R"( 627b1994897Sopenharmony_ci { 628b1994897Sopenharmony_ci "clusters_map" : 629b1994897Sopenharmony_ci { 630b1994897Sopenharmony_ci "A::count" : ["unroll_enable"], 631b1994897Sopenharmony_ci "B::count2" : ["unroll_disable"], 632b1994897Sopenharmony_ci "_GLOBAL::main" : ["inline_disable", 1] 633b1994897Sopenharmony_ci }, 634b1994897Sopenharmony_ci 635b1994897Sopenharmony_ci "compiler_options" : 636b1994897Sopenharmony_ci { 637b1994897Sopenharmony_ci "unroll_disable" : 638b1994897Sopenharmony_ci { 639b1994897Sopenharmony_ci "compiler-loop-unroll" : "false" 640b1994897Sopenharmony_ci }, 641b1994897Sopenharmony_ci 642b1994897Sopenharmony_ci "unroll_enable" : 643b1994897Sopenharmony_ci { 644b1994897Sopenharmony_ci "compiler-loop-unroll" : "true", 645b1994897Sopenharmony_ci "compiler-loop-unroll-factor" : 42, 646b1994897Sopenharmony_ci "compiler-loop-unroll-inst-limit" : 850 647b1994897Sopenharmony_ci }, 648b1994897Sopenharmony_ci 649b1994897Sopenharmony_ci "inline_disable" : 650b1994897Sopenharmony_ci { 651b1994897Sopenharmony_ci "compiler-inlining" : "false" 652b1994897Sopenharmony_ci } 653b1994897Sopenharmony_ci } 654b1994897Sopenharmony_ci } 655b1994897Sopenharmony_ci )"; 656b1994897Sopenharmony_ci 657b1994897Sopenharmony_ci TmpFile panda_fname("test.pf"); 658b1994897Sopenharmony_ci auto source = R"( 659b1994897Sopenharmony_ci .record A {} 660b1994897Sopenharmony_ci .record B {} 661b1994897Sopenharmony_ci 662b1994897Sopenharmony_ci .function i32 A.count() <static> { 663b1994897Sopenharmony_ci movi v1, 5 664b1994897Sopenharmony_ci ldai 0 665b1994897Sopenharmony_ci main_loop: 666b1994897Sopenharmony_ci jeq v1, main_ret 667b1994897Sopenharmony_ci addi 1 668b1994897Sopenharmony_ci jmp main_loop 669b1994897Sopenharmony_ci main_ret: 670b1994897Sopenharmony_ci return 671b1994897Sopenharmony_ci } 672b1994897Sopenharmony_ci 673b1994897Sopenharmony_ci .function i32 B.count() <static> { 674b1994897Sopenharmony_ci movi v1, 5 675b1994897Sopenharmony_ci ldai 0 676b1994897Sopenharmony_ci main_loop: 677b1994897Sopenharmony_ci jeq v1, main_ret 678b1994897Sopenharmony_ci addi 1 679b1994897Sopenharmony_ci jmp main_loop 680b1994897Sopenharmony_ci main_ret: 681b1994897Sopenharmony_ci return 682b1994897Sopenharmony_ci } 683b1994897Sopenharmony_ci 684b1994897Sopenharmony_ci .function i32 B.count2() <static> { 685b1994897Sopenharmony_ci movi v1, 5 686b1994897Sopenharmony_ci ldai 0 687b1994897Sopenharmony_ci main_loop: 688b1994897Sopenharmony_ci jeq v1, main_ret 689b1994897Sopenharmony_ci addi 1 690b1994897Sopenharmony_ci jmp main_loop 691b1994897Sopenharmony_ci main_ret: 692b1994897Sopenharmony_ci return 693b1994897Sopenharmony_ci } 694b1994897Sopenharmony_ci 695b1994897Sopenharmony_ci .function i32 main() { 696b1994897Sopenharmony_ci call.short A.count 697b1994897Sopenharmony_ci sta v0 698b1994897Sopenharmony_ci call.short B.count 699b1994897Sopenharmony_ci add2 v0 700b1994897Sopenharmony_ci call.short B.count2 701b1994897Sopenharmony_ci add2 v0 702b1994897Sopenharmony_ci return 703b1994897Sopenharmony_ci } 704b1994897Sopenharmony_ci )"; 705b1994897Sopenharmony_ci 706b1994897Sopenharmony_ci { 707b1994897Sopenharmony_ci pandasm::Parser parser; 708b1994897Sopenharmony_ci auto res = parser.Parse(source); 709b1994897Sopenharmony_ci ASSERT_TRUE(res); 710b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname.GetFileName(), res.Value())); 711b1994897Sopenharmony_ci } 712b1994897Sopenharmony_ci 713b1994897Sopenharmony_ci { 714b1994897Sopenharmony_ci TmpFile compiler_events("events.csv"); 715b1994897Sopenharmony_ci auto res = 716b1994897Sopenharmony_ci os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_fname.GetFileName(), "--paoc-clusters", 717b1994897Sopenharmony_ci paoc_clusters.GetFileName(), "--compiler-loop-unroll-factor=7", 718b1994897Sopenharmony_ci "--compiler-enable-events=true", "--compiler-events-path", compiler_events.GetFileName()); 719b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 720b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0); 721b1994897Sopenharmony_ci 722b1994897Sopenharmony_ci bool first_found = false; 723b1994897Sopenharmony_ci bool second_found = false; 724b1994897Sopenharmony_ci std::ifstream events_file(compiler_events.GetFileName()); 725b1994897Sopenharmony_ci 726b1994897Sopenharmony_ci std::regex rgx_unroll_applied_cluster("A::count,loop-unroll,.*,unroll_factor:42,.*"); 727b1994897Sopenharmony_ci std::regex rgx_unroll_restored_default("B::count,loop-unroll,.*,unroll_factor:7,.*"); 728b1994897Sopenharmony_ci 729b1994897Sopenharmony_ci for (std::string line; std::getline(events_file, line);) { 730b1994897Sopenharmony_ci if (line.rfind("loop-unroll") != std::string::npos) { 731b1994897Sopenharmony_ci if (!first_found) { 732b1994897Sopenharmony_ci // Check that the cluster is applied: 733b1994897Sopenharmony_ci ASSERT_TRUE(std::regex_match(line, rgx_unroll_applied_cluster)); 734b1994897Sopenharmony_ci first_found = true; 735b1994897Sopenharmony_ci continue; 736b1994897Sopenharmony_ci } 737b1994897Sopenharmony_ci ASSERT_FALSE(second_found); 738b1994897Sopenharmony_ci // Check that the option is restored: 739b1994897Sopenharmony_ci ASSERT_TRUE(std::regex_match(line, rgx_unroll_restored_default)); 740b1994897Sopenharmony_ci second_found = true; 741b1994897Sopenharmony_ci } 742b1994897Sopenharmony_ci } 743b1994897Sopenharmony_ci ASSERT_TRUE(first_found && second_found); 744b1994897Sopenharmony_ci } 745b1994897Sopenharmony_ci} 746b1994897Sopenharmony_ci 747b1994897Sopenharmony_ciTEST_F(AotTest, PandaFiles) 748b1994897Sopenharmony_ci{ 749b1994897Sopenharmony_ci#ifndef PANDA_EVENTS_ENABLED 750b1994897Sopenharmony_ci GTEST_SKIP(); 751b1994897Sopenharmony_ci#endif 752b1994897Sopenharmony_ci 753b1994897Sopenharmony_ci if (RUNTIME_ARCH != Arch::X86_64) { 754b1994897Sopenharmony_ci GTEST_SKIP(); 755b1994897Sopenharmony_ci } 756b1994897Sopenharmony_ci 757b1994897Sopenharmony_ci TmpFile aot_fname("./test.an"); 758b1994897Sopenharmony_ci TmpFile panda_fname1("test1.pf"); 759b1994897Sopenharmony_ci TmpFile panda_fname2("test2.pf"); 760b1994897Sopenharmony_ci TmpFile paoc_output_name("events-out.csv"); 761b1994897Sopenharmony_ci 762b1994897Sopenharmony_ci { 763b1994897Sopenharmony_ci auto source = R"( 764b1994897Sopenharmony_ci .record Z {} 765b1994897Sopenharmony_ci .function i32 Z.zoo() <static> { 766b1994897Sopenharmony_ci ldai 45 767b1994897Sopenharmony_ci return 768b1994897Sopenharmony_ci } 769b1994897Sopenharmony_ci )"; 770b1994897Sopenharmony_ci 771b1994897Sopenharmony_ci pandasm::Parser parser; 772b1994897Sopenharmony_ci auto res = parser.Parse(source); 773b1994897Sopenharmony_ci ASSERT_TRUE(res); 774b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname1.GetFileName(), res.Value())); 775b1994897Sopenharmony_ci } 776b1994897Sopenharmony_ci 777b1994897Sopenharmony_ci { 778b1994897Sopenharmony_ci auto source = R"( 779b1994897Sopenharmony_ci .record Z <external> 780b1994897Sopenharmony_ci .function i32 Z.zoo() <external, static> 781b1994897Sopenharmony_ci .record X {} 782b1994897Sopenharmony_ci .function i32 X.main() { 783b1994897Sopenharmony_ci call.short Z.zoo 784b1994897Sopenharmony_ci return 785b1994897Sopenharmony_ci } 786b1994897Sopenharmony_ci )"; 787b1994897Sopenharmony_ci 788b1994897Sopenharmony_ci pandasm::Parser parser; 789b1994897Sopenharmony_ci auto res = parser.Parse(source); 790b1994897Sopenharmony_ci ASSERT_TRUE(res); 791b1994897Sopenharmony_ci ASSERT_TRUE(pandasm::AsmEmitter::Emit(panda_fname2.GetFileName(), res.Value())); 792b1994897Sopenharmony_ci } 793b1994897Sopenharmony_ci 794b1994897Sopenharmony_ci { 795b1994897Sopenharmony_ci std::stringstream panda_files; 796b1994897Sopenharmony_ci panda_files << panda_fname1.GetFileName() << ',' << panda_fname2.GetFileName(); 797b1994897Sopenharmony_ci auto res = os::exec::Exec(paoc_path_.c_str(), "--paoc-panda-files", panda_fname2.GetFileName(), "--panda-files", 798b1994897Sopenharmony_ci panda_fname1.GetFileName(), "--events-output=csv", "--events-file", 799b1994897Sopenharmony_ci paoc_output_name.GetFileName()); 800b1994897Sopenharmony_ci ASSERT_TRUE(res) << "paoc failed with error: " << res.Error().ToString(); 801b1994897Sopenharmony_ci ASSERT_EQ(res.Value(), 0); 802b1994897Sopenharmony_ci 803b1994897Sopenharmony_ci std::ifstream infile(paoc_output_name.GetFileName()); 804b1994897Sopenharmony_ci // Inlining attempt proofs that Z::zoo was available to inline 805b1994897Sopenharmony_ci std::regex rgx("Inline,.*Z::zoo.*"); 806b1994897Sopenharmony_ci bool inline_attempt = false; 807b1994897Sopenharmony_ci for (std::string line; std::getline(infile, line);) { 808b1994897Sopenharmony_ci inline_attempt |= std::regex_match(line, rgx); 809b1994897Sopenharmony_ci } 810b1994897Sopenharmony_ci ASSERT_TRUE(inline_attempt); 811b1994897Sopenharmony_ci } 812b1994897Sopenharmony_ci} 813b1994897Sopenharmony_ci 814b1994897Sopenharmony_ci} // namespace panda::compiler 815