1# Copyright (c) 2021-2024 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14# 15# Checked tests for basic inlining. 16# 17 18#! CHECKER Instructions limit 19#! RUN force_jit: true, options: "--compiler-regex=Test1::main --compiler-inlining-max-insts=8 --compiler-inlining-always-inline-bc-size=0", entry: "Test1::main" 20#! EVENT /Inline,Test1::main,_GLOBAL::func,.*STATIC,LIMIT/ 21#! EVENT_NEXT /Inline,Test1::main,_GLOBAL::small_func,.*STATIC,SUCCESS/ 22 23#! CHECKER Instructions limit at Regular AOT 24#! RUN_PAOC options: "--compiler-regex=Test1::main --compiler-inlining-max-insts=8 --compiler-inlining-always-inline-bc-size=0" 25#! EVENT /Inline,Test1::main,_GLOBAL::func,.*STATIC,LIMIT/ 26#! EVENT_NEXT /Inline,Test1::main,_GLOBAL::small_func,.*STATIC,SUCCESS/ 27#! RUN entry: "Test1::main" 28 29#! CHECKER Instructions max size 30#! RUN force_jit: true, options: "--compiler-regex=Test1::main --compiler-inlining-max-insts=8 --compiler-inlining-always-inline-bc-size=0", entry: "Test1::main" 31#! EVENT /Inline,Test1::main,_GLOBAL::func,.*STATIC,LIMIT/ 32#! EVENT_NEXT /Inline,Test1::main,_GLOBAL::small_func,.*STATIC,SUCCESS/ 33 34#! CHECKER Instructions max size at Regular AOT 35#! RUN_PAOC options: "--compiler-regex=Test1::main --compiler-inlining-max-insts=8 --compiler-inlining-always-inline-bc-size=0" 36#! EVENT /Inline,Test1::main,_GLOBAL::func,.*STATIC,LIMIT/ 37#! EVENT_NEXT /Inline,Test1::main,_GLOBAL::small_func,.*STATIC,SUCCESS/ 38#! RUN entry: "Test1::main" 39 40.record Test1 {} 41 42.function i32 func(i32 a0) { 43 newobj v0, Test1 44 newobj v0, Test1 45 newobj v0, Test1 46 newobj v0, Test1 47 ldai 1 48 add2 a0 49 return 50} 51 52.function i32 small_func(i32 a0) { 53 ldai 1 54 add2 a0 55 return 56} 57 58.function i32 Test1.main() { 59 movi v1, 10 60 61 call.short func, v1 62 call.short small_func, v1 63 add2 v1 64 65 ldai 0 66 return 67} 68 69#! CHECKER Inline depth limit 70#! RUN force_jit: true, options: "--compiler-regex=Test1::main_depth --compiler-inlining-max-depth=2 --compiler-inlining-recursive-calls-limit=2", entry: "Test1::main_depth" 71#! EVENTS_COUNT /Inline,Test1::main_depth,_GLOBAL::func_rec,.*STATIC,SUCCESS/, 1 72#! EVENTS_COUNT /Inline,_GLOBAL::func_rec,_GLOBAL::func_rec,.*STATIC,SUCCESS/, 1 73 74#! CHECKER Inline depth limit at Regular AOT 75#! RUN_PAOC options: "--compiler-regex=Test1::main_depth --compiler-inlining-max-depth=2 --compiler-inlining-recursive-calls-limit=2" 76#! EVENTS_COUNT /Inline,Test1::main_depth,_GLOBAL::func_rec,.*STATIC,SUCCESS/, 1 77#! EVENTS_COUNT /Inline,_GLOBAL::func_rec,_GLOBAL::func_rec,.*STATIC,SUCCESS/, 1 78#! RUN entry: "Test1::main_depth" 79 80.function i32 func_rec(i32 a0) { 81 lda a0 82 jeqz exit 83 subi 1 84 sta a0 85 call.short func_rec, a0 86exit: 87 return 88} 89 90.function i32 Test1.main_depth() { 91 movi v1, 10 92 93 call.short func_rec, v1 94 95 return 96} 97 98#! CHECKER Check inlined float array 99#! RUN force_jit: true, options: "--compiler-regex=_GLOBAL::main", entry: "_GLOBAL::main" 100#! EVENT /Inline,_GLOBAL::main,_GLOBAL::farray,.*STATIC,SUCCESS/ 101#! METHOD "_GLOBAL::main" 102#! PASS_AFTER "Inline" 103#! INST "CallStatic.Inlined" 104 105#! CHECKER Check inlined float array at Regular AOT 106#! RUN_PAOC options: "--compiler-regex=_GLOBAL::main" 107#! EVENT /Inline,_GLOBAL::main,_GLOBAL::farray,.*STATIC,SUCCESS/ 108#! METHOD "_GLOBAL::main" 109#! PASS_AFTER "Inline" 110#! INST "CallStatic.Inlined" 111#! RUN entry: "_GLOBAL::main" 112 113#! CHECKER Check inlined float array at LLVM AOT 114#! RUN_LLVM options: "--compiler-regex='(_GLOBAL::main|_GLOBAL::farray)' --llvm-dump-before --llvm-dump-after \ 115#! --llvm-pre-opt=0" 116#! READ_FILE "console.out" 117#! INST "LLVM IR module BEFORE LLVM optimizations" 118#! INST_NEXT /define protected.*_GLOBAL::main/ 119#! INST_NEXT /call.*_GLOBAL::farray/ 120#! INST "LLVM IR module AFTER LLVM optimizations" 121#! INST_NEXT /define protected.*_GLOBAL::main/ 122#! INST_NEXT /label %"void _GLOBAL::farray/ 123#! RUN entry: "_GLOBAL::main" 124 125.function void farray(f64[] a0) { 126 ldai 2 127 movi v0, 1 128 fstarr.64 a0, v0 129 return.void 130} 131 132.function i32 main() { 133 movi v0, 5 134 newarr v1, v0, f64[] 135 call.short farray, v1 136 ldai 0 137 return 138} 139 140#! CHECKER Inline function with dead loop 141#! RUN force_jit: true, options: "--compiler-regex=_GLOBAL::main1", entry: "_GLOBAL::main1" 142#! EVENT /Inline,_GLOBAL::main1,_GLOBAL::foo1,.*STATIC,SUCCESS/ 143#! METHOD "_GLOBAL::main1" 144#! PASS_AFTER "Inline" 145#! INST_NOT "CallStatic.Inlined" 146#! INST_NOT "Return.Inlined" 147#! INST_NOT "SaveStateDeoptimize" 148 149#! CHECKER Inline function with dead loop at Regular AOT 150#! RUN_PAOC options: "--compiler-regex=_GLOBAL::main1" 151#! EVENT /Inline,_GLOBAL::main1,_GLOBAL::foo1,.*STATIC,SUCCESS/ 152#! METHOD "_GLOBAL::main1" 153#! PASS_AFTER "Inline" 154#! INST_NOT "CallStatic.Inlined" 155#! INST_NOT "Return.Inlined" 156#! INST_NOT "SaveStateDeoptimize" 157#! RUN entry: "_GLOBAL::main1" 158 159#! CHECKER Inline function with dead loop at LLVM AOT 160#! RUN_LLVM options: "--compiler-regex='(_GLOBAL::main1|_GLOBAL::foo1)' --llvm-dump-before --llvm-dump-after \ 161#! --llvm-pre-opt=0" 162#! READ_FILE "console.out" 163#! INST "LLVM IR module BEFORE LLVM optimizations" 164#! INST_NEXT /define protected.*_GLOBAL::main/ 165#! INST_NEXT /call.*_GLOBAL::foo1/ 166#! INST "LLVM IR module AFTER LLVM optimizations" 167#! INST_NEXT /define protected.*_GLOBAL::main/ 168#! INST_NEXT "ret i32 0" 169#! RUN entry: "_GLOBAL::main1" 170 171.function i32 foo1() { 172 movi v1, 0 173 ldai 10 174lbl: 175 jle v1, lbl # jump to 0 offset, never happens 176 ldai 0 177 return 178} 179 180.function i32 main1() { 181 call foo1 182 return 183} 184 185 186#! CHECKER Change to CallStatic by instructions limit 187#! RUN force_jit: true, options: "--compiler-regex=Test2::main --compiler-inlining-max-insts=12 --compiler-inlining-always-inline-bc-size=0", entry: "Test2::main" 188#! EVENT /Inline,Test2::main,Test2::func,.*VIRTUAL,LIMIT/ 189#! EVENT_NEXT /Inline,Test2::main,Test2::func,.*VIRTUAL,DEVIRTUALIZED/ 190#! EVENT_NEXT /Inline,Test2::main,Test2::small_func,.*VIRTUAL,SUCCESS/ 191 192#! CHECKER Change to CallStatic by instructions limit at Regular AOT 193#! RUN_PAOC options: "--compiler-regex=Test2::main --compiler-inlining-max-insts=12 --compiler-inlining-always-inline-bc-size=0" 194#! EVENT /Inline,Test2::main,Test2::func,.*VIRTUAL,LIMIT/ 195#! EVENT_NEXT /Inline,Test2::main,Test2::func,.*VIRTUAL,DEVIRTUALIZED/ 196#! EVENT_NEXT /Inline,Test2::main,Test2::small_func,.*VIRTUAL,SUCCESS/ 197#! RUN entry: "Test2::main" 198 199#! CHECKER Change to CallStatic by instructions limit at LLVM AOT 200#! RUN_LLVM options: "--compiler-regex=Test2.* --compiler-inlining-max-insts=12 --compiler-inlining-always-inline-bc-size=0 \ 201#! --llvm-pre-opt=0" 202#! EVENT_NEXT /Inline,Test2::main,Test2::func,.*VIRTUAL,DEVIRTUALIZED/ 203#! EVENT_NEXT /Inline,Test2::main,Test2::small_func,.*VIRTUAL,DEVIRTUALIZED/ 204#! RUN entry: "Test2::main" 205 206#! CHECKER Change to CallStatic by instructions max size 207#! RUN force_jit: true, options: "--compiler-regex=Test2::main --compiler-inlining-max-insts=8 --compiler-inlining-always-inline-bc-size=0", entry: "Test2::main" 208#! EVENT /Inline,Test2::main,Test2::func,.*VIRTUAL,LIMIT/ 209#! EVENT_NEXT /Inline,Test2::main,Test2::func,.*VIRTUAL,DEVIRTUALIZED/ 210#! EVENT_NEXT /Inline,Test2::main,Test2::small_func,.*VIRTUAL,SUCCESS/ 211 212#! CHECKER Change to CallStatic by instructions size at Regular AOT 213#! RUN_PAOC options: "--compiler-regex=Test2::main --compiler-inlining-max-insts=8 --compiler-inlining-always-inline-bc-size=0" 214#! EVENT /Inline,Test2::main,Test2::func,.*VIRTUAL,LIMIT/ 215#! EVENT_NEXT /Inline,Test2::main,Test2::func,.*VIRTUAL,DEVIRTUALIZED/ 216#! EVENT_NEXT /Inline,Test2::main,Test2::small_func,.*VIRTUAL,SUCCESS/ 217#! RUN entry: "Test2::main" 218 219#! CHECKER Change to CallStatic by instructions size at LLVM AOT 220#! RUN_LLVM options: "--compiler-regex=Test2::main --compiler-inlining-max-insts=8 --compiler-inlining-always-inline-bc-size=0 \ 221#! --llvm-pre-opt=0" 222#! EVENT_NEXT /Inline,Test2::main,Test2::func,.*VIRTUAL,DEVIRTUALIZED/ 223#! EVENT_NEXT /Inline,Test2::main,Test2::small_func,.*VIRTUAL,DEVIRTUALIZED/ 224#! RUN entry: "Test2::main" 225 226.record Test2 {} 227 228.function i32 Test2.func(Test2 a0, i32 a1) { 229 newobj v0, Test1 230 newobj v0, Test1 231 newobj v0, Test1 232 newobj v0, Test1 233 ldai 1 234 add2 a1 235 return 236} 237 238.function i32 Test2.small_func(Test2 a0, i32 a1) { 239 ldai 1 240 add2 a1 241 return 242} 243 244.function i32 Test2.main() { 245 newobj v0, Test2 246 movi v1, 10 247 248 call.virt Test2.func, v0, v1 249 call.virt Test2.small_func, v0, v1 250 add2 v1 251 252 ldai 0 253 return 254} 255 256#! CHECKER Do not inline infinite loop 257#! RUN force_jit: true, entry: "Test3::main" 258#! EVENT /Inline,Test3::main,Test3::foo1,.*VIRTUAL,SUCCESS/ 259#! EVENT /Inline,Test3::main,_GLOBAL::foo_inf_loop,.*STATIC,INF_LOOP/ 260 261#! CHECKER Do not inline infinite loop at Regular AOT 262#! RUN_PAOC options: "--compiler-regex=Test3::main" 263#! EVENT /Inline,Test3::main,Test3::foo1,.*VIRTUAL,SUCCESS/ 264#! EVENT /Inline,Test3::main,_GLOBAL::foo_inf_loop,.*STATIC,INF_LOOP/ 265#! RUN entry: "Test3::main" 266 267#! CHECKER Do not inline infinite loop at LLVM AOT 268#! RUN_LLVM options: "--compiler-regex='(Test3::main|Test3::foo1|_GLOBAL::foo_inf_loop)' --llvm-dump-before --llvm-dump-after \ 269#! --llvm-pre-opt=0" 270#! READ_FILE "console.out" 271#! INST "LLVM IR module BEFORE LLVM optimizations" 272#! INST_NEXT /define protected.*Test3::main/ 273#! INST_NEXT /call.*_GLOBAL::foo_inf_loop/ 274#! INST "LLVM IR module AFTER LLVM optimizations" 275#! INST_NEXT /define protected.*Test3::main/ 276#! INST_NEXT_NOT "resolve_method" 277#! RUN entry: "Test3::main" 278 279.record Test3 {} 280 281.function i32 Test3.foo1(Test3 a0) { 282 ldai 0 283 return 284} 285 286.function i32 foo_inf_loop(i32 a0) { 287 lda a0 288 jeqz exit 289loop: 290 addi 1 291 sta a0 292 jmp loop 293exit: 294 return 295} 296 297.function i32 Test3.main() { 298 newobj v0, Test3 299 call.virt Test3.foo1, v0 300 jeqz exit 301 sta v1 302 call.short foo_inf_loop, v1 303 ldai 0 304exit: 305 return 306} 307 308#! CHECKER Inline external files in AOT mode 309#! RUN_PAOC options: "--panda-files=../../inline_external.checked/test.abc --paoc-use-cha=true --compiler-regex=Test4.*" 310#! METHOD "Test4::func_A_getConst_static__noinline__" 311#! PASS_AFTER "IrBuilder" 312#! INST /CallStatic.*A::getConst/ 313#! INST_NOT "Constant" 314#! PASS_AFTER "Inline" 315#! INST_NOT /CallStatic.*A::getConst/ 316#! INST "Constant" 317#! METHOD "Test4::func_A_getConst_virtual__noinline__" 318#! PASS_AFTER "IrBuilder" 319#! INST /CallVirtual.*A::getConst/ 320#! INST_NOT "Constant" 321#! PASS_AFTER "Inline" 322#! INST_NOT /CallVirtual.*A::getConst/ 323#! INST "Constant" 324#! METHOD "Test4::func_A_getParam_static__noinline__" 325#! PASS_AFTER "IrBuilder" 326#! INST /CallStatic.*A::getParam/ 327#! PASS_AFTER "Inline" 328#! INST_NOT /CallStatic.*A::getParam/ 329#! METHOD "Test4::func_A_getParam_virtual__noinline__" 330#! PASS_AFTER "IrBuilder" 331#! INST /CallVirtual.*A::getParam/ 332#! PASS_AFTER "Inline" 333#! INST_NOT /CallVirtual.*A::getParam/ 334#! METHOD "Test4::func_A_getVoid_static__noinline__" 335#! PASS_AFTER "IrBuilder" 336#! INST /CallStatic.*A::getVoid/ 337#! PASS_AFTER "Inline" 338#! INST_NOT /CallStatic.*A::getVoid/ 339#! METHOD "Test4::func_A_getVoid_virtual__noinline__" 340#! PASS_AFTER "IrBuilder" 341#! INST /CallVirtual.*A::getVoid/ 342#! PASS_AFTER "Inline" 343#! INST_NOT /CallVirtual.*A::getVoid/ 344#! METHOD "Test4::func_A_getObj_static__noinline__" 345#! PASS_AFTER "IrBuilder" 346#! INST /CallStatic.*A::getObj/ 347#! INST_NOT "LoadObject" 348#! PASS_AFTER "Inline" 349#! INST_NOT /CallStatic.*A::getObj/ 350#! INST "LoadObject" 351#! METHOD "Test4::func_A_getObj_virtual__noinline__" 352#! PASS_AFTER "IrBuilder" 353#! INST /CallVirtual.*A::getObj/ 354#! INST_NOT "LoadObject" 355#! PASS_AFTER "Inline" 356#! INST_NOT /CallVirtual.*A::getObj/ 357#! INST "LoadObject" 358#! METHOD "Test4::func_A_setObj_static__noinline__" 359#! PASS_AFTER "IrBuilder" 360#! INST /CallStatic.*A::setObj/ 361#! INST_NOT "StoreObject" 362#! PASS_AFTER "Inline" 363#! INST_NOT /CallStatic.*A::setObj/ 364#! INST "StoreObject" 365#! METHOD "Test4::func_A_setObj_virtual__noinline__" 366#! PASS_AFTER "IrBuilder" 367#! INST /CallVirtual.*A::setObj/ 368#! INST_NOT "StoreObject" 369#! PASS_AFTER "Inline" 370#! INST_NOT /CallVirtual.*A::setObj/ 371#! INST "StoreObject" 372#! METHOD "Test4::func_A_getObj_wrong_virtual__noinline__" 373#! PASS_AFTER "IrBuilder" 374#! INST /CallVirtual.*A::getObj/ 375#! INST_NOT "LoadObject" 376#! PASS_AFTER "Inline" 377#! INST_NOT /CallVirtual.*A::getObj/ 378#! INST "LoadObject" 379#! METHOD "Test4::func_A_setObj_wrong_virtual__noinline__" 380#! PASS_AFTER "IrBuilder" 381#! INST /CallVirtual.*A::setObj/ 382#! INST_NOT "StoreObject" 383#! PASS_AFTER "Inline" 384#! INST_NOT /CallVirtual.*A::setObj/ 385#! INST "StoreObject" 386#! METHOD "Test4::func_A_setObj_multiple__noinline__" 387#! PASS_AFTER "IrBuilder" 388#! INST /CallStatic.*A::setObj_multiple/ 389#! PASS_AFTER "Inline" 390#! INST_NOT /CallStatic.*A::setObj_multiple/ 391#! METHOD "Test4::func_A_complexMethod__noinline__" 392#! PASS_AFTER "IrBuilder" 393#! INST /CallVirtual.*A::complexMethod/ 394#! PASS_AFTER "Inline" 395#! INST_NOT /CallVirtual.*A::complexMethod/ 396#! METHOD "Test4::func_A_setObj_unknown_target__noinline__" 397#! PASS_AFTER "IrBuilder" 398#! INST /CallStatic.*A::setObj/ 399#! PASS_AFTER "Inline" 400#! INST /CallStatic.*A::setObj/ 401#! RUN options: "--panda-files=../../inline_external.checked/test.abc", entry: "Test4::main" 402 403#! CHECKER Inline external files in LLVM AOT mode 404#! RUN_LLVM options: "--panda-files=../../inline_external.checked/test.abc --paoc-use-cha=true --compiler-regex=Test4.*" 405#! METHOD "Test4::func_A_getConst_static__noinline__" 406#! PASS_AFTER "IrBuilder" 407#! INST /CallStatic.*A::getConst/ 408#! INST_NOT "Constant" 409#! PASS_AFTER "Inline" 410#! INST_NOT /CallStatic.*A::getConst/ 411#! INST "Constant" 412#! METHOD "Test4::func_A_getConst_virtual__noinline__" 413#! PASS_AFTER "IrBuilder" 414#! INST /CallVirtual.*A::getConst/ 415#! INST_NOT "Constant" 416#! PASS_AFTER "Inline" 417#! INST_NOT /CallVirtual.*A::getConst/ 418#! INST "Constant" 419#! METHOD "Test4::func_A_getParam_static__noinline__" 420#! PASS_AFTER "IrBuilder" 421#! INST /CallStatic.*A::getParam/ 422#! PASS_AFTER "Inline" 423#! INST_NOT /CallStatic.*A::getParam/ 424#! METHOD "Test4::func_A_getParam_virtual__noinline__" 425#! PASS_AFTER "IrBuilder" 426#! INST /CallVirtual.*A::getParam/ 427#! PASS_AFTER "Inline" 428#! INST_NOT /CallVirtual.*A::getParam/ 429#! METHOD "Test4::func_A_getVoid_static__noinline__" 430#! PASS_AFTER "IrBuilder" 431#! INST /CallStatic.*A::getVoid/ 432#! PASS_AFTER "Inline" 433#! INST_NOT /CallStatic.*A::getVoid/ 434#! METHOD "Test4::func_A_getVoid_virtual__noinline__" 435#! PASS_AFTER "IrBuilder" 436#! INST /CallVirtual.*A::getVoid/ 437#! PASS_AFTER "Inline" 438#! INST_NOT /CallVirtual.*A::getVoid/ 439#! METHOD "Test4::func_A_getObj_static__noinline__" 440#! PASS_AFTER "IrBuilder" 441#! INST /CallStatic.*A::getObj/ 442#! INST_NOT "LoadObject" 443#! PASS_AFTER "Inline" 444#! INST_NOT /CallStatic.*A::getObj/ 445#! INST "LoadObject" 446#! METHOD "Test4::func_A_getObj_virtual__noinline__" 447#! PASS_AFTER "IrBuilder" 448#! INST /CallVirtual.*A::getObj/ 449#! INST_NOT "LoadObject" 450#! PASS_AFTER "Inline" 451#! INST_NOT /CallVirtual.*A::getObj/ 452#! INST "LoadObject" 453#! METHOD "Test4::func_A_setObj_static__noinline__" 454#! PASS_AFTER "IrBuilder" 455#! INST /CallStatic.*A::setObj/ 456#! INST_NOT "StoreObject" 457#! PASS_AFTER "Inline" 458#! INST_NOT /CallStatic.*A::setObj/ 459#! INST "StoreObject" 460#! METHOD "Test4::func_A_setObj_virtual__noinline__" 461#! PASS_AFTER "IrBuilder" 462#! INST /CallVirtual.*A::setObj/ 463#! INST_NOT "StoreObject" 464#! PASS_AFTER "Inline" 465#! INST_NOT /CallVirtual.*A::setObj/ 466#! INST "StoreObject" 467#! METHOD "Test4::func_A_getObj_wrong_virtual__noinline__" 468#! PASS_AFTER "IrBuilder" 469#! INST /CallVirtual.*A::getObj/ 470#! INST_NOT "LoadObject" 471#! PASS_AFTER "Inline" 472#! INST_NOT /CallVirtual.*A::getObj/ 473#! INST "LoadObject" 474#! METHOD "Test4::func_A_setObj_wrong_virtual__noinline__" 475#! PASS_AFTER "IrBuilder" 476#! INST /CallVirtual.*A::setObj/ 477#! INST_NOT "StoreObject" 478#! PASS_AFTER "Inline" 479#! INST_NOT /CallVirtual.*A::setObj/ 480#! INST "StoreObject" 481#! METHOD "Test4::func_A_setObj_multiple__noinline__" 482#! PASS_AFTER "IrBuilder" 483#! INST /CallStatic.*A::setObj_multiple/ 484#! PASS_AFTER "Inline" 485#! INST_NOT /CallStatic.*A::setObj_multiple/ 486#! METHOD "Test4::func_A_complexMethod__noinline__" 487#! PASS_AFTER "IrBuilder" 488#! INST /CallVirtual.*A::complexMethod/ 489#! PASS_AFTER "Inline" 490#! INST_NOT /CallVirtual.*A::complexMethod/ 491#! METHOD "Test4::func_A_setObj_unknown_target__noinline__" 492#! PASS_AFTER "IrBuilder" 493#! INST /CallStatic.*A::setObj/ 494#! PASS_AFTER "Inline" 495#! INST /CallStatic.*A::setObj/ 496#! RUN options: "--panda-files=../../inline_external.checked/test.abc", entry: "Test4::main" 497 498#! CHECKER CallVirtual for external method is replaced with CallStatic 499#! RUN_PAOC options: "--panda-files=../../inline_external.checked/test.abc --paoc-use-cha=true \ 500#! --compiler-regex=Test4.* --compiler-inlining-max-insts=0 --compiler-inlining-always-inline-bc-size=0" 501#! METHOD "Test4::func_A_complexMethod__noinline__" 502#! PASS_AFTER "IrBuilder" 503#! INST /CallVirtual.*A::complexMethod/ 504#! PASS_AFTER "Inline" 505#! INST /CallStatic.*A::complexMethod/ 506 507#! CHECKER CallVirtual for external method is not replaced with CallStatic if external inlining is disabled 508#! RUN_PAOC options: "--panda-files=../../inline_external.checked/test.abc --paoc-use-cha=true \ 509#! --compiler-regex=Test4.* --compiler-inlining-max-insts=0 \ 510#! --compiler-inline-external-methods=false --compiler-inlining-always-inline-bc-size=0" 511#! METHOD "Test4::func_A_complexMethod__noinline__" 512#! PASS_AFTER "IrBuilder" 513#! INST /CallVirtual.*A::complexMethod/ 514#! PASS_AFTER "Inline" 515#! INST_NOT /CallStatic.*A::complexMethod/ 516#! INST /CallVirtual.*A::complexMethod/ 517 518#! CHECKER Don't inline external files in AOT mode without cha 519#! RUN_PAOC options: "--panda-files=../../inline_external.checked/test.abc --paoc-use-cha=false --compiler-regex=Test4.*" 520#! METHOD "Test4::func_A_getConst_static__noinline__" 521#! PASS_AFTER "IrBuilder" 522#! INST /CallStatic.*A::getConst/ 523#! INST_NOT "Constant" 524#! PASS_AFTER "Inline" 525#! INST /CallStatic.*A::getConst/ 526#! INST_NOT "Constant" 527 528.record A { 529 i32 data <external> 530} 531.record A.data <external> 532.function i32 A.getConst() <external,static> 533.function i32 A.getConst_virt(A a0) <external> 534.function i32 A.getParam(i32 a0) <external,static> 535.function i32 A.getParam_virt(A a0, i32 a1) <external> 536.function void A.getVoid() <external,static> 537.function void A.getVoid_virt(A a0) <external> 538.function i32 A.getObj(A a0) <external,static> 539.function i32 A.getObj_virt(A a0) <external> 540.function void A.setObj(A a0, i32 a1) <external,static> 541.function void A.setObjConst_virt(A a0) <external> 542.function void A.setObj_virt(A a0, i32 a1) <external> 543.function i32 A.getObj_wrong_virt(A a0, A a1) <external> 544.function void A.setObj_wrong_virt(A a0, i32 a1, A a2) <external> 545.function void A.setObj_multiple(A a0, i32 a1, i32 a2) <external,static> 546.function i32 A.complexMethod(A a0) <external> 547 548.record Test4 {} 549 550.function i32 Test4.func_A_getConst_static__noinline__() <static> { 551 call A.getConst 552 return 553} 554 555.function i32 Test4.func_A_getConst_virtual__noinline__() <static> { 556 newobj v0, A 557 call.virt A.getConst_virt, v0 558 return 559} 560 561.function i32 Test4.func_A_getParam_static__noinline__(i32 a0) <static> { 562 call A.getParam, a0 563 return 564} 565 566.function i32 Test4.func_A_getParam_virtual__noinline__(i32 a0) <static> { 567 newobj v0, A 568 call.virt A.getParam_virt, v0, a0 569 return 570} 571 572.function void Test4.func_A_getVoid_static__noinline__() <static> { 573 call A.getVoid 574 return.void 575} 576 577.function void Test4.func_A_getVoid_virtual__noinline__() <static> { 578 newobj v0, A 579 call.virt A.getVoid_virt, v0 580 return.void 581} 582 583.function i32 Test4.func_A_getObj_static__noinline__() <static> { 584 newobj v0, A 585 ldai 0x5 586 stobj v0, A.data 587 call A.getObj, v0 588 return 589} 590 591.function i32 Test4.func_A_getObj_virtual__noinline__() <static> { 592 newobj v0, A 593 ldai 0x6 594 stobj v0, A.data 595 call.virt A.getObj_virt, v0 596 return 597} 598 599.function i32 Test4.func_A_setObj_static__noinline__() <static> { 600 newobj v0, A 601 movi v1, 0x7 602 call A.setObj, v0, v1 603 ldobj v0, A.data 604 return 605} 606 607.function i32 Test4.func_A_setObj_virtual__noinline__() <static> { 608 newobj v0, A 609 movi v1, 0x8 610 call.virt A.setObj_virt, v0, v1 611 ldobj v0, A.data 612 return 613} 614 615.function i32 Test4.func_A_getObj_wrong_virtual__noinline__() <static> { 616 newobj v0, A 617 newobj v1, A 618 ldai 0x9 619 stobj v0, A.data 620 ldai 0x10 621 stobj v1, A.data 622 call.virt A.getObj_wrong_virt, v0, v1 623 return 624} 625 626.function i32 Test4.func_A_setObj_wrong_virtual__noinline__() <static> { 627 newobj v0, A 628 newobj v2, A 629 movi v1, 0x11 630 call.virt A.setObj_wrong_virt, v0, v1, v2 631 ldobj v2, A.data 632 return 633} 634 635.function i32 Test4.func_A_setObjConst_virtual__noinline__() <static> { 636 newobj v0, A 637 call.virt A.setObjConst_virt, v0 638 ldobj v0, A.data 639 return 640} 641 642.function i32 Test4.func_A_setObj_multiple__noinline__() <static> { 643 newobj v0, A 644 movi v1, 42 645 movi v2, 0 646 call A.setObj_multiple, v0, v1, v2 647 ldobj v0, A.data 648 return 649} 650 651.function i32 Test4.func_A_complexMethod__noinline__() <static> { 652 newobj v0, A 653 call.virt A.complexMethod, v0 654 sta v0 655 ldai 42 656 jeq v0, success 657 ldai 1 658 return 659success: 660 ldai 0 661 return 662} 663 664.function i32 Test4.func_A_setObj_unknown_target__noinline__(A a0) <static> { 665 movi v0, 0 666 call A.setObj, a0, v0 667 ldobj a0, A.data 668 return 669} 670 671.function i32 Test4.func_A_setObj_unknown_target_wrapper__noinline__() <static> { 672 newobj v0, A 673 call Test4.func_A_setObj_unknown_target__noinline__, v0 674 return 675} 676 677.function i32 Test4.main() { 678 movi v0, 0x1 679 call Test4.func_A_getConst_static__noinline__ 680 jne v0, error_exit_1 681 movi v0, 0x2 682 call Test4.func_A_getConst_virtual__noinline__ 683 jne v0, error_exit_2 684 movi v0, 0x3 685 call Test4.func_A_getParam_static__noinline__, v0 686 jne v0, error_exit_3 687 movi v0, 0x4 688 call Test4.func_A_getParam_virtual__noinline__, v0 689 jne v0, error_exit_4 690 call Test4.func_A_getVoid_static__noinline__, v0 691 call Test4.func_A_getVoid_virtual__noinline__, v0 692 movi v0, 0x5 693 call Test4.func_A_getObj_static__noinline__ 694 jne v0, error_exit_5 695 movi v0, 0x6 696 call Test4.func_A_getObj_virtual__noinline__ 697 jne v0, error_exit_6 698 movi v0, 0x7 699 call Test4.func_A_setObj_static__noinline__ 700 jne v0, error_exit_7 701 movi v0, 0x8 702 call Test4.func_A_setObj_virtual__noinline__ 703 jne v0, error_exit_8 704 movi v0, 0x9 705 call Test4.func_A_setObjConst_virtual__noinline__ 706 jne v0, error_exit_9 707 movi v0, 0x10 708 call Test4.func_A_getObj_wrong_virtual__noinline__ 709 jne v0, error_exit_10 710 movi v0, 0x11 711 call Test4.func_A_setObj_wrong_virtual__noinline__ 712 jne v0, error_exit_11 713 call Test4.func_A_setObj_multiple__noinline__ 714 jnez error_exit_12 715 call Test4.func_A_complexMethod__noinline__ 716 jnez error_exit_13 717 call Test4.func_A_setObj_unknown_target_wrapper__noinline__ 718 jnez error_exit_14 719 ldai 0x0 720 return 721error_exit_1: 722 ldai 0x1 723 return 724error_exit_2: 725 ldai 0x2 726error_exit_3: 727 ldai 0x3 728 return 729error_exit_4: 730 ldai 0x4 731 return 732error_exit_5: 733 ldai 0x5 734 return 735error_exit_6: 736 ldai 0x6 737 return 738error_exit_7: 739 ldai 0x7 740 return 741error_exit_8: 742 ldai 0x8 743 return 744error_exit_9: 745 ldai 0x9 746 return 747error_exit_10: 748 ldai 0xa 749 return 750error_exit_11: 751 ldai 0xb 752 return 753error_exit_12: 754 ldai 0xc 755 return 756error_exit_13: 757 ldai 0xd 758 return 759error_exit_14: 760 ldai 0xe 761 return 762} 763 764#! CHECKER Inline nested calls in AOT mode 765#! RUN_PAOC options: "--panda-files=../../inline.checked/test.abc --compiler-regex=NestedCalls::main" 766#! EVENT /Inline,NestedCalls::outer,NestedCalls::inner,.*,VIRTUAL,SUCCESS/ 767#! EVENT /Inline,NestedCalls::main,NestedCalls::outer,.*,VIRTUAL,SUCCESS/ 768 769#! CHECKER Inline nested calls in JIT mode 770#! RUN force_jit: true, entry: "NestedCalls::main", options: "--compiler-regex=NestedCalls::main --compiler-no-cha-inlining" 771#! EVENT /Inline,NestedCalls::outer,NestedCalls::inner,.*,VIRTUAL,SUCCESS/ 772#! EVENT /Inline,NestedCalls::main,NestedCalls::outer,.*,VIRTUAL,SUCCESS/ 773.record NestedCalls {} 774.function i32 NestedCalls.outer(NestedCalls a0) { 775 call.virt NestedCalls.inner, a0 776 return 777} 778.function i32 NestedCalls.inner(NestedCalls a0) { 779 ldai 0 780 return 781} 782.function i32 NestedCalls.main() <static> { 783 newobj v0, NestedCalls 784 call.virt NestedCalls.outer, v0 785 return 786} 787 788#! CHECKER Inline final class 789#! RUN force_jit: true, options: "", entry: "Test5::main" 790#! EVENT /Inline,B1::func__noinline__,B1::func,.*VIRTUAL,SUCCESS/ 791#! EVENT_NEXT /Inline,B1::func__noinline__,C1::func,.*VIRTUAL,SUCCESS/ 792#! EVENT_NOT /Inline,B1::func__noinline__,A1::func,.*VIRTUAL,SUCCESS/ 793 794#! CHECKER Inline final class AOT 795#! RUN_PAOC options: "" 796#! EVENT /Inline,B1::func__noinline__,B1::func,.*VIRTUAL,SUCCESS/ 797#! EVENT_NEXT /Inline,B1::func__noinline__,C1::func,.*VIRTUAL,SUCCESS/ 798#! EVENT_NOT /Inline,B1::func__noinline__,A1::func,.*VIRTUAL,SUCCESS/ 799#! RUN options: "", entry: "Test5::main" 800 801.record Test5 {} 802.record A1 {} 803.record B1 <extends=A1, final> {} 804.record C1 <final> {} 805 806.function i32 A1.func(A1 a0) { 807 ldai 1 808 return 809} 810 811.function i32 B1.func(B1 a0) { 812 ldai 2 813 return 814} 815 816.function i32 C1.func(C1 a0) { 817 ldai 3 818 return 819} 820 821.function i32 A1.func__noinline__(A1 a0, C1 a1, A1 a2) { 822 ldai 5 823 return 824} 825 826.function i32 B1.func__noinline__(B1 a0, C1 a1, A1 a2) { 827 call.virt A1.func, a0 828 movi v0, 0x2 829 jne v0, error_exit_1 830 call.virt C1.func, a1 831 movi v0, 0x3 832 jne v0, error_exit_2 833 call.virt A1.func, a2 834 movi v0, 0x1 835 jne v0, error_exit_3 836 ldai 0x0 837 return 838error_exit_1: 839 ldai 0x1 840 return 841error_exit_2: 842 ldai 0x2 843 return 844error_exit_3: 845 ldai 0x3 846 return 847} 848 849.function i32 Test5.main() { 850 newobj v0, A1 851 newobj v1, B1 852 newobj v2, C1 853 854 call.virt A1.func__noinline__, v1, v2, v0 855 return 856} 857