14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 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_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <algorithm> 204514f5e3Sopenharmony_ci#include <tuple> 214514f5e3Sopenharmony_ci#include <utility> 224514f5e3Sopenharmony_ci#include <vector> 234514f5e3Sopenharmony_ci 244514f5e3Sopenharmony_ci#include "ecmascript/compiler/argument_accessor.h" 254514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecode_info_collector.h" 264514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecodes.h" 274514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit.h" 284514f5e3Sopenharmony_ci#include "ecmascript/compiler/ecma_opcode_des.h" 294514f5e3Sopenharmony_ci#include "ecmascript/compiler/frame_states.h" 304514f5e3Sopenharmony_ci#include "ecmascript/compiler/pgo_type/pgo_type_recorder.h" 314514f5e3Sopenharmony_ci#include "ecmascript/jit/jit_profiler.h" 324514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/js_pandafile.h" 334514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/method_literal.h" 344514f5e3Sopenharmony_ci#include "libpandafile/index_accessor.h" 354514f5e3Sopenharmony_ci 364514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 374514f5e3Sopenharmony_cistruct ExceptionItem { 384514f5e3Sopenharmony_ci uint8_t* startPc; 394514f5e3Sopenharmony_ci uint8_t* endPc; 404514f5e3Sopenharmony_ci std::vector<uint8_t*> catches; 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_ci ExceptionItem(uint8_t* startPc, uint8_t* endPc, std::vector<uint8_t*> catches) 434514f5e3Sopenharmony_ci : startPc(startPc), endPc(endPc), catches(catches) {} 444514f5e3Sopenharmony_ci}; 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_ciusing ExceptionInfo = std::vector<ExceptionItem>; 474514f5e3Sopenharmony_ci 484514f5e3Sopenharmony_ciclass RegionItem { 494514f5e3Sopenharmony_cipublic: 504514f5e3Sopenharmony_ci static constexpr uint32_t INVALID_BC_INDEX = static_cast<uint32_t>(-1); 514514f5e3Sopenharmony_ci bool operator<(const RegionItem &rhs) const 524514f5e3Sopenharmony_ci { 534514f5e3Sopenharmony_ci return this->startBcIndex_ < rhs.startBcIndex_; 544514f5e3Sopenharmony_ci } 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_ci bool operator>(const RegionItem &rhs) const 574514f5e3Sopenharmony_ci { 584514f5e3Sopenharmony_ci return this->startBcIndex_ > rhs.startBcIndex_; 594514f5e3Sopenharmony_ci } 604514f5e3Sopenharmony_ci 614514f5e3Sopenharmony_ci bool operator==(const RegionItem &rhs) const 624514f5e3Sopenharmony_ci { 634514f5e3Sopenharmony_ci return this->startBcIndex_ == rhs.startBcIndex_; 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ci 664514f5e3Sopenharmony_ci RegionItem(uint32_t startBcIndex, bool isHeadBlock) 674514f5e3Sopenharmony_ci : startBcIndex_(startBcIndex), isHeadBlock_(isHeadBlock) {} 684514f5e3Sopenharmony_ci 694514f5e3Sopenharmony_ci uint32_t GetStartBcIndex() const 704514f5e3Sopenharmony_ci { 714514f5e3Sopenharmony_ci return startBcIndex_; 724514f5e3Sopenharmony_ci } 734514f5e3Sopenharmony_ci 744514f5e3Sopenharmony_ci uint32_t IsHeadBlock() const 754514f5e3Sopenharmony_ci { 764514f5e3Sopenharmony_ci return isHeadBlock_; 774514f5e3Sopenharmony_ci } 784514f5e3Sopenharmony_ciprivate: 794514f5e3Sopenharmony_ci uint32_t startBcIndex_ { INVALID_BC_INDEX }; 804514f5e3Sopenharmony_ci bool isHeadBlock_ { false }; 814514f5e3Sopenharmony_ci friend class RegionsInfo; 824514f5e3Sopenharmony_ci}; 834514f5e3Sopenharmony_ci 844514f5e3Sopenharmony_cistruct BytecodeSplitItem { 854514f5e3Sopenharmony_ci BytecodeSplitItem(uint32_t start, uint32_t pred) 864514f5e3Sopenharmony_ci : startBcIndex(start), predBcIndex(pred) {} 874514f5e3Sopenharmony_ci uint32_t startBcIndex { RegionItem::INVALID_BC_INDEX }; 884514f5e3Sopenharmony_ci uint32_t predBcIndex { RegionItem::INVALID_BC_INDEX }; 894514f5e3Sopenharmony_ci}; 904514f5e3Sopenharmony_ci 914514f5e3Sopenharmony_ciclass RegionsInfo { 924514f5e3Sopenharmony_cipublic: 934514f5e3Sopenharmony_ci void InsertJump(uint32_t bcIndex, uint32_t predBcIndex, bool isJumpImm) 944514f5e3Sopenharmony_ci { 954514f5e3Sopenharmony_ci InsertBlockItem(bcIndex, false); 964514f5e3Sopenharmony_ci auto fallThrogth = bcIndex - 1; // 1: fall through 974514f5e3Sopenharmony_ci // isJumpImm will not generate fall through 984514f5e3Sopenharmony_ci if (isJumpImm || fallThrogth != predBcIndex) { 994514f5e3Sopenharmony_ci InsertSplitItem(bcIndex, predBcIndex); 1004514f5e3Sopenharmony_ci } 1014514f5e3Sopenharmony_ci } 1024514f5e3Sopenharmony_ci 1034514f5e3Sopenharmony_ci void InsertHead(uint32_t bcIndex) 1044514f5e3Sopenharmony_ci { 1054514f5e3Sopenharmony_ci InsertBlockItem(bcIndex, true); 1064514f5e3Sopenharmony_ci } 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_ci void InsertSplit(uint32_t bcIndex) 1094514f5e3Sopenharmony_ci { 1104514f5e3Sopenharmony_ci InsertBlockItem(bcIndex, false); 1114514f5e3Sopenharmony_ci } 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_ci size_t FindBBIndexByBcIndex(uint32_t bcIndex) const 1144514f5e3Sopenharmony_ci { 1154514f5e3Sopenharmony_ci auto findFunc = [] (uint32_t value, const RegionItem &item) { 1164514f5e3Sopenharmony_ci return value < item.startBcIndex_; 1174514f5e3Sopenharmony_ci }; 1184514f5e3Sopenharmony_ci const auto &it = std::upper_bound(blockItems_.begin(), 1194514f5e3Sopenharmony_ci blockItems_.end(), bcIndex, findFunc); 1204514f5e3Sopenharmony_ci if (it == blockItems_.end()) { 1214514f5e3Sopenharmony_ci return blockItems_.size(); 1224514f5e3Sopenharmony_ci } 1234514f5e3Sopenharmony_ci // blockItems_[0]'s value is 0, bcIndex must be: bcIndex > blockItems_.begin() 1244514f5e3Sopenharmony_ci return std::distance(blockItems_.begin(), it); 1254514f5e3Sopenharmony_ci } 1264514f5e3Sopenharmony_ci 1274514f5e3Sopenharmony_ci const std::vector<BytecodeSplitItem> &GetSplitItems() const 1284514f5e3Sopenharmony_ci { 1294514f5e3Sopenharmony_ci return splitItems_; 1304514f5e3Sopenharmony_ci } 1314514f5e3Sopenharmony_ci 1324514f5e3Sopenharmony_ci const std::set<RegionItem> &GetBlockItems() const 1334514f5e3Sopenharmony_ci { 1344514f5e3Sopenharmony_ci return blockItems_; 1354514f5e3Sopenharmony_ci } 1364514f5e3Sopenharmony_ciprivate: 1374514f5e3Sopenharmony_ci void InsertBlockItem(uint32_t bcIndex, bool isHeadBlock) 1384514f5e3Sopenharmony_ci { 1394514f5e3Sopenharmony_ci auto result = blockItems_.insert(RegionItem { bcIndex, isHeadBlock }); 1404514f5e3Sopenharmony_ci if (!result.second && isHeadBlock) { 1414514f5e3Sopenharmony_ci blockItems_.erase(result.first); 1424514f5e3Sopenharmony_ci blockItems_.insert(RegionItem { bcIndex, isHeadBlock }); 1434514f5e3Sopenharmony_ci } 1444514f5e3Sopenharmony_ci } 1454514f5e3Sopenharmony_ci 1464514f5e3Sopenharmony_ci void InsertSplitItem(uint32_t bcIndex, uint32_t predBcIndex) 1474514f5e3Sopenharmony_ci { 1484514f5e3Sopenharmony_ci splitItems_.emplace_back(BytecodeSplitItem { bcIndex, predBcIndex }); 1494514f5e3Sopenharmony_ci } 1504514f5e3Sopenharmony_ci std::set<RegionItem> blockItems_ {}; 1514514f5e3Sopenharmony_ci std::vector<BytecodeSplitItem> splitItems_ {}; 1524514f5e3Sopenharmony_ci}; 1534514f5e3Sopenharmony_ci 1544514f5e3Sopenharmony_cistruct BytecodeRegion { 1554514f5e3Sopenharmony_ci size_t id {0}; 1564514f5e3Sopenharmony_ci uint32_t start {0}; 1574514f5e3Sopenharmony_ci uint32_t end {0}; 1584514f5e3Sopenharmony_ci ChunkVector<BytecodeRegion *> preds; // List of predessesor blocks 1594514f5e3Sopenharmony_ci ChunkVector<BytecodeRegion *> succs; // List of successors blocks 1604514f5e3Sopenharmony_ci ChunkVector<BytecodeRegion *> trys; // List of trys blocks 1614514f5e3Sopenharmony_ci ChunkVector<BytecodeRegion *> catches; // List of catches blocks 1624514f5e3Sopenharmony_ci ChunkSet<size_t> loopBacks; 1634514f5e3Sopenharmony_ci size_t numOfLoopBack {0}; 1644514f5e3Sopenharmony_ci size_t numOfStatePreds {0}; 1654514f5e3Sopenharmony_ci size_t loopNumber {0}; 1664514f5e3Sopenharmony_ci size_t loopIndex {0}; 1674514f5e3Sopenharmony_ci ChunkVector<std::tuple<size_t, size_t, bool>> expandedPreds; 1684514f5e3Sopenharmony_ci GateRef dependCache {Circuit::NullGate()}; 1694514f5e3Sopenharmony_ci BytecodeIterator bytecodeIterator_ {}; 1704514f5e3Sopenharmony_ci BytecodeRegion(Chunk* chunk) : preds(chunk), succs(chunk), 1714514f5e3Sopenharmony_ci trys(chunk), catches(chunk), loopBacks(chunk), expandedPreds(chunk) 1724514f5e3Sopenharmony_ci { 1734514f5e3Sopenharmony_ci } 1744514f5e3Sopenharmony_ci 1754514f5e3Sopenharmony_ci BytecodeIterator &GetBytecodeIterator() 1764514f5e3Sopenharmony_ci { 1774514f5e3Sopenharmony_ci return bytecodeIterator_; 1784514f5e3Sopenharmony_ci } 1794514f5e3Sopenharmony_ci 1804514f5e3Sopenharmony_ci bool operator <(const BytecodeRegion &target) const 1814514f5e3Sopenharmony_ci { 1824514f5e3Sopenharmony_ci return id < target.id; 1834514f5e3Sopenharmony_ci } 1844514f5e3Sopenharmony_ci 1854514f5e3Sopenharmony_ci void SortCatches() 1864514f5e3Sopenharmony_ci { 1874514f5e3Sopenharmony_ci if (catches.size() > 1) { 1884514f5e3Sopenharmony_ci std::sort(catches.begin(), catches.end(), [](BytecodeRegion *first, BytecodeRegion *second) { 1894514f5e3Sopenharmony_ci return first->start < second->start; 1904514f5e3Sopenharmony_ci }); 1914514f5e3Sopenharmony_ci } 1924514f5e3Sopenharmony_ci } 1934514f5e3Sopenharmony_ci 1944514f5e3Sopenharmony_ci void EraseThisBlock(ChunkVector<BytecodeRegion *> &blocks) 1954514f5e3Sopenharmony_ci { 1964514f5e3Sopenharmony_ci auto it = std::find(blocks.begin(), blocks.end(), this); 1974514f5e3Sopenharmony_ci if (it != blocks.end()) { 1984514f5e3Sopenharmony_ci blocks.erase(it); 1994514f5e3Sopenharmony_ci } 2004514f5e3Sopenharmony_ci } 2014514f5e3Sopenharmony_ci 2024514f5e3Sopenharmony_ci bool IsEmptryBlock() const 2034514f5e3Sopenharmony_ci { 2044514f5e3Sopenharmony_ci return end == static_cast<uint32_t>(BytecodeIterator::INVALID_INDEX); 2054514f5e3Sopenharmony_ci } 2064514f5e3Sopenharmony_ci 2074514f5e3Sopenharmony_ci bool IsLoopBack(const BytecodeRegion &bb) const 2084514f5e3Sopenharmony_ci { 2094514f5e3Sopenharmony_ci return loopBacks.find(bb.id) != loopBacks.end(); 2104514f5e3Sopenharmony_ci } 2114514f5e3Sopenharmony_ci}; 2124514f5e3Sopenharmony_ci 2134514f5e3Sopenharmony_ciusing BytecodeGraph = ChunkVector<BytecodeRegion*>; 2144514f5e3Sopenharmony_ci 2154514f5e3Sopenharmony_ciclass BytecodeCircuitBuilder { 2164514f5e3Sopenharmony_cipublic: 2174514f5e3Sopenharmony_ci BytecodeCircuitBuilder(const JSPandaFile *jsPandaFile, 2184514f5e3Sopenharmony_ci const MethodLiteral *methodLiteral, 2194514f5e3Sopenharmony_ci const MethodPcInfo &methodPCInfo, 2204514f5e3Sopenharmony_ci Circuit *circuit, 2214514f5e3Sopenharmony_ci Bytecodes *bytecodes, 2224514f5e3Sopenharmony_ci bool enableLog, 2234514f5e3Sopenharmony_ci bool enableTypeLowering, 2244514f5e3Sopenharmony_ci std::string name, 2254514f5e3Sopenharmony_ci const CString &recordName, 2264514f5e3Sopenharmony_ci PGOProfilerDecoder *decoder, 2274514f5e3Sopenharmony_ci bool isInline, 2284514f5e3Sopenharmony_ci JITProfiler* jitProfiler = nullptr) 2294514f5e3Sopenharmony_ci : circuit_(circuit), graph_(circuit->chunk()), file_(jsPandaFile), 2304514f5e3Sopenharmony_ci method_(methodLiteral), gateAcc_(circuit), argAcc_(circuit, method_), 2314514f5e3Sopenharmony_ci pgoTypeRecorder_(*decoder, jsPandaFile, method_->GetMethodId().GetOffset()), 2324514f5e3Sopenharmony_ci enableLog_(enableLog), enableTypeLowering_(enableTypeLowering), 2334514f5e3Sopenharmony_ci pcOffsets_(methodPCInfo.pcOffsets), 2344514f5e3Sopenharmony_ci frameStateBuilder_(this, circuit, methodLiteral), 2354514f5e3Sopenharmony_ci methodName_(name), recordName_(recordName), 2364514f5e3Sopenharmony_ci bytecodes_(bytecodes), 2374514f5e3Sopenharmony_ci loopHeaderGates_(circuit->chunk()), 2384514f5e3Sopenharmony_ci preFrameState_(circuit_->GetRoot()), 2394514f5e3Sopenharmony_ci preFrameArgs_(circuit_->GetRoot()), 2404514f5e3Sopenharmony_ci isInline_(isInline), 2414514f5e3Sopenharmony_ci methodId_(method_->GetMethodId().GetOffset()) 2424514f5e3Sopenharmony_ci { 2434514f5e3Sopenharmony_ci if (jitProfiler != nullptr) { 2444514f5e3Sopenharmony_ci pgoTypeRecorder_.InitMap(jitProfiler); 2454514f5e3Sopenharmony_ci } 2464514f5e3Sopenharmony_ci } 2474514f5e3Sopenharmony_ci ~BytecodeCircuitBuilder() = default; 2484514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(BytecodeCircuitBuilder); 2494514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(BytecodeCircuitBuilder); 2504514f5e3Sopenharmony_ci void PUBLIC_API BytecodeToCircuit(); 2514514f5e3Sopenharmony_ci void CollectRegionInfo(uint32_t bcIndex); 2524514f5e3Sopenharmony_ci 2534514f5e3Sopenharmony_ci [[nodiscard]] Circuit* GetCircuit() const 2544514f5e3Sopenharmony_ci { 2554514f5e3Sopenharmony_ci return circuit_; 2564514f5e3Sopenharmony_ci } 2574514f5e3Sopenharmony_ci 2584514f5e3Sopenharmony_ci GateRef GetGateByBcIndex(uint32_t bcIndex) const 2594514f5e3Sopenharmony_ci { 2604514f5e3Sopenharmony_ci ASSERT(bcIndex < byteCodeToJSGates_.size()); 2614514f5e3Sopenharmony_ci if (byteCodeToJSGates_[bcIndex].size() > 0) { 2624514f5e3Sopenharmony_ci ASSERT(byteCodeToJSGates_[bcIndex].size() == 1); 2634514f5e3Sopenharmony_ci return byteCodeToJSGates_[bcIndex].at(0); 2644514f5e3Sopenharmony_ci } 2654514f5e3Sopenharmony_ci return Circuit::NullGate(); 2664514f5e3Sopenharmony_ci } 2674514f5e3Sopenharmony_ci 2684514f5e3Sopenharmony_ci const std::vector<GateRef>& GetGatesByBcIndex(uint32_t bcIndex) const 2694514f5e3Sopenharmony_ci { 2704514f5e3Sopenharmony_ci ASSERT(bcIndex < byteCodeToJSGates_.size()); 2714514f5e3Sopenharmony_ci return byteCodeToJSGates_[bcIndex]; 2724514f5e3Sopenharmony_ci } 2734514f5e3Sopenharmony_ci 2744514f5e3Sopenharmony_ci uint32_t GetBcIndexByGate(GateRef gate) const 2754514f5e3Sopenharmony_ci { 2764514f5e3Sopenharmony_ci return jsGatesToByteCode_.at(gate); 2774514f5e3Sopenharmony_ci } 2784514f5e3Sopenharmony_ci 2794514f5e3Sopenharmony_ci bool IsBcIndexByGate(GateRef gate) const 2804514f5e3Sopenharmony_ci { 2814514f5e3Sopenharmony_ci if (jsGatesToByteCode_.find(gate) == jsGatesToByteCode_.end()) { 2824514f5e3Sopenharmony_ci return false; 2834514f5e3Sopenharmony_ci } 2844514f5e3Sopenharmony_ci return true; 2854514f5e3Sopenharmony_ci } 2864514f5e3Sopenharmony_ci 2874514f5e3Sopenharmony_ci void SetOsrOffset(int32_t offset) 2884514f5e3Sopenharmony_ci { 2894514f5e3Sopenharmony_ci osrOffset_ = offset; 2904514f5e3Sopenharmony_ci } 2914514f5e3Sopenharmony_ci 2924514f5e3Sopenharmony_ci bool NeedCheckSafePointAndStackOver() const 2934514f5e3Sopenharmony_ci { 2944514f5e3Sopenharmony_ci return !isInline_ && !method_->IsNoGC(); 2954514f5e3Sopenharmony_ci } 2964514f5e3Sopenharmony_ci 2974514f5e3Sopenharmony_ci void UpdateBcIndexGate(GateRef gate, uint32_t bcIndex) 2984514f5e3Sopenharmony_ci { 2994514f5e3Sopenharmony_ci ASSERT(gateAcc_.GetOpCode(gate) == OpCode::JS_BYTECODE); 3004514f5e3Sopenharmony_ci ASSERT(bcIndex < byteCodeToJSGates_.size()); 3014514f5e3Sopenharmony_ci byteCodeToJSGates_[bcIndex].emplace_back(gate); 3024514f5e3Sopenharmony_ci jsGatesToByteCode_[gate] = bcIndex; 3034514f5e3Sopenharmony_ci } 3044514f5e3Sopenharmony_ci 3054514f5e3Sopenharmony_ci [[nodiscard]] const MethodLiteral* GetMethod() const 3064514f5e3Sopenharmony_ci { 3074514f5e3Sopenharmony_ci return method_; 3084514f5e3Sopenharmony_ci } 3094514f5e3Sopenharmony_ci 3104514f5e3Sopenharmony_ci [[nodiscard]] const JSPandaFile *GetJSPandaFile() const 3114514f5e3Sopenharmony_ci { 3124514f5e3Sopenharmony_ci return file_; 3134514f5e3Sopenharmony_ci } 3144514f5e3Sopenharmony_ci 3154514f5e3Sopenharmony_ci const std::string& GetMethodName() const 3164514f5e3Sopenharmony_ci { 3174514f5e3Sopenharmony_ci return methodName_; 3184514f5e3Sopenharmony_ci } 3194514f5e3Sopenharmony_ci 3204514f5e3Sopenharmony_ci bool IsLogEnabled() const 3214514f5e3Sopenharmony_ci { 3224514f5e3Sopenharmony_ci return enableLog_; 3234514f5e3Sopenharmony_ci } 3244514f5e3Sopenharmony_ci 3254514f5e3Sopenharmony_ci bool IsTypeLoweringEnabled() const 3264514f5e3Sopenharmony_ci { 3274514f5e3Sopenharmony_ci return enableTypeLowering_; 3284514f5e3Sopenharmony_ci } 3294514f5e3Sopenharmony_ci 3304514f5e3Sopenharmony_ci [[nodiscard]] const std::vector<GateRef>& GetAsyncRelatedGates() const 3314514f5e3Sopenharmony_ci { 3324514f5e3Sopenharmony_ci return suspendAndResumeGates_; 3334514f5e3Sopenharmony_ci } 3344514f5e3Sopenharmony_ci 3354514f5e3Sopenharmony_ci void UpdateAsyncRelatedGate(GateRef gate) 3364514f5e3Sopenharmony_ci { 3374514f5e3Sopenharmony_ci suspendAndResumeGates_.emplace_back(gate); 3384514f5e3Sopenharmony_ci }; 3394514f5e3Sopenharmony_ci 3404514f5e3Sopenharmony_ci template <class Callback> 3414514f5e3Sopenharmony_ci void EnumerateBlock(BytecodeRegion &bb, const Callback &cb) 3424514f5e3Sopenharmony_ci { 3434514f5e3Sopenharmony_ci auto &iterator = bb.GetBytecodeIterator(); 3444514f5e3Sopenharmony_ci iterator.GotoStart(); 3454514f5e3Sopenharmony_ci while (!iterator.Done()) { 3464514f5e3Sopenharmony_ci auto &bytecodeInfo = iterator.GetBytecodeInfo(); 3474514f5e3Sopenharmony_ci bool ret = cb(bytecodeInfo); 3484514f5e3Sopenharmony_ci if (!ret) { 3494514f5e3Sopenharmony_ci break; 3504514f5e3Sopenharmony_ci } 3514514f5e3Sopenharmony_ci ++iterator; 3524514f5e3Sopenharmony_ci } 3534514f5e3Sopenharmony_ci } 3544514f5e3Sopenharmony_ci 3554514f5e3Sopenharmony_ci BytecodeRegion &GetBasicBlockById(size_t id) 3564514f5e3Sopenharmony_ci { 3574514f5e3Sopenharmony_ci ASSERT(id < graph_.size()); 3584514f5e3Sopenharmony_ci return RegionAt(id); 3594514f5e3Sopenharmony_ci } 3604514f5e3Sopenharmony_ci 3614514f5e3Sopenharmony_ci void AddBasicBlock(BytecodeRegion* region) 3624514f5e3Sopenharmony_ci { 3634514f5e3Sopenharmony_ci graph_.emplace_back(region); 3644514f5e3Sopenharmony_ci } 3654514f5e3Sopenharmony_ci 3664514f5e3Sopenharmony_ci size_t GetBasicBlockCount() const 3674514f5e3Sopenharmony_ci { 3684514f5e3Sopenharmony_ci return graph_.size(); 3694514f5e3Sopenharmony_ci } 3704514f5e3Sopenharmony_ci 3714514f5e3Sopenharmony_ci size_t GetPcOffset(const uint8_t *pc) const 3724514f5e3Sopenharmony_ci { 3734514f5e3Sopenharmony_ci return static_cast<size_t>(pc - method_->GetBytecodeArray()); 3744514f5e3Sopenharmony_ci } 3754514f5e3Sopenharmony_ci 3764514f5e3Sopenharmony_ci size_t GetPcOffset(uint32_t bcIndex) const 3774514f5e3Sopenharmony_ci { 3784514f5e3Sopenharmony_ci const uint8_t* pc = GetPCByIndex(bcIndex); 3794514f5e3Sopenharmony_ci return GetPcOffset(pc); 3804514f5e3Sopenharmony_ci } 3814514f5e3Sopenharmony_ci 3824514f5e3Sopenharmony_ci size_t GetPcOffsetByGate(GateRef gate) const 3834514f5e3Sopenharmony_ci { 3844514f5e3Sopenharmony_ci return GetPcOffset(jsGatesToByteCode_.at(gate)); 3854514f5e3Sopenharmony_ci } 3864514f5e3Sopenharmony_ci 3874514f5e3Sopenharmony_ci std::vector<ElementsKind> GetElementsKindsForUser(GateRef gate) const 3884514f5e3Sopenharmony_ci { 3894514f5e3Sopenharmony_ci return pgoTypeRecorder_.GetElementsKindsForUser(GetPcOffsetByGate(gate)); 3904514f5e3Sopenharmony_ci } 3914514f5e3Sopenharmony_ci 3924514f5e3Sopenharmony_ci PUBLIC_API std::vector<ElementsKind> GetTransitionElementsKindsForUser(GateRef gate) const 3934514f5e3Sopenharmony_ci { 3944514f5e3Sopenharmony_ci return pgoTypeRecorder_.GetTransitionElementsKindsForUser(GetPcOffsetByGate(gate)); 3954514f5e3Sopenharmony_ci } 3964514f5e3Sopenharmony_ci 3974514f5e3Sopenharmony_ci ElementsKind GetElementsKindForCreater(GateRef gate) const 3984514f5e3Sopenharmony_ci { 3994514f5e3Sopenharmony_ci return pgoTypeRecorder_.GetElementsKindForCreater(gateAcc_.TryGetPcOffset(gate)); 4004514f5e3Sopenharmony_ci } 4014514f5e3Sopenharmony_ci 4024514f5e3Sopenharmony_ci uint32_t GetArrayElementsLength(GateRef gate) const 4034514f5e3Sopenharmony_ci { 4044514f5e3Sopenharmony_ci return pgoTypeRecorder_.GetElementsLength(gateAcc_.TryGetPcOffset(gate)); 4054514f5e3Sopenharmony_ci } 4064514f5e3Sopenharmony_ci 4074514f5e3Sopenharmony_ci RegionSpaceFlag GetRegionSpaceFlag(GateRef gate) const 4084514f5e3Sopenharmony_ci { 4094514f5e3Sopenharmony_ci return pgoTypeRecorder_.GetRegionSpaceFlag(gateAcc_.TryGetPcOffset(gate)); 4104514f5e3Sopenharmony_ci } 4114514f5e3Sopenharmony_ci 4124514f5e3Sopenharmony_ci bool ShouldPGOTypeInfer(GateRef gate) const 4134514f5e3Sopenharmony_ci { 4144514f5e3Sopenharmony_ci return jsGatesToByteCode_.find(gate) != jsGatesToByteCode_.end(); 4154514f5e3Sopenharmony_ci } 4164514f5e3Sopenharmony_ci 4174514f5e3Sopenharmony_ci size_t GetNumberVRegs() const 4184514f5e3Sopenharmony_ci { 4194514f5e3Sopenharmony_ci return static_cast<size_t>(method_->GetNumberVRegs()); 4204514f5e3Sopenharmony_ci } 4214514f5e3Sopenharmony_ci 4224514f5e3Sopenharmony_ci size_t GetNumberVRegsWithEnv() const 4234514f5e3Sopenharmony_ci { 4244514f5e3Sopenharmony_ci return GetNumberVRegs() + 1; // 1: env variable 4254514f5e3Sopenharmony_ci } 4264514f5e3Sopenharmony_ci 4274514f5e3Sopenharmony_ci size_t GetEnvVregIdx() const 4284514f5e3Sopenharmony_ci { 4294514f5e3Sopenharmony_ci return GetNumberVRegs(); 4304514f5e3Sopenharmony_ci } 4314514f5e3Sopenharmony_ci 4324514f5e3Sopenharmony_ci Bytecodes *GetBytecodes() const 4334514f5e3Sopenharmony_ci { 4344514f5e3Sopenharmony_ci return bytecodes_; 4354514f5e3Sopenharmony_ci } 4364514f5e3Sopenharmony_ci 4374514f5e3Sopenharmony_ci uint32_t GetLastBcIndex() const 4384514f5e3Sopenharmony_ci { 4394514f5e3Sopenharmony_ci ASSERT(pcOffsets_.size() > 0); 4404514f5e3Sopenharmony_ci return static_cast<uint32_t>(pcOffsets_.size() - 1); 4414514f5e3Sopenharmony_ci } 4424514f5e3Sopenharmony_ci 4434514f5e3Sopenharmony_ci const uint8_t *GetPCByIndex(uint32_t index) const 4444514f5e3Sopenharmony_ci { 4454514f5e3Sopenharmony_ci ASSERT(index <= GetLastBcIndex()); 4464514f5e3Sopenharmony_ci return pcOffsets_[index]; 4474514f5e3Sopenharmony_ci } 4484514f5e3Sopenharmony_ci 4494514f5e3Sopenharmony_ci const uint8_t *GetFirstPC() const 4504514f5e3Sopenharmony_ci { 4514514f5e3Sopenharmony_ci return GetPCByIndex(0); 4524514f5e3Sopenharmony_ci } 4534514f5e3Sopenharmony_ci 4544514f5e3Sopenharmony_ci const uint8_t *GetLastPC() const 4554514f5e3Sopenharmony_ci { 4564514f5e3Sopenharmony_ci return GetPCByIndex(GetLastBcIndex()); 4574514f5e3Sopenharmony_ci } 4584514f5e3Sopenharmony_ci 4594514f5e3Sopenharmony_ci uint32_t FindBcIndexByPc(const uint8_t *pc) const 4604514f5e3Sopenharmony_ci { 4614514f5e3Sopenharmony_ci auto begin = pcOffsets_.begin(); 4624514f5e3Sopenharmony_ci auto end = pcOffsets_.end(); 4634514f5e3Sopenharmony_ci auto it = std::lower_bound(begin, end, pc); 4644514f5e3Sopenharmony_ci ASSERT(it != end); 4654514f5e3Sopenharmony_ci ASSERT(*it == pc); 4664514f5e3Sopenharmony_ci return std::distance(begin, it); 4674514f5e3Sopenharmony_ci } 4684514f5e3Sopenharmony_ci 4694514f5e3Sopenharmony_ci const BytecodeInfo &GetBytecodeInfo(uint32_t index) const 4704514f5e3Sopenharmony_ci { 4714514f5e3Sopenharmony_ci return infoData_[index]; 4724514f5e3Sopenharmony_ci } 4734514f5e3Sopenharmony_ci 4744514f5e3Sopenharmony_ci bool HasTryCatch() const 4754514f5e3Sopenharmony_ci { 4764514f5e3Sopenharmony_ci return hasTryCatch_; 4774514f5e3Sopenharmony_ci } 4784514f5e3Sopenharmony_ci 4794514f5e3Sopenharmony_ci bool EnableLoopOptimization() const 4804514f5e3Sopenharmony_ci { 4814514f5e3Sopenharmony_ci return (!HasTryCatch()) && frameStateBuilder_.HasLoop(); 4824514f5e3Sopenharmony_ci } 4834514f5e3Sopenharmony_ci 4844514f5e3Sopenharmony_ci void RemoveUnreachableRegion(); 4854514f5e3Sopenharmony_ci 4864514f5e3Sopenharmony_ci GateRef GetFrameArgs() const 4874514f5e3Sopenharmony_ci { 4884514f5e3Sopenharmony_ci return argAcc_.GetFrameArgs(); 4894514f5e3Sopenharmony_ci } 4904514f5e3Sopenharmony_ci 4914514f5e3Sopenharmony_ci GateRef GetPreFrameState() const 4924514f5e3Sopenharmony_ci { 4934514f5e3Sopenharmony_ci return preFrameState_; 4944514f5e3Sopenharmony_ci } 4954514f5e3Sopenharmony_ci 4964514f5e3Sopenharmony_ci void SetPreFrameState(GateRef gate) 4974514f5e3Sopenharmony_ci { 4984514f5e3Sopenharmony_ci preFrameState_ = gate; 4994514f5e3Sopenharmony_ci } 5004514f5e3Sopenharmony_ci 5014514f5e3Sopenharmony_ci GateRef GetPreFrameArgs() const 5024514f5e3Sopenharmony_ci { 5034514f5e3Sopenharmony_ci return preFrameArgs_; 5044514f5e3Sopenharmony_ci } 5054514f5e3Sopenharmony_ci 5064514f5e3Sopenharmony_ci void SetPreFrameArgs(GateRef gate) 5074514f5e3Sopenharmony_ci { 5084514f5e3Sopenharmony_ci preFrameArgs_ = gate; 5094514f5e3Sopenharmony_ci } 5104514f5e3Sopenharmony_ci 5114514f5e3Sopenharmony_ci inline bool IsEntryBlock(const size_t bbId) const 5124514f5e3Sopenharmony_ci { 5134514f5e3Sopenharmony_ci return bbId == 0; 5144514f5e3Sopenharmony_ci } 5154514f5e3Sopenharmony_ci 5164514f5e3Sopenharmony_ci inline bool IsFirstBasicBlock(const size_t bbId) const 5174514f5e3Sopenharmony_ci { 5184514f5e3Sopenharmony_ci return bbId == 1; 5194514f5e3Sopenharmony_ci } 5204514f5e3Sopenharmony_ci 5214514f5e3Sopenharmony_ci const PGOTypeRecorder *GetPGOTypeRecorder() const 5224514f5e3Sopenharmony_ci { 5234514f5e3Sopenharmony_ci return &pgoTypeRecorder_; 5244514f5e3Sopenharmony_ci } 5254514f5e3Sopenharmony_ci 5264514f5e3Sopenharmony_ci GateRef GetArgGate(const size_t currentVreg) const 5274514f5e3Sopenharmony_ci { 5284514f5e3Sopenharmony_ci return argAcc_.GetArgGate(currentVreg); 5294514f5e3Sopenharmony_ci } 5304514f5e3Sopenharmony_ci 5314514f5e3Sopenharmony_ci GateRef ArgGateNotExisted(const size_t currentVreg) 5324514f5e3Sopenharmony_ci { 5334514f5e3Sopenharmony_ci return argAcc_.ArgGateNotExisted(currentVreg); 5344514f5e3Sopenharmony_ci } 5354514f5e3Sopenharmony_ci 5364514f5e3Sopenharmony_ci ChunkVector<GateRef>& GetLoopHeaderGates() 5374514f5e3Sopenharmony_ci { 5384514f5e3Sopenharmony_ci return loopHeaderGates_; 5394514f5e3Sopenharmony_ci } 5404514f5e3Sopenharmony_ci 5414514f5e3Sopenharmony_ci size_t NumberOfLiveBlock() const 5424514f5e3Sopenharmony_ci { 5434514f5e3Sopenharmony_ci return numOfLiveBB_; 5444514f5e3Sopenharmony_ci } 5454514f5e3Sopenharmony_ci 5464514f5e3Sopenharmony_ci int32_t GetCurrentConstpoolId() const 5474514f5e3Sopenharmony_ci { 5484514f5e3Sopenharmony_ci panda_file::IndexAccessor indexAccessor(*file_->GetPandaFile(), panda_file::File::EntityId(methodId_)); 5494514f5e3Sopenharmony_ci return static_cast<int32_t>(indexAccessor.GetHeaderIndex()); 5504514f5e3Sopenharmony_ci } 5514514f5e3Sopenharmony_ci 5524514f5e3Sopenharmony_ci void GetCurrentConstpool(GateRef jsFunc, GateRef &sharedConstPool, GateRef &unSharedConstPool) 5534514f5e3Sopenharmony_ci { 5544514f5e3Sopenharmony_ci int32_t constpoolId = GetCurrentConstpoolId(); 5554514f5e3Sopenharmony_ci if (gateAcc_.GetOpCode(preFrameArgs_) == OpCode::CIRCUIT_ROOT) { 5564514f5e3Sopenharmony_ci sharedConstPool = circuit_->NewGate(circuit_->GetSharedConstPool(constpoolId), MachineType::I64, {jsFunc}, 5574514f5e3Sopenharmony_ci GateType::AnyType()); 5584514f5e3Sopenharmony_ci unSharedConstPool = circuit_->NewGate(circuit_->GetUnsharedConstPool(), MachineType::I64, 5594514f5e3Sopenharmony_ci {sharedConstPool}, GateType::AnyType()); 5604514f5e3Sopenharmony_ci } 5614514f5e3Sopenharmony_ci GateRef frameArgs = preFrameArgs_; 5624514f5e3Sopenharmony_ci GateRef preSharedConstPool = Circuit::NullGate(); 5634514f5e3Sopenharmony_ci GateRef preUnsharedConstPool = Circuit::NullGate(); 5644514f5e3Sopenharmony_ci int32_t preConstpoolId = 0; 5654514f5e3Sopenharmony_ci while (gateAcc_.GetOpCode(frameArgs) != OpCode::CIRCUIT_ROOT) { 5664514f5e3Sopenharmony_ci preSharedConstPool = gateAcc_.GetValueIn(frameArgs, static_cast<size_t>(FrameArgIdx::SHARED_CONST_POOL)); 5674514f5e3Sopenharmony_ci preUnsharedConstPool = 5684514f5e3Sopenharmony_ci gateAcc_.GetValueIn(frameArgs, static_cast<size_t>(FrameArgIdx::UNSHARED_CONST_POOL)); 5694514f5e3Sopenharmony_ci preConstpoolId = static_cast<int32_t>(gateAcc_.GetConstpoolId(preSharedConstPool)); 5704514f5e3Sopenharmony_ci if (preConstpoolId == constpoolId) { 5714514f5e3Sopenharmony_ci sharedConstPool = preSharedConstPool; 5724514f5e3Sopenharmony_ci unSharedConstPool = preUnsharedConstPool; 5734514f5e3Sopenharmony_ci break; 5744514f5e3Sopenharmony_ci } 5754514f5e3Sopenharmony_ci frameArgs = gateAcc_.GetFrameState(frameArgs); 5764514f5e3Sopenharmony_ci } 5774514f5e3Sopenharmony_ci } 5784514f5e3Sopenharmony_ci 5794514f5e3Sopenharmony_ci void SetIrreducibleLoop() 5804514f5e3Sopenharmony_ci { 5814514f5e3Sopenharmony_ci isIrreducible_ = true; 5824514f5e3Sopenharmony_ci } 5834514f5e3Sopenharmony_ci 5844514f5e3Sopenharmony_ci bool HasIrreducibleLoop() const 5854514f5e3Sopenharmony_ci { 5864514f5e3Sopenharmony_ci return isIrreducible_; 5874514f5e3Sopenharmony_ci } 5884514f5e3Sopenharmony_ci 5894514f5e3Sopenharmony_ci void SetJitCompile() 5904514f5e3Sopenharmony_ci { 5914514f5e3Sopenharmony_ci isJitCompile_ = true; 5924514f5e3Sopenharmony_ci } 5934514f5e3Sopenharmony_ci 5944514f5e3Sopenharmony_ci bool IsJitCompile() const 5954514f5e3Sopenharmony_ci { 5964514f5e3Sopenharmony_ci return isJitCompile_; 5974514f5e3Sopenharmony_ci } 5984514f5e3Sopenharmony_ci 5994514f5e3Sopenharmony_ci void SetPreAnalysis() 6004514f5e3Sopenharmony_ci { 6014514f5e3Sopenharmony_ci preAnalysis_ = true; 6024514f5e3Sopenharmony_ci } 6034514f5e3Sopenharmony_ci 6044514f5e3Sopenharmony_ci bool IsPreAnalysis() const 6054514f5e3Sopenharmony_ci { 6064514f5e3Sopenharmony_ci return preAnalysis_; 6074514f5e3Sopenharmony_ci } 6084514f5e3Sopenharmony_ci 6094514f5e3Sopenharmony_ci bool NeedIrreducibleLoopCheck() const 6104514f5e3Sopenharmony_ci { 6114514f5e3Sopenharmony_ci return IsPreAnalysis() || IsJitCompile(); 6124514f5e3Sopenharmony_ci } 6134514f5e3Sopenharmony_ci 6144514f5e3Sopenharmony_ci bool TerminateAnalysis() const 6154514f5e3Sopenharmony_ci { 6164514f5e3Sopenharmony_ci return IsPreAnalysis() || HasIrreducibleLoop(); 6174514f5e3Sopenharmony_ci } 6184514f5e3Sopenharmony_ci 6194514f5e3Sopenharmony_ci bool IsOSR() const 6204514f5e3Sopenharmony_ci { 6214514f5e3Sopenharmony_ci return osrOffset_ != MachineCode::INVALID_OSR_OFFSET; 6224514f5e3Sopenharmony_ci } 6234514f5e3Sopenharmony_ci 6244514f5e3Sopenharmony_ci bool IsCacheBBOfOSRLoop(const BytecodeRegion &bb) const 6254514f5e3Sopenharmony_ci { 6264514f5e3Sopenharmony_ci return catchBBOfOSRLoop_.find(&bb) != catchBBOfOSRLoop_.end(); 6274514f5e3Sopenharmony_ci } 6284514f5e3Sopenharmony_ci 6294514f5e3Sopenharmony_ci void ComputeNumOfLoopBack(); 6304514f5e3Sopenharmony_ci 6314514f5e3Sopenharmony_ci enum class MarkState : uint8_t { 6324514f5e3Sopenharmony_ci UNVISITED = 0, 6334514f5e3Sopenharmony_ci ON_STACK, 6344514f5e3Sopenharmony_ci PENDING, 6354514f5e3Sopenharmony_ci VISITED, 6364514f5e3Sopenharmony_ci VISITED1, 6374514f5e3Sopenharmony_ci UNVISITED1 = VISITED 6384514f5e3Sopenharmony_ci }; 6394514f5e3Sopenharmony_ci 6404514f5e3Sopenharmony_ci struct VisitedInfo { 6414514f5e3Sopenharmony_ci size_t needVisitIndex; 6424514f5e3Sopenharmony_ci bool isVisitedCatchBlock = false; 6434514f5e3Sopenharmony_ci }; 6444514f5e3Sopenharmony_ci bool IsAncestor(size_t nodeA, size_t nodeB); 6454514f5e3Sopenharmony_ci 6464514f5e3Sopenharmony_ciprivate: 6474514f5e3Sopenharmony_ci void CollectTryCatchBlockInfo(ExceptionInfo &Exception); 6484514f5e3Sopenharmony_ci void BuildCatchBlocks(const ExceptionInfo &Exception); 6494514f5e3Sopenharmony_ci void BuildEntryBlock(); 6504514f5e3Sopenharmony_ci void BuildBasicBlock(); 6514514f5e3Sopenharmony_ci void BuildRegions(const ExceptionInfo &Exception); 6524514f5e3Sopenharmony_ci // build circuit 6534514f5e3Sopenharmony_ci void BuildCircuitArgs(); 6544514f5e3Sopenharmony_ci void BuildOSRArgs(); 6554514f5e3Sopenharmony_ci std::vector<GateRef> CreateGateInList(const BytecodeInfo &info, const GateMetaData *meta); 6564514f5e3Sopenharmony_ci GateRef NewConst(const BytecodeInfo &info); 6574514f5e3Sopenharmony_ci void NewJSGate(BytecodeRegion &bb); 6584514f5e3Sopenharmony_ci void NewJump(BytecodeRegion &bbd); 6594514f5e3Sopenharmony_ci GateRef NewReturn(BytecodeRegion &bb); 6604514f5e3Sopenharmony_ci void NewByteCode(BytecodeRegion &bb); 6614514f5e3Sopenharmony_ci void MergeThrowGate(BytecodeRegion &bb, uint32_t bcIndex); 6624514f5e3Sopenharmony_ci void MergeExceptionGete(BytecodeRegion &bb, const BytecodeInfo& bytecodeInfo, uint32_t bcIndex); 6634514f5e3Sopenharmony_ci void BuildSubCircuit(); 6644514f5e3Sopenharmony_ci bool FindOsrLoopHeadBB(); 6654514f5e3Sopenharmony_ci void GenDeoptAndReturnForOsrLoopExit(BytecodeRegion& osrLoopExitBB); 6664514f5e3Sopenharmony_ci void CollectCacheBBforOSRLoop(BytecodeRegion *bb); 6674514f5e3Sopenharmony_ci void HandleOsrLoopBody(BytecodeRegion &osrLoopBodyBB); 6684514f5e3Sopenharmony_ci void BuildOsrCircuit(); 6694514f5e3Sopenharmony_ci 6704514f5e3Sopenharmony_ci void UpdateCFG(); 6714514f5e3Sopenharmony_ci void CollectTryPredsInfo(); 6724514f5e3Sopenharmony_ci void ClearUnreachableRegion(ChunkVector<BytecodeRegion*>& pendingList); 6734514f5e3Sopenharmony_ci void RemoveUnusedPredsInfo(BytecodeRegion& bb); 6744514f5e3Sopenharmony_ci void BuildCircuit(); 6754514f5e3Sopenharmony_ci void PrintGraph(); 6764514f5e3Sopenharmony_ci void PrintBBInfo(); 6774514f5e3Sopenharmony_ci void PrintGraph(const char* title); 6784514f5e3Sopenharmony_ci void PrintBytecodeInfo(BytecodeRegion& region); 6794514f5e3Sopenharmony_ci void PrintDefsitesInfo(const std::unordered_map<uint16_t, std::set<size_t>> &defsitesInfo); 6804514f5e3Sopenharmony_ci void BuildRegionInfo(); 6814514f5e3Sopenharmony_ci void BuildFrameArgs(); 6824514f5e3Sopenharmony_ci void RemoveIfInRpoList(BytecodeRegion *bb); 6834514f5e3Sopenharmony_ci void PerformDFS(const std::vector<size_t> &immDom, size_t listSize); 6844514f5e3Sopenharmony_ci void ReducibilityCheck(); 6854514f5e3Sopenharmony_ci void ComputeImmediateDominators(const std::vector<size_t> &basicBlockList, 6864514f5e3Sopenharmony_ci std::unordered_map<size_t, size_t> &dfsFatherIdx, std::vector<size_t> &immDom, 6874514f5e3Sopenharmony_ci std::unordered_map<size_t, size_t> &bbDfsTimestampToIdx); 6884514f5e3Sopenharmony_ci void ComputeDominatorTree(std::vector<size_t> &basicBlockList, std::vector<size_t> &immDom, 6894514f5e3Sopenharmony_ci std::unordered_map<size_t, size_t> &bbDfsTimestampToIdx); 6904514f5e3Sopenharmony_ci 6914514f5e3Sopenharmony_ci BytecodeRegion &RegionAt(size_t i) 6924514f5e3Sopenharmony_ci { 6934514f5e3Sopenharmony_ci return *graph_[i]; 6944514f5e3Sopenharmony_ci } 6954514f5e3Sopenharmony_ci 6964514f5e3Sopenharmony_ci Circuit *circuit_; 6974514f5e3Sopenharmony_ci std::vector<std::vector<GateRef>> byteCodeToJSGates_; 6984514f5e3Sopenharmony_ci std::unordered_map<GateRef, size_t> jsGatesToByteCode_; 6994514f5e3Sopenharmony_ci BytecodeGraph graph_; 7004514f5e3Sopenharmony_ci const JSPandaFile *file_ {nullptr}; 7014514f5e3Sopenharmony_ci const MethodLiteral *method_ {nullptr}; 7024514f5e3Sopenharmony_ci GateAccessor gateAcc_; 7034514f5e3Sopenharmony_ci ArgumentAccessor argAcc_; 7044514f5e3Sopenharmony_ci PGOTypeRecorder pgoTypeRecorder_; 7054514f5e3Sopenharmony_ci int32_t osrOffset_ {MachineCode::INVALID_OSR_OFFSET}; 7064514f5e3Sopenharmony_ci bool enableLog_ {false}; 7074514f5e3Sopenharmony_ci bool enableTypeLowering_ {false}; 7084514f5e3Sopenharmony_ci std::vector<GateRef> suspendAndResumeGates_ {}; 7094514f5e3Sopenharmony_ci std::vector<const uint8_t*> pcOffsets_; 7104514f5e3Sopenharmony_ci FrameStateBuilder frameStateBuilder_; 7114514f5e3Sopenharmony_ci std::string methodName_; 7124514f5e3Sopenharmony_ci const CString &recordName_; 7134514f5e3Sopenharmony_ci Bytecodes *bytecodes_; 7144514f5e3Sopenharmony_ci RegionsInfo regionsInfo_{}; 7154514f5e3Sopenharmony_ci std::vector<BytecodeInfo> infoData_ {}; 7164514f5e3Sopenharmony_ci bool hasTryCatch_ {false}; 7174514f5e3Sopenharmony_ci ChunkVector<GateRef> loopHeaderGates_; 7184514f5e3Sopenharmony_ci GateRef preFrameState_ {Circuit::NullGate()}; 7194514f5e3Sopenharmony_ci GateRef preFrameArgs_ {Circuit::NullGate()}; 7204514f5e3Sopenharmony_ci size_t numOfLiveBB_ {0}; 7214514f5e3Sopenharmony_ci bool isInline_ {false}; 7224514f5e3Sopenharmony_ci uint32_t methodId_ {0}; 7234514f5e3Sopenharmony_ci bool preAnalysis_ {false}; 7244514f5e3Sopenharmony_ci std::set<const BytecodeRegion *> catchBBOfOSRLoop_{}; 7254514f5e3Sopenharmony_ci bool isIrreducible_ {false}; 7264514f5e3Sopenharmony_ci bool isJitCompile_ {false}; 7274514f5e3Sopenharmony_ci CVector<size_t> timeIn_ {}; 7284514f5e3Sopenharmony_ci CVector<size_t> timeOut_ {}; 7294514f5e3Sopenharmony_ci std::unordered_map<size_t, size_t> bbIdToDfsTimestamp_ {}; 7304514f5e3Sopenharmony_ci}; 7314514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 7324514f5e3Sopenharmony_ci#endif // ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H 733