From a9624e0e3be7379ec0df14227268fcbea18f97ac Mon Sep 17 00:00:00 2001 From: Vsevolod Pukhov Date: Tue, 9 Sep 2025 19:04:08 +0300 Subject: [PATCH] Optimize constant builtin types creation Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICX7JU Signed-off-by: Vsevolod Pukhov --- ets2panda/checker/ETSAnalyzer.cpp | 25 ++++++++----------- ets2panda/checker/ETSchecker.h | 3 +++ ets2panda/checker/ets/arithmetic.cpp | 17 ++++++------- ets2panda/checker/ets/object.cpp | 17 +++++++++++++ ets2panda/checker/ets/typeCheckingHelpers.cpp | 2 +- 5 files changed, 39 insertions(+), 25 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 53f045d8b8..716609bc6d 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -3015,9 +3015,7 @@ checker::Type *ETSAnalyzer::Check(ir::BooleanLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - auto type = checker->GlobalETSBooleanBuiltinType()->Clone(GetChecker()); - type->AddTypeFlag(TypeFlag::CONSTANT); - expr->SetTsType(type); + expr->SetTsType(checker->GetConstantBuiltinType(checker->GlobalETSBooleanBuiltinType())); } return expr->TsType(); } @@ -3026,9 +3024,7 @@ checker::Type *ETSAnalyzer::Check(ir::CharLiteral *expr) const { ETSChecker *checker = GetETSChecker(); if (expr->TsType() == nullptr) { - auto type = checker->GlobalCharBuiltinType()->Clone(GetChecker()); - type->AddTypeFlag(TypeFlag::CONSTANT); - expr->SetTsType(type); + expr->SetTsType(checker->GetConstantBuiltinType(checker->GlobalCharBuiltinType())); } return expr->TsType(); } @@ -3091,25 +3087,24 @@ checker::Type *ETSAnalyzer::Check(ir::NumberLiteral *expr) const GetAppropriatePreferredType(expr->PreferredType(), [&](Type *tp) { return checker->CheckIfNumeric(tp); }); preferredType != nullptr && !expr->IsFolded() && CheckIfLiteralValueIsAppropriate(checker, preferredType, expr)) { - type = preferredType->Clone(checker); + type = preferredType; } else if (expr->Number().IsDouble()) { - type = checker->GlobalDoubleBuiltinType()->Clone(checker); + type = checker->GlobalDoubleBuiltinType(); } else if (expr->Number().IsFloat()) { - type = checker->GlobalFloatBuiltinType()->Clone(checker); + type = checker->GlobalFloatBuiltinType(); } else if (expr->Number().IsLong()) { - type = checker->GlobalLongBuiltinType()->Clone(checker); + type = checker->GlobalLongBuiltinType(); } else if (expr->Number().IsInt()) { - type = checker->GlobalIntBuiltinType()->Clone(checker); + type = checker->GlobalIntBuiltinType(); } else if (expr->Number().IsShort()) { - type = checker->GlobalShortBuiltinType()->Clone(checker); + type = checker->GlobalShortBuiltinType(); } else if (expr->Number().IsByte()) { - type = checker->GlobalByteBuiltinType()->Clone(checker); + type = checker->GlobalByteBuiltinType(); } else { return checker->GlobalTypeError(); } - type->AddTypeFlag(TypeFlag::CONSTANT); - return expr->SetTsType(type); + return expr->SetTsType(checker->GetConstantBuiltinType(type)); } checker::Type *ETSAnalyzer::Check(ir::StringLiteral *expr) const diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 81fed860b6..a97ccdc8ff 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -297,6 +297,7 @@ public: [[nodiscard]] Type const *GetApparentType(Type const *type) const; ETSObjectType *GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target); bool HasETSFunctionType(ir::TypeNode *typeAnnotation); + Type *GetConstantBuiltinType(Type *type); void VariableTypeFromInitializer(varbinder::Variable *variable, Type *annotationType, Type *initType); @@ -967,6 +968,7 @@ public: unionAssemblerTypes_.clear(); GetCachedComputedAbstracts()->clear(); functionalInterfaceCache_.clear(); + constantBuiltinTypesCache_.clear(); apparentTypes_.clear(); elementStack_.clear(); overloadSigContainer_.clear(); @@ -1096,6 +1098,7 @@ private: GlobalArraySignatureMap globalArraySignatures_; ArenaSet unionAssemblerTypes_; ComputedAbstracts *cachedComputedAbstracts_ {nullptr}; + std::unordered_map constantBuiltinTypesCache_; FunctionalInterfaceMap functionalInterfaceCache_; TypeMapping apparentTypes_; std::recursive_mutex mtx_; diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 46ea410c02..cc7e14a1bb 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -810,12 +810,11 @@ std::tuple ETSChecker::CheckBinaryOperatorInstanceOf(lexer::Sour } template -static void ConvertNumberLiteralTo(ir::NumberLiteral *lit, Type *toType) +static void ConvertNumberLiteralTo(ETSChecker *checker, ir::NumberLiteral *lit, Type *toType) { auto &number = lit->Number(); number.SetValue(number.GetValueAndCastTo()); - toType->AddTypeFlag(TypeFlag::CONSTANT); - lit->SetTsType(toType); + lit->SetTsType(checker->GetConstantBuiltinType(toType)); } template @@ -836,11 +835,11 @@ static void ConvertIntegerNumberLiteral(ETSChecker *checker, ir::NumberLiteral * ETSObjectType *toType) { if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG)) { - ConvertNumberLiteralTo(lit, checker->GlobalLongBuiltinType()->Clone(checker)); + ConvertNumberLiteralTo(checker, lit, checker->GlobalLongBuiltinType()); } else if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_INT)) { if (!fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) || CheckNumberLiteralValue(checker, lit)) { - ConvertNumberLiteralTo(lit, checker->GlobalIntBuiltinType()->Clone(checker)); + ConvertNumberLiteralTo(checker, lit, checker->GlobalIntBuiltinType()); } } else if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT)) { if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) && @@ -851,7 +850,7 @@ static void ConvertIntegerNumberLiteral(ETSChecker *checker, ir::NumberLiteral * !CheckNumberLiteralValue(checker, lit)) { return; } - ConvertNumberLiteralTo(lit, checker->GlobalShortBuiltinType()->Clone(checker)); + ConvertNumberLiteralTo(checker, lit, checker->GlobalShortBuiltinType()); } else if (toType->HasObjectFlag(ETSObjectFlags::BUILTIN_BYTE)) { if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_LONG) && !CheckNumberLiteralValue(checker, lit)) { @@ -865,7 +864,7 @@ static void ConvertIntegerNumberLiteral(ETSChecker *checker, ir::NumberLiteral * !CheckNumberLiteralValue(checker, lit)) { return; } - ConvertNumberLiteralTo(lit, checker->GlobalByteBuiltinType()->Clone(checker)); + ConvertNumberLiteralTo(checker, lit, checker->GlobalByteBuiltinType()); } } @@ -876,14 +875,14 @@ static void ConvertNumberLiteral(ETSChecker *checker, ir::NumberLiteral *lit, ET if (auto *fromType = lit->TsType()->AsETSObjectType(); !checker->Relation()->IsIdenticalTo(fromType, toType)) { switch (static_cast(toType->ObjectFlags() & ETSObjectFlags::BUILTIN_NUMERIC)) { case ETSObjectFlags::BUILTIN_DOUBLE: - ConvertNumberLiteralTo(lit, checker->GlobalDoubleBuiltinType()->Clone(checker)); + ConvertNumberLiteralTo(checker, lit, checker->GlobalDoubleBuiltinType()); break; case ETSObjectFlags::BUILTIN_FLOAT: if (fromType->HasObjectFlag(ETSObjectFlags::BUILTIN_DOUBLE)) { checker->LogError(diagnostic::INVALID_ASSIGNMNENT, {fromType, toType}, lit->Start()); } else { - ConvertNumberLiteralTo(lit, checker->GlobalFloatBuiltinType()->Clone(checker)); + ConvertNumberLiteralTo(checker, lit, checker->GlobalFloatBuiltinType()); } break; diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index a9e62345ac..8c4e0372be 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -2790,6 +2790,23 @@ Type const *ETSChecker::GetApparentType(Type const *type) const return const_cast(const_cast(this)->GetApparentType(const_cast(type))); } +Type *ETSChecker::GetConstantBuiltinType(Type *type) +{ + ES2PANDA_ASSERT(type->IsETSObjectType() && type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::UNBOXABLE_TYPE)); + + auto &cache = constantBuiltinTypesCache_; + if (auto it = cache.find(type); it != cache.end()) { + auto res = it->second; + ES2PANDA_ASSERT(res->IsConstantType()); + return res; + } + + auto cloned = type->Clone(this); + cloned->AddTypeFlag(TypeFlag::CONSTANT); + cache.insert({type, cloned}); + return cloned; +} + ETSObjectType *ETSChecker::GetClosestCommonAncestor(ETSObjectType *source, ETSObjectType *target) { if (source->AsETSObjectType()->GetDeclNode() == target->AsETSObjectType()->GetDeclNode()) { diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 5ea56002c7..93ab545c3a 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -446,7 +446,7 @@ Type *ETSChecker::GetNonConstantType(Type *type) if (!type->IsETSPrimitiveType()) { if (type->IsETSObjectType() && type->AsETSObjectType()->IsBoxedPrimitive()) { - type->RemoveTypeFlag(TypeFlag::CONSTANT); + return MaybeBoxType(MaybeUnboxType(type)); } return type; } -- Gitee