14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_COMPILER_TS_INLINE_LOWERING_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_TS_INLINE_LOWERING_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/argument_accessor.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecode_circuit_builder.h" 214514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecode_info_collector.h" 224514f5e3Sopenharmony_ci#include "ecmascript/compiler/pass_manager.h" 234514f5e3Sopenharmony_ci#include "ecmascript/compiler/type_info_accessors.h" 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 264514f5e3Sopenharmony_ciclass CircuitRootScope { 274514f5e3Sopenharmony_cipublic: 284514f5e3Sopenharmony_ci explicit CircuitRootScope(Circuit *circuit) 294514f5e3Sopenharmony_ci : circuit_(circuit), root_(circuit->GetRoot()) 304514f5e3Sopenharmony_ci { 314514f5e3Sopenharmony_ci } 324514f5e3Sopenharmony_ci 334514f5e3Sopenharmony_ci ~CircuitRootScope() 344514f5e3Sopenharmony_ci { 354514f5e3Sopenharmony_ci circuit_->SetRoot(root_); 364514f5e3Sopenharmony_ci } 374514f5e3Sopenharmony_ci 384514f5e3Sopenharmony_ciprivate: 394514f5e3Sopenharmony_ci Circuit *circuit_ {nullptr}; 404514f5e3Sopenharmony_ci GateRef root_ { 0 }; 414514f5e3Sopenharmony_ci}; 424514f5e3Sopenharmony_ci 434514f5e3Sopenharmony_ciclass TSInlineLowering { 444514f5e3Sopenharmony_cipublic: 454514f5e3Sopenharmony_ci static constexpr size_t MAX_INLINE_CALL_ALLOWED = 6; 464514f5e3Sopenharmony_ci TSInlineLowering(Circuit *circuit, PassContext *ctx, bool enableLog, const std::string &name, 474514f5e3Sopenharmony_ci NativeAreaAllocator *nativeAreaAllocator, PassOptions *options, uint32_t methodOffset, 484514f5e3Sopenharmony_ci CallMethodFlagMap *callMethodFlagMap) 494514f5e3Sopenharmony_ci : circuit_(circuit), 504514f5e3Sopenharmony_ci compilationEnv_(ctx->GetCompilationEnv()), 514514f5e3Sopenharmony_ci acc_(circuit), 524514f5e3Sopenharmony_ci glue_(acc_.GetGlueFromArgList()), 534514f5e3Sopenharmony_ci builder_(circuit, ctx->GetCompilerConfig()), 544514f5e3Sopenharmony_ci ptManager_(ctx->GetPTManager()), 554514f5e3Sopenharmony_ci ctx_(ctx), 564514f5e3Sopenharmony_ci passOptions_(options), 574514f5e3Sopenharmony_ci enableLog_(enableLog), 584514f5e3Sopenharmony_ci methodName_(name), 594514f5e3Sopenharmony_ci enableTypeLowering_(ctx->GetCompilationEnv()->GetJSOptions().IsEnableTypeLowering()), 604514f5e3Sopenharmony_ci traceInline_(ctx->GetCompilationEnv()->GetJSOptions().GetTraceInline()), 614514f5e3Sopenharmony_ci maxInlineBytecodesCount_(ctx->GetCompilationEnv()->GetJSOptions().GetMaxInlineBytecodes()), 624514f5e3Sopenharmony_ci nativeAreaAllocator_(nativeAreaAllocator), 634514f5e3Sopenharmony_ci noCheck_(ctx->GetCompilationEnv()->GetJSOptions().IsCompilerNoCheck()), 644514f5e3Sopenharmony_ci chunk_(circuit->chunk()), 654514f5e3Sopenharmony_ci inlinedCallMap_(circuit->chunk()), 664514f5e3Sopenharmony_ci argAcc_(circuit), 674514f5e3Sopenharmony_ci initMethodOffset_(methodOffset), 684514f5e3Sopenharmony_ci callMethodFlagMap_(callMethodFlagMap) {} 694514f5e3Sopenharmony_ci 704514f5e3Sopenharmony_ci ~TSInlineLowering() = default; 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_ci void RunTSInlineLowering(); 734514f5e3Sopenharmony_ci 744514f5e3Sopenharmony_ciprivate: 754514f5e3Sopenharmony_ci bool IsLogEnabled() const 764514f5e3Sopenharmony_ci { 774514f5e3Sopenharmony_ci return enableLog_; 784514f5e3Sopenharmony_ci } 794514f5e3Sopenharmony_ci 804514f5e3Sopenharmony_ci const std::string& GetMethodName() const 814514f5e3Sopenharmony_ci { 824514f5e3Sopenharmony_ci return methodName_; 834514f5e3Sopenharmony_ci } 844514f5e3Sopenharmony_ci 854514f5e3Sopenharmony_ci bool IsSmallMethod(size_t bcSize) const 864514f5e3Sopenharmony_ci { 874514f5e3Sopenharmony_ci return bcSize <= maxInlineBytecodesCount_; 884514f5e3Sopenharmony_ci } 894514f5e3Sopenharmony_ci 904514f5e3Sopenharmony_ci bool IsInlineCountsOverflow(size_t inlineCount) const 914514f5e3Sopenharmony_ci { 924514f5e3Sopenharmony_ci return inlineCount >= MAX_INLINE_CALL_ALLOWED; 934514f5e3Sopenharmony_ci } 944514f5e3Sopenharmony_ci 954514f5e3Sopenharmony_ci void UpdateInlineCounts(GateRef frameArgs, size_t inlineCallCounts) 964514f5e3Sopenharmony_ci { 974514f5e3Sopenharmony_ci inlinedCallMap_[frameArgs] = ++inlineCallCounts; 984514f5e3Sopenharmony_ci } 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_ci bool IsCallSetter(CallKind kind) const 1014514f5e3Sopenharmony_ci { 1024514f5e3Sopenharmony_ci return kind == CallKind::CALL_SETTER; 1034514f5e3Sopenharmony_ci } 1044514f5e3Sopenharmony_ci 1054514f5e3Sopenharmony_ci void CollectInlineInfo(); 1064514f5e3Sopenharmony_ci void GetInlinedMethodId(GateRef gate); 1074514f5e3Sopenharmony_ci void CandidateInlineCall(GateRef gate, ChunkQueue<InlineTypeInfoAccessor> &workList); 1084514f5e3Sopenharmony_ci void TryInline(InlineTypeInfoAccessor &info, ChunkQueue<InlineTypeInfoAccessor> &workList); 1094514f5e3Sopenharmony_ci bool FilterInlinedMethod(MethodLiteral* method, std::vector<const uint8_t*> pcOffsets); 1104514f5e3Sopenharmony_ci bool FilterCallInTryCatch(GateRef gate); 1114514f5e3Sopenharmony_ci void InlineCall( 1124514f5e3Sopenharmony_ci MethodInfo &methodInfo, MethodPcInfo &methodPCInfo, MethodLiteral *method, InlineTypeInfoAccessor &info); 1134514f5e3Sopenharmony_ci void ReplaceCallInput(InlineTypeInfoAccessor &info, GateRef glue, MethodLiteral *method); 1144514f5e3Sopenharmony_ci void ReplaceEntryGate(GateRef callGate, GateRef callerFunc, GateRef inlineFunc, GateRef glue); 1154514f5e3Sopenharmony_ci void ReplaceReturnGate(GateRef callGate); 1164514f5e3Sopenharmony_ci void ReplaceHirAndDeleteState(GateRef gate, GateRef state, GateRef depend, GateRef value); 1174514f5e3Sopenharmony_ci GateRef MergeAllReturn(const std::vector<GateRef> &returnVector, GateRef &state, GateRef &depend); 1184514f5e3Sopenharmony_ci bool CheckParameter(GateRef gate, InlineTypeInfoAccessor &info, MethodLiteral* method); 1194514f5e3Sopenharmony_ci void LowerToInlineCall(InlineTypeInfoAccessor &info, const std::vector<GateRef> &args, MethodLiteral* method); 1204514f5e3Sopenharmony_ci void RemoveRoot(); 1214514f5e3Sopenharmony_ci void BuildFrameStateChain(InlineTypeInfoAccessor &info, BytecodeCircuitBuilder &builder); 1224514f5e3Sopenharmony_ci GateRef TraceInlineFunction(GateRef glue, GateRef depend, std::vector<GateRef> &args, GateRef callGate); 1234514f5e3Sopenharmony_ci void InlineFuncCheck(const InlineTypeInfoAccessor &info); 1244514f5e3Sopenharmony_ci void SupplementType(GateRef callGate, GateRef targetGate); 1254514f5e3Sopenharmony_ci void UpdateWorkList(ChunkQueue<InlineTypeInfoAccessor> &workList); 1264514f5e3Sopenharmony_ci size_t GetOrInitialInlineCounts(GateRef frameArgs); 1274514f5e3Sopenharmony_ci bool IsRecursiveFunc(InlineTypeInfoAccessor &info, size_t calleeMethodOffset); 1284514f5e3Sopenharmony_ci void CandidateAccessor(GateRef gate, ChunkQueue<InlineTypeInfoAccessor> &workList, CallKind kind); 1294514f5e3Sopenharmony_ci void CandidateNormalCall(GateRef gate, ChunkQueue<InlineTypeInfoAccessor> &workList, CallKind kind); 1304514f5e3Sopenharmony_ci void InlineAccessorCheck(const InlineTypeInfoAccessor &info); 1314514f5e3Sopenharmony_ci void InlineAccessorCheckInJIT(const InlineTypeInfoAccessor &info); 1324514f5e3Sopenharmony_ci void InlineCheck(InlineTypeInfoAccessor &info); 1334514f5e3Sopenharmony_ci GateRef GetAccessorReceiver(GateRef gate); 1344514f5e3Sopenharmony_ci GateRef GetFrameArgs(InlineTypeInfoAccessor &info); 1354514f5e3Sopenharmony_ci void ReplaceAccessorInput(InlineTypeInfoAccessor &info, GateRef glue, MethodLiteral *method); 1364514f5e3Sopenharmony_ci void ReplaceInput(InlineTypeInfoAccessor &info, GateRef glue, MethodLiteral *method); 1374514f5e3Sopenharmony_ci GateRef BuildAccessor(InlineTypeInfoAccessor &info); 1384514f5e3Sopenharmony_ci GateRef GetCallSetterValue(GateRef gate); 1394514f5e3Sopenharmony_ci GateRef GetFrameState(InlineTypeInfoAccessor &info); 1404514f5e3Sopenharmony_ci void SetInitCallTargetAndConstPoolId(InlineTypeInfoAccessor &info); 1414514f5e3Sopenharmony_ci uint32_t GetAccessorConstpoolId(InlineTypeInfoAccessor &info); 1424514f5e3Sopenharmony_ci bool CalleePFIProcess(uint32_t methodOffset); 1434514f5e3Sopenharmony_ci void UpdateCallMethodFlagMap(uint32_t methodOffset, const MethodLiteral *method); 1444514f5e3Sopenharmony_ci 1454514f5e3Sopenharmony_ci Circuit *circuit_ {nullptr}; 1464514f5e3Sopenharmony_ci CompilationEnv *compilationEnv_ {nullptr}; 1474514f5e3Sopenharmony_ci GateAccessor acc_; 1484514f5e3Sopenharmony_ci GateRef glue_; 1494514f5e3Sopenharmony_ci CircuitBuilder builder_; 1504514f5e3Sopenharmony_ci PGOTypeManager *ptManager_ {nullptr}; 1514514f5e3Sopenharmony_ci PassContext *ctx_ {nullptr}; 1524514f5e3Sopenharmony_ci PassOptions *passOptions_ {nullptr}; 1534514f5e3Sopenharmony_ci bool enableLog_ {false}; 1544514f5e3Sopenharmony_ci std::string methodName_; 1554514f5e3Sopenharmony_ci bool enableTypeLowering_ {false}; 1564514f5e3Sopenharmony_ci bool inlineSuccess_ {false}; 1574514f5e3Sopenharmony_ci bool traceInline_ {false}; 1584514f5e3Sopenharmony_ci size_t maxInlineBytecodesCount_ {0}; 1594514f5e3Sopenharmony_ci NativeAreaAllocator *nativeAreaAllocator_ {nullptr}; 1604514f5e3Sopenharmony_ci bool noCheck_ {false}; 1614514f5e3Sopenharmony_ci Chunk* chunk_ {nullptr}; 1624514f5e3Sopenharmony_ci ChunkMap<GateRef, size_t> inlinedCallMap_; 1634514f5e3Sopenharmony_ci size_t lastCallId_ {0}; 1644514f5e3Sopenharmony_ci ArgumentAccessor argAcc_; 1654514f5e3Sopenharmony_ci uint32_t initMethodOffset_ {0}; 1664514f5e3Sopenharmony_ci uint32_t initConstantPoolId_ {0}; 1674514f5e3Sopenharmony_ci GateRef initCallTarget_ {Circuit::NullGate()}; 1684514f5e3Sopenharmony_ci CallMethodFlagMap *callMethodFlagMap_; 1694514f5e3Sopenharmony_ci}; 1704514f5e3Sopenharmony_ci} // panda::ecmascript::kungfu 1714514f5e3Sopenharmony_ci#endif // ECMASCRIPT_COMPILER_TS_INLINE_LOWERING_H 172