From 5567aca6bc0b539648be880d8381cb867832bdb4 Mon Sep 17 00:00:00 2001 From: shawn_hu_ls Date: Sat, 25 Mar 2023 23:03:05 +0800 Subject: [PATCH] Type Extractor: Remove redundant local variable type bindings Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I6QA3X?from=project-issue Signed-off-by: shawn_hu_ls --- es2panda/compiler/base/lexenv.cpp | 24 +++++++------- es2panda/compiler/core/pandagen.cpp | 30 +++++++++--------- es2panda/compiler/core/pandagen.h | 12 +++++++ .../testcases_with_assert/test-function.ts | 31 +++++++++++++++++++ 4 files changed, 71 insertions(+), 26 deletions(-) create mode 100644 es2panda/test/type_extractor/testcases_with_assert/test-function.ts diff --git a/es2panda/compiler/base/lexenv.cpp b/es2panda/compiler/base/lexenv.cpp index f199cf3b00..cf3451d569 100644 --- a/es2panda/compiler/base/lexenv.cpp +++ b/es2panda/compiler/base/lexenv.cpp @@ -114,19 +114,21 @@ static void ExpandStoreNormalVar(PandaGen *pg, const ir::AstNode *node, const bi } auto context = pg->Context(); - if (context->IsTypeExtractorEnabled()) { - auto typeIndex = context->TypeRecorder()->GetVariableTypeIndex(local); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - pg->StoreAccumulatorWithType(node, typeIndex, localReg); - DCOUT << "[LOG]Local vreg in variable has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; + if (context->IsTypeExtractorEnabled() && pg->TypedVars().count(local) == 0U) { + auto fn = [&pg, &node, &local, &localReg](auto typeIndex, const auto &tag) { + if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { + pg->StoreAccumulatorWithType(node, typeIndex, localReg); + pg->TypedVars().emplace(local); + DCOUT << "[LOG]Local vreg in " << tag << " has type index: " << local->Name() << + "@" << local << " | " << typeIndex << std::endl; + return true; + } + return false; + }; + if (fn(context->TypeRecorder()->GetVariableTypeIndex(local), "variable")) { return; } - typeIndex = context->TypeRecorder()->GetNodeTypeIndex(node); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - pg->StoreAccumulatorWithType(node, typeIndex, localReg); - DCOUT << "[LOG]Local vreg in declnode has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; + if (fn(context->TypeRecorder()->GetNodeTypeIndex(node), "declnode")) { return; } DCOUT << "[WARNING]Local vreg lose type index: " << local->Name() << "@" << local << std::endl; diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 23fab34a87..567ddb418b 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -16,9 +16,6 @@ #include "pandagen.h" #include -#include -#include -#include #include #include #include @@ -45,6 +42,9 @@ #include #include #include +#include +#include +#include namespace panda::es2panda::compiler { @@ -1835,20 +1835,20 @@ void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t RegScope rs(this); VReg value = AllocReg(); if (context_->IsTypeExtractorEnabled()) { - auto typeIndex = context_->TypeRecorder()->GetVariableTypeIndex(local); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - StoreAccumulatorWithType(node, typeIndex, value); - DCOUT << "[LOG]Lexical vreg in variable has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; - StoreLexicalVar(node, level, slot, value); + auto fn = [&node, &level, &slot, &local, &value, this](auto typeIndex, const auto &tag) { + if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { + StoreAccumulatorWithType(node, typeIndex, value); + DCOUT << "[LOG]Lexical vreg in " << tag << " has type index: " << local->Name() << + "@" << local << " | " << typeIndex << std::endl; + StoreLexicalVar(node, level, slot, value); + return true; + } + return false; + }; + if (fn(context_->TypeRecorder()->GetVariableTypeIndex(local), "variable")) { return; } - typeIndex = context_->TypeRecorder()->GetNodeTypeIndex(node); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - StoreAccumulatorWithType(node, typeIndex, value); - DCOUT << "[LOG]Lexical vreg in declnode has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; - StoreLexicalVar(node, level, slot, value); + if (fn(context_->TypeRecorder()->GetNodeTypeIndex(node), "declnode")) { return; } DCOUT << "[WARNING]Lexical vreg lose type index: " << local->Name() << "@" << local << std::endl; diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index ff98829d14..8cf666701e 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -86,6 +86,7 @@ public: rootNode_(scope->Node()), insns_(allocator_->Adapter()), typedInsns_(allocator_->Adapter()), + typedVars_(allocator_->Adapter()), catchList_(allocator_->Adapter()), strings_(allocator_->Adapter()), buffStorage_(allocator_->Adapter()), @@ -156,6 +157,16 @@ public: return typedInsns_; } + ArenaUnorderedSet &TypedVars() + { + return typedVars_; + } + + const ArenaUnorderedSet &TypedVars() const + { + return typedVars_; + } + std::pair &TypedFunc() { return typedFunc_; @@ -501,6 +512,7 @@ private: const ir::AstNode *rootNode_; ArenaList insns_; ArenaMap typedInsns_; + ArenaUnorderedSet typedVars_; std::pair typedFunc_ {}; ArenaVector catchList_; ArenaSet strings_; diff --git a/es2panda/test/type_extractor/testcases_with_assert/test-function.ts b/es2panda/test/type_extractor/testcases_with_assert/test-function.ts new file mode 100644 index 0000000000..abf3ff9e0b --- /dev/null +++ b/es2panda/test/type_extractor/testcases_with_assert/test-function.ts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 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. + */ + + +declare function AssertType(value:any, type:string):void; +{ + function p(num : number) : any { + if (num == 1) { + return 1; + } + return 2 + p(num - 1); + } + + let a : number = 1; + for (let i : number = 0 ; i < 10; i++) { + AssertType(a, "any"); + a = a + p(10); + } +} -- Gitee