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#include <cstring> 17#include <gtest/gtest.h> 18#include <iomanip> 19#include <iostream> 20#include <memory> 21#include <sstream> 22#include <string> 23 24#include "bytecode_optimizer/reg_acc_alloc.h" 25#include "bytecode_optimizer/reg_encoder.h" 26#include "dump.cpp" 27#include "graph.h" 28#include "graph_test.h" 29#include "inst.h" 30#include "locations.h" 31#include "optimizer/optimizations/vn.h" 32#include "optimizer/optimizations/cleanup.h" 33#include "optimizer/optimizations/regalloc/reg_alloc_resolver.h" 34#include "optimizer/optimizations/regalloc/reg_alloc.h" 35#include "mem/pool_manager.h" 36 37using namespace testing::ext; 38 39namespace panda::compiler { 40class DumpTest : public testing::Test { 41public: 42 static void SetUpTestCase(void) {} 43 static void TearDownTestCase(void) {} 44 void SetUp() {} 45 void TearDown() {} 46 47 GraphTest graph_test_; 48}; 49 50/** 51 * @tc.name: dump_test_001 52 * @tc.desc: Verify the InstId function. 53 * @tc.type: FUNC 54 * @tc.require: issueNumber 55 */ 56HWTEST_F(DumpTest, dump_test_001, TestSize.Level1) 57{ 58 std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc"; 59 const char *test_method_name = "func_main_0"; 60 bool status = false; 61 compiler::options.SetCompilerDumpCompact(true); 62 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 63 if (test_method_name != method_name) { 64 return; 65 } 66 67 EXPECT_NE(graph, nullptr); 68 for (auto bb : graph->GetBlocksRPO()) { 69 for (auto inst : bb->AllInsts()) { 70 if (inst->GetOpcode() != Opcode::SaveState) { 71 auto value1 = InstId(inst, graph->GetAllocator()); 72 EXPECT_FALSE(value1.empty()); 73 } 74 75 status = true; 76 auto value = InstId(inst, graph->GetAllocator()); 77 EXPECT_FALSE(value.empty()); 78 } 79 } 80 }); 81 EXPECT_TRUE(status); 82} 83 84/** 85 * @tc.name: dump_test_002 86 * @tc.desc: Verify the PcToString function. 87 * @tc.type: FUNC 88 * @tc.require: issueNumber 89 */ 90HWTEST_F(DumpTest, dump_test_002, TestSize.Level1) 91{ 92 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 93 const char *test_method_name = "func_main_0"; 94 bool status = false; 95 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 96 if (test_method_name != method_name) { 97 return; 98 } 99 status = true; 100 EXPECT_NE(graph, nullptr); 101 uint32_t id = 2; 102 std::string test_data = "prop: start, bc: 0x00000000\n"; 103 std::stringstream data; 104 BlockProps(graph->GetStartBlock(), &data); 105 EXPECT_EQ(data.str(), test_data); 106 data.clear(); 107 data.str(""); 108 test_data = "prop: end, bc: 0x00000026\n"; 109 BlockProps(graph->GetEndBlock(), &data); 110 EXPECT_EQ(data.str(), test_data); 111 Loop loop(graph->GetAllocator(), graph->GetEndBlock(), 1); 112 Loop loop1(graph->GetAllocator(), graph->GetEndBlock(), id); 113 Loop loop2(graph->GetAllocator(), graph->GetStartBlock(), 0); 114 Loop loop3(graph->GetAllocator(), graph->GetStartBlock(), 1); 115 loop1.SetIsIrreducible(true); 116 graph->GetEndBlock()->SetLoop(&loop); 117 loop3.SetAsRoot(); 118 data.clear(); 119 data.str(""); 120 test_data = "prop: end, head, loop 1, bc: 0x00000026\n"; 121 BlockProps(graph->GetEndBlock(), &data); 122 EXPECT_EQ(data.str(), test_data); 123 data.clear(); 124 data.str(""); 125 test_data = "prop: loop 0, try_begin (id 0), bc: 0x00000015\n" 126 "prop: loop (irreducible) 2, try (id 0), bc: 0x00000015\n" 127 "prop: try_end (id 0), bc: 0x0000001e\n" 128 "prop: catch_begin, catch, bc: 0x00000020\n" 129 "prop: catch_begin, catch, bc: 0x00000020\n" 130 "prop: catch, bc: 0x00000020\n"; 131 for (auto block : graph->GetBlocksRPO()) { 132 if (block->IsTry()) { 133 block->SetLoop(&loop1); 134 BlockProps(block, &data); 135 } 136 if (block->IsTryBegin()) { 137 block->SetLoop(&loop2); 138 BlockProps(block, &data); 139 } 140 if (block->IsTryEnd()) { 141 block->SetLoop(&loop3); 142 BlockProps(block, &data); 143 } 144 if (block->IsCatch()) { 145 block->SetLoop(nullptr); 146 BlockProps(block, &data); 147 } 148 if (block->IsCatchBegin() || block->IsCatchEnd()) { 149 BlockProps(block, &data); 150 } 151 } 152 auto value1 = PcToString(graph->GetEndBlock()->GetGuestPc(), graph->GetLocalAllocator()); 153 std::string str = value1.data(); 154 EXPECT_EQ(str, "bc: 0x00000026"); 155 EXPECT_EQ(data.str(), test_data); 156 }); 157 EXPECT_TRUE(status); 158} 159 160/** 161 * @tc.name: dump_test_003 162 * @tc.desc: Verify the BBId function. 163 * @tc.type: FUNC 164 * @tc.require: issueNumber 165 */ 166HWTEST_F(DumpTest, dump_test_003, TestSize.Level1) 167{ 168 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 169 const char *test_method_name = "func_main_0"; 170 bool status = false; 171 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 172 if (test_method_name != method_name) { 173 return; 174 } 175 status = true; 176 EXPECT_NE(graph, nullptr); 177 auto value = BBId(graph->GetStartBlock(), graph->GetAllocator()); 178 std::string str = value.data(); 179 EXPECT_EQ(str, "7"); 180 BasicBlock *block = nullptr; 181 str = BBId(block, graph->GetAllocator()).data(); 182 EXPECT_EQ(str, "null"); 183 }); 184 EXPECT_TRUE(status); 185} 186 187/** 188 * @tc.name: dump_test_004 189 * @tc.desc: Verify the DumpInputs function. 190 * @tc.type: FUNC 191 * @tc.require: issueNumber 192 */ 193HWTEST_F(DumpTest, dump_test_004, TestSize.Level1) 194{ 195 std::stringstream out; 196 uint64_t value = 1; 197 ConstantInst constant(Opcode::Constant, value, false); 198 constant.DumpInputs(&out); 199 EXPECT_EQ(out.str(), "0x1"); 200 constant.GetInt64Value(); 201 EXPECT_TRUE(constant.IsBoolConst()); 202 203 float float_value = 1.0; 204 ConstantInst first_constant(Opcode::Constant, float_value, false); 205 out.clear(); 206 out.str(""); 207 EXPECT_TRUE(first_constant.DumpInputs(&out)); 208 EXPECT_EQ(out.str(), "1"); 209 210 double double_value = 1.0; 211 ConstantInst constant_inst(Opcode::Constant, double_value, false); 212 out.clear(); 213 out.str(""); 214 EXPECT_TRUE(constant_inst.DumpInputs(&out)); 215 EXPECT_EQ(out.str(), "1"); 216 EXPECT_FALSE(constant_inst.IsBoolConst()); 217 218 uint32_t integer_value = 1; 219 ConstantInst constant_inst1(Opcode::Constant, integer_value, true); 220 out.clear(); 221 out.str(""); 222 EXPECT_TRUE(constant_inst1.DumpInputs(&out)); 223 EXPECT_EQ(out.str(), "0x1"); 224 constant_inst1.GetInt32Value(); 225 EXPECT_FALSE(constant_inst1.IsBoolConst()); 226 227 uint16_t num = 0; 228 ConstantInst second_constant(Opcode::Constant, num, false); 229 EXPECT_TRUE(second_constant.DumpInputs(&out)); 230 EXPECT_TRUE(second_constant.IsBoolConst()); 231 ConstantInst third_constant(Opcode::Constant, num, false); 232 auto type = DataType::Type::ANY; 233 third_constant.SetType(type); 234 out.clear(); 235 out.str(""); 236 EXPECT_TRUE(third_constant.DumpInputs(&out)); 237 EXPECT_EQ(out.str(), "0x0"); 238 EXPECT_TRUE(third_constant.DumpInputs(&out)); 239} 240 241/** 242 * @tc.name: dump_test_005 243 * @tc.desc: Verify the PrintIfValidLocation function. 244 * @tc.type: FUNC 245 * @tc.require: issueNumber 246 */ 247HWTEST_F(DumpTest, dump_test_005, TestSize.Level1) 248{ 249 std::stringstream out; 250 uintptr_t value = 255; // 255: random number 251 uintptr_t num = 2; // 2: random number 252 Location location(Location::Kind::REGISTER, value); 253 PrintIfValidLocation(location, Arch::AARCH64, &out, false); 254 EXPECT_EQ(out.str(), ""); 255 256 Location locations_info(Location::Kind::FP_REGISTER, num); 257 out.clear(); 258 out.str(""); 259 PrintIfValidLocation(locations_info, Arch::AARCH64, &out, true); 260 EXPECT_EQ(out.str(), "()"); 261 auto unEqual = location.operator==(locations_info); 262 EXPECT_FALSE(unEqual); 263 264 Location locations(Location::Kind::STACK_ARGUMENT); 265 EXPECT_FALSE(locations.IsInvalid()); 266 out.clear(); 267 out.str(""); 268 PrintIfValidLocation(locations, Arch::AARCH64, &out, false); 269 EXPECT_EQ(out.str(), " "); 270 EXPECT_FALSE(locations.IsUnallocatedRegister()); 271 272 out.clear(); 273 out.str(""); 274 Location invalid_location(Location::Kind::INVALID); 275 PrintIfValidLocation(invalid_location, Arch::AARCH64, &out, false); 276 EXPECT_EQ(out.str(), ""); 277} 278 279/** 280 * @tc.name: dump_test_006 281 * @tc.desc: Verify the GetCondCodeToString function. 282 * @tc.type: FUNC 283 * @tc.require: issueNumber 284 */ 285HWTEST_F(DumpTest, dump_test_006, TestSize.Level1) 286{ 287 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 288 const char *test_method_name = "func_main_0"; 289 bool status = false; 290 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 291 if (test_method_name != method_name) { 292 return; 293 } 294 status = true; 295 EXPECT_NE(graph, nullptr); 296 IfImmInst imm_inst(ConditionCode::CC_EQ); 297 auto value = GetCondCodeToString(imm_inst.GetCc(), graph->GetAllocator()); 298 std::string str = value.data(); 299 EXPECT_EQ(str, "EQ"); 300 IfImmInst inst(ConditionCode::CC_NE); 301 auto value1 = GetCondCodeToString(inst.GetCc(), graph->GetAllocator()); 302 str = value1.data(); 303 EXPECT_EQ(str, "NE"); 304 305 IfImmInst ifImm_inst(ConditionCode::CC_LT); 306 auto result = GetCondCodeToString(ifImm_inst.GetCc(), graph->GetAllocator()); 307 str = result.data(); 308 EXPECT_EQ(str, "LT"); 309 IfImmInst ifImm(ConditionCode::CC_LE); 310 auto num = GetCondCodeToString(ifImm.GetCc(), graph->GetAllocator()); 311 str = num.data(); 312 EXPECT_EQ(str, "LE"); 313 314 IfImmInst ifInst(ConditionCode::CC_GE); 315 auto number = GetCondCodeToString(ifInst.GetCc(), graph->GetAllocator()); 316 str = number.data(); 317 EXPECT_EQ(str, "GE"); 318 IfImmInst imm_inst1(ConditionCode::CC_GT); 319 auto info = GetCondCodeToString(imm_inst1.GetCc(), graph->GetAllocator()); 320 str = info.data(); 321 EXPECT_EQ(str, "GT"); 322 323 IfImmInst ifImm_inst1(ConditionCode::CC_B); 324 auto testData = GetCondCodeToString(ifImm_inst1.GetCc(), graph->GetAllocator()); 325 str = testData.data(); 326 EXPECT_EQ(str, "B"); 327 IfImmInst first_imm_inst(ConditionCode::CC_BE); 328 auto code = GetCondCodeToString(first_imm_inst.GetCc(), graph->GetAllocator()); 329 str = code.data(); 330 EXPECT_EQ(str, "BE"); 331 332 IfImmInst first_inst(ConditionCode::CC_A); 333 auto number1 = GetCondCodeToString(first_inst.GetCc(), graph->GetAllocator()); 334 str = number1.data(); 335 EXPECT_EQ(str, "A"); 336 IfImmInst second_inst(ConditionCode::CC_AE); 337 auto number2 = GetCondCodeToString(second_inst.GetCc(), graph->GetAllocator()); 338 str = number2.data(); 339 EXPECT_EQ(str, "AE"); 340 341 IfImmInst first_imm_inst1(ConditionCode::CC_TST_EQ); 342 auto datum = GetCondCodeToString(first_imm_inst1.GetCc(), graph->GetAllocator()); 343 str = datum.data(); 344 EXPECT_EQ(str, "TST_EQ"); 345 346 IfImmInst second_imm_inst(ConditionCode::CC_TST_NE); 347 auto datum1 = GetCondCodeToString(second_imm_inst.GetCc(), graph->GetAllocator()); 348 str = datum1.data(); 349 EXPECT_EQ(str, "TST_NE"); 350 351 IfImmInst if_inst2(ConditionCode::CC_FIRST); 352 auto data = GetCondCodeToString(if_inst2.GetCc(), graph->GetAllocator()); 353 str = data.data(); 354 EXPECT_EQ(str, "EQ"); 355 }); 356 EXPECT_TRUE(status); 357} 358 359/** 360 * @tc.name: dump_test_007 361 * @tc.desc: Verify the DumpOpcode function. 362 * @tc.type: FUNC 363 * @tc.require: issueNumber 364 */ 365HWTEST_F(DumpTest, dump_test_007, TestSize.Level1) 366{ 367 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 368 const char *test_method_name = "func_main_0"; 369 bool status = false; 370 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 371 if (test_method_name != method_name) { 372 return; 373 } 374 status = true; 375 EXPECT_NE(graph, nullptr); 376 std::string test_data = " Parameter"; 377 std::stringstream out; 378 auto inst = graph->GetStartBlock()->GetFirstInst(); 379 inst->DumpOpcode(&out); 380 EXPECT_EQ(out.str(), test_data); 381 EXPECT_FALSE(inst->IsSaveState()); 382 }); 383 EXPECT_TRUE(status); 384} 385 386/** 387 * @tc.name: dump_test_008 388 * @tc.desc: Verify the DumpInputs function. 389 * @tc.type: FUNC 390 * @tc.require: issueNumber 391 */ 392HWTEST_F(DumpTest, dump_test_008, TestSize.Level1) 393{ 394 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 395 const char *test_method_name = "func_main_0"; 396 bool status = false; 397 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 398 if (test_method_name != method_name) { 399 return; 400 } 401 402 EXPECT_NE(graph, nullptr); 403 std::string test_data = "arg 0arg 1arg 2"; 404 std::stringstream out; 405 for (auto bb : graph->GetBlocksRPO()) { 406 for (auto inst : bb->AllInsts()) { 407 if (inst->GetOpcode() != Opcode::Parameter) { 408 continue; 409 } 410 status = true; 411 auto parameterInst = inst->CastToParameter(); 412 EXPECT_TRUE(parameterInst->DumpInputs(&out)); 413 } 414 } 415 EXPECT_EQ(out.str(), test_data); 416 }); 417 EXPECT_TRUE(status); 418} 419 420/** 421 * @tc.name: dump_test_009 422 * @tc.desc: Verify the DumpInputs function. 423 * @tc.type: FUNC 424 * @tc.require: issueNumber 425 */ 426HWTEST_F(DumpTest, dump_test_009, TestSize.Level1) 427{ 428 std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc"; 429 const char *test_method_name = "func4"; 430 bool status = false; 431 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 432 if (test_method_name != method_name) { 433 return; 434 } 435 436 EXPECT_NE(graph, nullptr); 437 graph->RunPass<Cleanup>(); 438 graph->RunPass<bytecodeopt::RegAccAlloc>(); 439 graph->RunPass<Cleanup>(); 440 EXPECT_TRUE(RegAlloc(graph)); 441 graph->RunPass<Cleanup>(); 442 EXPECT_TRUE(graph->RunPass<bytecodeopt::RegEncoder>()); 443 std::string test_data = " -> [u64], -> [u64], -> [u64], -> [u64], -> [u64]"; 444 std::stringstream out; 445 for (auto block : graph->GetVectorBlocks()) { 446 if (block == nullptr) { 447 continue; 448 } 449 for (auto inst : block->AllInsts()) { 450 if (inst->GetOpcode() != Opcode::SpillFill) { 451 continue; 452 } 453 status = true; 454 auto spillFill = inst->CastToSpillFill(); 455 EXPECT_TRUE(spillFill->DumpInputs(&out)); 456 } 457 } 458 EXPECT_EQ(out.str(), test_data); 459 }); 460 EXPECT_TRUE(status); 461} 462 463/** 464 * @tc.name: dump_test_010 465 * @tc.desc: Verify the DumpTypedOpcode function. 466 * @tc.type: FUNC 467 * @tc.require: issueNumber 468 */ 469HWTEST_F(DumpTest, dump_test_010, TestSize.Level1) 470{ 471 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 472 const char *test_method_name = "func_main_0"; 473 bool status = false; 474 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 475 if (test_method_name != method_name) { 476 return; 477 } 478 status = true; 479 EXPECT_NE(graph, nullptr); 480 std::string test_data = " SaveState 1"; 481 std::stringstream out; 482 uint32_t typeId = 1; 483 auto inst = graph->CreateInst(Opcode::SaveState); 484 DumpTypedOpcode(&out, inst->GetOpcode(), typeId, graph->GetLocalAllocator()); 485 EXPECT_TRUE(inst->IsSaveState()); 486 EXPECT_EQ(out.str(), test_data); 487 }); 488 EXPECT_TRUE(status); 489} 490 491/** 492 * @tc.name: dump_test_011 493 * @tc.desc: Verify the DumpOpcode function. 494 * @tc.type: FUNC 495 * @tc.require: issueNumber 496 */ 497HWTEST_F(DumpTest, dump_test_011, TestSize.Level1) 498{ 499 std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc"; 500 const char *test_method_name = "func_main_0"; 501 bool status = false; 502 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 503 if (test_method_name != method_name) { 504 return; 505 } 506 507 EXPECT_NE(graph, nullptr); 508 std::stringstream data; 509 std::string test_data = " Compare EQ any Compare EQ any Compare EQ any" 510 " Compare EQ any Compare EQ any"; 511 for (auto bb : graph->GetBlocksRPO()) { 512 for (auto inst : bb->AllInsts()) { 513 auto value = inst->IsZeroRegInst(); 514 EXPECT_FALSE(value); 515 if (inst->GetOpcode() != Opcode::Compare) { 516 continue; 517 } 518 status = true; 519 auto compare = inst->CastToCompare(); 520 compare->DumpOpcode(&data); 521 } 522 } 523 EXPECT_EQ(data.str(), test_data); 524 }); 525 EXPECT_TRUE(status); 526} 527 528/** 529 * @tc.name: dump_test_012 530 * @tc.desc: Verify the DumpOpcode function. 531 * @tc.type: FUNC 532 * @tc.require: issueNumber 533 */ 534HWTEST_F(DumpTest, dump_test_012, TestSize.Level1) 535{ 536 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 537 const char *test_method_name = "foo"; 538 bool status = false; 539 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 540 if (test_method_name != method_name) { 541 return; 542 } 543 544 EXPECT_NE(graph, nullptr); 545 std::stringstream data; 546 std::string test_data = " IfImm NE b"; 547 for (auto bb : graph->GetBlocksRPO()) { 548 for (auto inst : bb->AllInsts()) { 549 if (inst->GetOpcode() != Opcode::IfImm) { 550 continue; 551 } 552 status = true; 553 auto ifImmInst = inst->CastToIfImm(); 554 ifImmInst->DumpOpcode(&data); 555 EXPECT_TRUE(inst->IsAccRead()); 556 } 557 } 558 EXPECT_EQ(data.str(), test_data); 559 }); 560 EXPECT_TRUE(status); 561} 562 563/** 564 * @tc.name: dump_test_013 565 * @tc.desc: Verify the DumpInputs function. 566 * @tc.type: FUNC 567 * @tc.require: issueNumber 568 */ 569HWTEST_F(DumpTest, dump_test_013, TestSize.Level1) 570{ 571 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 572 const char *test_method_name = "foo"; 573 bool status = false; 574 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 575 if (test_method_name != method_name) { 576 return; 577 } 578 579 EXPECT_NE(graph, nullptr); 580 std::stringstream data; 581 std::string test_data = "v10, 0x0"; 582 for (auto bb : graph->GetBlocksRPO()) { 583 for (auto inst : bb->AllInsts()) { 584 if (inst->GetOpcode() != Opcode::IfImm) { 585 continue; 586 } 587 status = true; 588 auto ifImmInst = inst->CastToIfImm(); 589 EXPECT_TRUE(ifImmInst->DumpInputs(&data)); 590 } 591 } 592 EXPECT_EQ(data.str(), test_data); 593 }); 594 EXPECT_TRUE(status); 595} 596 597/** 598 * @tc.name: dump_test_014 599 * @tc.desc: Verify the DumpOpcode function. 600 * @tc.type: FUNC 601 * @tc.require: issueNumber 602 */ 603HWTEST_F(DumpTest, dump_test_014, TestSize.Level1) 604{ 605 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 606 const char *test_method_name = "func_main_0"; 607 bool status = false; 608 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 609 if (test_method_name != method_name) { 610 return; 611 } 612 613 EXPECT_NE(graph, nullptr); 614 std::stringstream data; 615 std::string test_data = " Intrinsic.definefunc" 616 " Intrinsic.stglobalvar Intrinsic.definefunc" 617 " Intrinsic.stglobalvar Intrinsic.trystglobalbyname Intrinsic.tryldglobalbyname" 618 " Intrinsic.ldundefined Intrinsic.returnundefined "; 619 for (auto bb : graph->GetBlocksRPO()) { 620 for (auto inst : bb->AllInsts()) { 621 if (inst->GetOpcode() != Opcode::Intrinsic) { 622 continue; 623 } 624 status = true; 625 auto intrinsic = inst->CastToIntrinsic(); 626 intrinsic->DumpOpcode(&data); 627 } 628 } 629 EXPECT_EQ(data.str(), test_data); 630 }); 631 EXPECT_TRUE(status); 632} 633 634/** 635 * @tc.name: dump_test_015 636 * @tc.desc: Verify the DumpOpcode function. 637 * @tc.type: FUNC 638 * @tc.require: issueNumber 639 */ 640HWTEST_F(DumpTest, dump_test_015, TestSize.Level1) 641{ 642 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 643 const char *test_method_name = "func_main_0"; 644 bool status = false; 645 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 646 if (test_method_name != method_name) { 647 return; 648 } 649 status = true; 650 EXPECT_NE(graph, nullptr); 651 LoadFromPool loadFromPool; 652 std::stringstream out; 653 std::string test_data = " LoadString 1"; 654 uint32_t id = 1; 655 uint32_t guestPc = 5; // 5: random number 656 BasicBlock block(graph, guestPc); 657 loadFromPool.SetOpcode(Opcode::LoadString); 658 EXPECT_EQ(loadFromPool.GetOpcode(), Opcode::LoadString); 659 loadFromPool.SetBasicBlock(&block); 660 EXPECT_NE(loadFromPool.GetBasicBlock(), nullptr); 661 loadFromPool.SetTypeId(id); 662 EXPECT_EQ(loadFromPool.GetTypeId(), 1); 663 loadFromPool.DumpOpcode(&out); 664 auto result = block.IsCatch(); 665 EXPECT_FALSE(result); 666 EXPECT_EQ(out.str(), test_data); 667 }); 668 EXPECT_TRUE(status); 669} 670 671/** 672 * @tc.name: dump_test_016 673 * @tc.desc: Verify the DumpTypedFieldOpcode function. 674 * @tc.type: FUNC 675 * @tc.require: issueNumber 676 */ 677HWTEST_F(DumpTest, dump_test_016, TestSize.Level1) 678{ 679 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 680 const char *test_method_name = "foo"; 681 bool status = false; 682 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 683 if (test_method_name != method_name) { 684 return; 685 } 686 status = true; 687 EXPECT_NE(graph, nullptr); 688 std::stringstream out; 689 std::string test_data = " Phi 1 field_name "; 690 ArenaString fieldName("field_name", graph->GetAllocator()->Adapter()); 691 uint32_t typeId = 1; 692 for (auto bb : graph->GetBlocksRPO()) { 693 for (auto inst : bb->PhiInsts()) { 694 DumpTypedFieldOpcode(&out, inst->GetOpcode(), typeId, fieldName, graph->GetAllocator()); 695 EXPECT_TRUE(inst->IsPhi()); 696 } 697 } 698 EXPECT_EQ(out.str(), test_data); 699 }); 700 EXPECT_TRUE(status); 701} 702 703/** 704 * @tc.name: dump_test_017 705 * @tc.desc: Verify the DumpOpcode function. 706 * @tc.type: FUNC 707 * @tc.require: issueNumber 708 */ 709HWTEST_F(DumpTest, dump_test_017, TestSize.Level1) 710{ 711 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 712 const char *test_method_name = "func_main_0"; 713 bool status = false; 714 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 715 if (test_method_name != method_name) { 716 return; 717 } 718 status = true; 719 EXPECT_NE(graph, nullptr); 720 std::stringstream out; 721 std::string test_data = "CastValueToAnyType UNDEFINED_TYPE "; 722 uint32_t guestPc = 5; 723 BasicBlock block(graph, guestPc); 724 CastValueToAnyTypeInst castValueToAnyType; 725 castValueToAnyType.SetOpcode(Opcode::CastValueToAnyType); 726 castValueToAnyType.SetBasicBlock(&block); 727 castValueToAnyType.SetAnyType(AnyBaseType::UNDEFINED_TYPE); 728 castValueToAnyType.DumpOpcode(&out); 729 EXPECT_EQ(out.str(), test_data); 730 }); 731 EXPECT_TRUE(status); 732} 733 734/** 735 * @tc.name: dump_test_018 736 * @tc.desc: Verify the Dump function. 737 * @tc.type: FUNC 738 * @tc.require: issueNumber 739 */ 740HWTEST_F(DumpTest, dump_test_018, TestSize.Level1) 741{ 742 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 743 const char *test_method_name = "func_main_0"; 744 bool status = false; 745 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 746 if (test_method_name != method_name) { 747 return; 748 } 749 status = true; 750 EXPECT_NE(graph, nullptr); 751 std::stringstream out; 752 std::string test_data = "Method: L_GLOBAL;::func_main_0\n\n" 753 "BB 7\n" 754 "prop: start, bc: 0x00000000\n" 755 " 5.any Parameter " 756 "arg 0 \n -> [u64]\n" 757 " 6.any Parameter " 758 "arg 1 \n -> [u64]\n" 759 " 7.any Parameter " 760 "arg 2 \n -> [u64]\n" 761 " 16.i32 Constant 0x1 -> " 762 "(v17) \n" 763 "succs: [bb 0]\n\n" 764 "BB 0 preds: [bb 7]\n" 765 "prop: bc: 0x00000000\n" 766 " 8.any Intrinsic.definefunc ss9 -> (v10)" 767 " \n" 768 " 10.void Intrinsic.stglobalvar v8, ss11" 769 " \n" 770 " 12.any Intrinsic.definefunc ss13 -> (v14)" 771 " \n" 772 " 14.void Intrinsic.stglobalvar v12, ss15" 773 " \n" 774 "succs: [bb 2]\n\n" 775 "BB 2 preds: [bb 0]\n" 776 "prop: try_begin (id 0), bc: 0x00000015\n" 777 " 0. Try " 778 " \n" 779 "succs: [bb 4, bb 9]\n\n" 780 "BB 4 preds: [bb 2]\n" 781 "prop: try (id 0), bc: 0x00000015\n" 782 " 17.void Intrinsic.trystglobalbyname v16, ss18" 783 " \n" 784 "succs: [bb 3]\n\n" 785 "BB 3 preds: [bb 4]\n" 786 "prop: try_end (id 0), bc: 0x0000001e\n" 787 "succs: [bb 5, bb 9]\n\n" 788 "BB 9 preds: [bb 2, bb 3]\n" 789 "prop: catch_begin, catch, bc: 0x00000020\n" 790 "succs: [bb 6]\n\n" 791 "BB 6 preds: [bb 9]\n" 792 "prop: catch, bc: 0x00000020\n" 793 " 19.any Intrinsic.tryldglobalbyname ss20 " 794 " \n" 795 "succs: [bb 1]\n\n" 796 "BB 5 preds: [bb 3]\n" 797 "prop: bc: 0x0000001e\n" 798 "succs: [bb 1]\n\n" 799 "BB 1 preds: [bb 5, bb 6]\n" 800 "prop: bc: 0x00000024\n" 801 " 25.any Intrinsic.ldundefined ss26" 802 " \n" 803 " 27.void Intrinsic.returnundefined ss28" 804 " \n" 805 "succs: [bb 8]\n\n" 806 "BB 8 preds: [bb 1]\n" 807 "prop: end, bc: 0x00000026\n\n"; 808 graph->Dump(&out); 809 EXPECT_TRUE(graph->HasEndBlock()); 810 EXPECT_EQ(out.str(), test_data); 811 }); 812 EXPECT_TRUE(status); 813} 814 815/** 816 * @tc.name: dump_test_019 817 * @tc.desc: Verify the Dump function. 818 * @tc.type: FUNC 819 * @tc.require: issueNumber 820 */ 821HWTEST_F(DumpTest, dump_test_019, TestSize.Level1) 822{ 823 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 824 const char *test_method_name = "func_main_0"; 825 bool status = false; 826 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 827 if (test_method_name != method_name) { 828 return; 829 } 830 status = true; 831 EXPECT_NE(graph, nullptr); 832 std::stringstream out; 833 std::string test_data = "BB 7\n" 834 "prop: start, bc: 0x00000000\n" 835 " 5.any Parameter arg 0" 836 " \n -> [u64]\n" 837 " 6.any Parameter arg 1" 838 " \n -> [u64]\n" 839 " 7.any Parameter arg 2" 840 " \n -> [u64]\n" 841 " 16.i32 Constant 0x1 -> (v17)" 842 " \n" 843 "succs: [bb 0]\n" 844 "BB 0 preds: [bb 7]\n" 845 "prop: bc: 0x00000000\n" 846 " 8.any Intrinsic.definefunc ss9 -> (v10)" 847 " \n" 848 " 10.void Intrinsic.stglobalvar v8, ss11" 849 " \n" 850 " 12.any Intrinsic.definefunc ss13 -> (v14)" 851 " \n" 852 " 14.void Intrinsic.stglobalvar v12, ss15" 853 " \n" 854 "succs: [bb 2]\n" 855 "BB 2 preds: [bb 0]\n" 856 "prop: try_begin (id 0), bc: 0x00000015\n" 857 " 0. Try " 858 " \n" 859 "succs: [bb 4, bb 9]\n" 860 "BB 4 preds: [bb 2]\n" 861 "prop: try (id 0), bc: 0x00000015\n" 862 " 17.void Intrinsic.trystglobalbyname v16, ss18" 863 " \n" 864 "succs: [bb 3]\n" 865 "BB 3 preds: [bb 4]\n" 866 "prop: try_end (id 0), bc: 0x0000001e\n" 867 "succs: [bb 5, bb 9]\n" 868 "BB 9 preds: [bb 2, bb 3]\n" 869 "prop: catch_begin, catch, bc: 0x00000020\n" 870 "succs: [bb 6]\n" 871 "BB 6 preds: [bb 9]\n" 872 "prop: catch, bc: 0x00000020\n" 873 " 19.any Intrinsic.tryldglobalbyname ss20" 874 " \n" 875 "succs: [bb 1]\n" 876 "BB 5 preds: [bb 3]\n" 877 "prop: bc: 0x0000001e\n" 878 "succs: [bb 1]\n" 879 "BB 1 preds: [bb 5, bb 6]\n" 880 "prop: bc: 0x00000024\n" 881 " 25.any Intrinsic.ldundefined ss26" 882 " \n" 883 " 27.void Intrinsic.returnundefined ss28" 884 " \n" 885 "succs: [bb 8]\n" 886 "BB 8 preds: [bb 1]\n" 887 "prop: end, bc: 0x00000026\n"; 888 for (auto bb : graph->GetBlocksRPO()) { 889 bb->Dump(&out); 890 } 891 EXPECT_EQ(out.str(), test_data); 892 }); 893 EXPECT_TRUE(status); 894} 895 896/** 897 * @tc.name: dump_test_020 898 * @tc.desc: Verify the AppendImmediate function. 899 * @tc.type: FUNC 900 * @tc.require: issueNumber 901 */ 902HWTEST_F(DumpTest, dump_test_020, TestSize.Level1) 903{ 904 std::string pfile = GRAPH_TEST_ABC_DIR "regallocTest.abc"; 905 const char *test_method_name = "func5"; 906 bool status = false; 907 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 908 if (test_method_name != method_name) { 909 return; 910 } 911 912 EXPECT_NE(graph, nullptr); 913 uint64_t immediate = 1; 914 uint16_t vreg = 2; // 2: random number 915 bool isAcc = true; 916 std::stringstream out; 917 std::string test_data = "0x1(acc)0x1(acc)0x1(acc)0x1(acc)0x1(acc)0x1(acc)0x1(acc)0x1(acc)0x1(acc)0x1(acc)0x1" 918 "(acc)0x1(acc)0x1(acc)0x1(acc)0x1(acc)"; 919 920 for (auto bb : graph->GetVectorBlocks()) { 921 for (auto inst : bb->AllInsts()) { 922 if (inst->GetOpcode() != Opcode::SaveState) { 923 continue; 924 } 925 status = true; 926 auto saveState = inst->CastToSaveState(); 927 saveState->AppendImmediate(immediate, vreg, DataType::Type::INT64, isAcc); 928 EXPECT_TRUE(saveState->DumpInputs(&out)); 929 } 930 } 931 EXPECT_EQ(out.str(), test_data); 932 }); 933 EXPECT_TRUE(status); 934} 935 936/** 937 * @tc.name: dump_test_021 938 * @tc.desc: Verify the DumpInputs function. 939 * @tc.type: FUNC 940 * @tc.require: issueNumber 941 */ 942HWTEST_F(DumpTest, dump_test_021, TestSize.Level1) 943{ 944 std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc"; 945 const char *test_method_name = "foo"; 946 bool status = false; 947 graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) { 948 if (test_method_name != method_name) { 949 return; 950 } 951 952 std::stringstream out; 953 std::string test_data = "v4(bb0), v5(bb2)"; 954 for (auto bb : graph->GetBlocksRPO()) { 955 for (auto inst : bb->PhiInsts()) { 956 auto phi = inst->CastToPhi(); 957 status = true; 958 EXPECT_TRUE(phi->DumpInputs(&out)); 959 } 960 } 961 962 EXPECT_EQ(out.str(), test_data); 963 }); 964 EXPECT_TRUE(status); 965} 966} // namespace panda::compiler 967