From 5906fe93abe76a1565c7c9e021daeedbe3d7d199 Mon Sep 17 00:00:00 2001 From: "Sergey V. Ignatov" Date: Mon, 10 Apr 2023 16:15:59 +0300 Subject: [PATCH] [Compiler] Support LoadObjFromConst and FunctionImmediate in VN and LICM Signed-off-by: Sergey V. Ignatov --- .../optimizer/optimizations/ecma_inlining.cpp | 9 +++- .../optimizations/expand_intrinsics.cpp | 7 ++- runtime/builtins/builtins_runtime_testing.cpp | 4 +- tests/checked/CMakeLists.txt | 1 + tests/checked/functionimmediate_check.js | 49 +++++++++++++++++++ 5 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 tests/checked/functionimmediate_check.js diff --git a/compiler/optimizer/optimizations/ecma_inlining.cpp b/compiler/optimizer/optimizations/ecma_inlining.cpp index fe280f129..071666464 100644 --- a/compiler/optimizer/optimizations/ecma_inlining.cpp +++ b/compiler/optimizer/optimizations/ecma_inlining.cpp @@ -143,7 +143,12 @@ void EcmaInlining::BuildGuard(CallInst *call_inst) deopt_inst->SetInput(1, call_inst->GetSaveState()); deopt_inst->SetDeoptimizeType(DeoptimizeType::INLINE_DYN); - call_inst->InsertBefore(load_function); + auto save_state = call_inst->GetSaveState(); + ASSERT(save_state); + save_state->InsertBefore(load_function); + save_state->AppendInput(load_function); + VirtualRegister vreg {VirtualRegister::BRIDGE, VRegType::VREG}; + save_state->SetVirtualRegister(save_state->GetInputsCount() - 1, vreg); call_inst->InsertBefore(cmp_inst); call_inst->InsertBefore(deopt_inst); } @@ -215,4 +220,4 @@ bool EcmaInlining::TryInline(CallInst *call_inst) return true; } -} // namespace panda::compiler::ecmascript \ No newline at end of file +} // namespace panda::compiler::ecmascript diff --git a/compiler/optimizer/optimizations/expand_intrinsics.cpp b/compiler/optimizer/optimizations/expand_intrinsics.cpp index f8a5e4e0d..e628a7f11 100644 --- a/compiler/optimizer/optimizations/expand_intrinsics.cpp +++ b/compiler/optimizer/optimizations/expand_intrinsics.cpp @@ -337,7 +337,12 @@ void ExpandIntrinsics::BuildGuard(Inst *inst, uintptr_t target) deopt_inst->SetInput(1, inst->GetSaveState()); deopt_inst->SetDeoptimizeType(DeoptimizeType::INLINE_DYN); - inst->InsertBefore(load_function); + auto save_state = inst->GetSaveState(); + ASSERT(save_state); + save_state->InsertBefore(load_function); + save_state->AppendInput(load_function); + VirtualRegister vreg {VirtualRegister::BRIDGE, VRegType::VREG}; + save_state->SetVirtualRegister(save_state->GetInputsCount() - 1, vreg); inst->InsertBefore(cmp_inst); inst->InsertBefore(deopt_inst); } diff --git a/runtime/builtins/builtins_runtime_testing.cpp b/runtime/builtins/builtins_runtime_testing.cpp index 52add75ff..0d10a6f08 100644 --- a/runtime/builtins/builtins_runtime_testing.cpp +++ b/runtime/builtins/builtins_runtime_testing.cpp @@ -135,7 +135,9 @@ JSTaggedValue BuiltinsRuntimeTesting::OptimizeFunctionOnNextCall(EcmaRuntimeCall } } auto *compiler = Runtime::GetCurrent()->GetPandaVM()->GetCompiler(); - ASSERT(!js_method->HasCompiledCode()); + if (js_method->HasCompiledCode()) { + return JSTaggedValue::Undefined(); + } bool saved_async_flag = compiler->IsNoAsyncJit(); compiler->SetNoAsyncJit(!is_async); compiler->CompileMethod(js_method, 0, false, arg_tagged_0.GetTaggedValue()); diff --git a/tests/checked/CMakeLists.txt b/tests/checked/CMakeLists.txt index 18196bd63..b2ca166ff 100644 --- a/tests/checked/CMakeLists.txt +++ b/tests/checked/CMakeLists.txt @@ -112,6 +112,7 @@ if (NOT PANDA_TARGET_ARM32) panda_add_checked_test_ecma(FILE ${CMAKE_CURRENT_SOURCE_DIR}/peephole_negoverflowandzerocheck.js SUPPORT_RELEASE true) panda_add_checked_test_ecma(FILE ${CMAKE_CURRENT_SOURCE_DIR}/ldlex.js SUPPORT_RELEASE true) panda_add_checked_test_ecma(FILE ${CMAKE_CURRENT_SOURCE_DIR}/typeof.js SUPPORT_RELEASE true) + panda_add_checked_test_ecma(FILE ${CMAKE_CURRENT_SOURCE_DIR}/functionimmediate_check.js SUPPORT_RELEASE true) # there is flaky bug when turning on TSAN if (NOT PANDA_ENABLE_THREAD_SANITIZER) panda_add_checked_test_ecma(FILE ${CMAKE_CURRENT_SOURCE_DIR}/acc_after_deopt.js SUPPORT_RELEASE true) diff --git a/tests/checked/functionimmediate_check.js b/tests/checked/functionimmediate_check.js new file mode 100644 index 000000000..02b7cc401 --- /dev/null +++ b/tests/checked/functionimmediate_check.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! CHECKER Checking LICM for FunctionImmediate. +//! RUN options: "--compiler-enable-jit=true --compiler-hotness-threshold=0 --compiler-profiling-threshold=0 --gc-type=g1-gc --compiler-regex _GLOBAL::test", entry: "_GLOBAL::func_main_0" +//! EVENT /Compilation,_GLOBAL::test,.*,COMPILED/ +//! EVENT /Inline,_GLOBAL::test,_GLOBAL::bar,.*,SUCCESS/ +//! EVENT_NOT /Deoptimization,_GLOBAL::test/ +//! METHOD "_GLOBAL::func_test_4" +//! PASS_AFTER "ChecksElimination" +//! INST_COUNT "FunctionImmediate",1 +//! IN_BLOCK "loop 1" +//! INST "FunctionImmediate" +//! PASS_AFTER "LICM" +//! INST_COUNT "FunctionImmediate",1 +//! IN_BLOCK "prehead" +//! INST "FunctionImmediate" + +function bar() { return 1; } +function __noinline__add2() { return 2; } +function __noinline__add3() { return 3; } + +function test () { + var sum = 0; + for (var i = 0; i < 20; i++) { + sum += __noinline__add2(); + sum += bar(); + let gc = startGC("full"); + waitForFinishGC(gc); + sum += __noinline__add3(); + } +} + +RuntimeTesting.PrepareFunctionForOptimization(test); +test(); +RuntimeTesting.OptimizeFunctionOnNextCall(test); +test(); -- Gitee