14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 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_COMPILER_ESCAPE_ANALYSIS_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_ESCAPE_ANALYSIS_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/combined_pass_visitor.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/gate_accessor.h" 214514f5e3Sopenharmony_ci#include "ecmascript/mem/chunk_containers.h" 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_ciclass EscapeAnalysis; 264514f5e3Sopenharmony_ciclass FieldLocation; 274514f5e3Sopenharmony_ci 284514f5e3Sopenharmony_ciclass VirtualObject { 294514f5e3Sopenharmony_cipublic: 304514f5e3Sopenharmony_ci VirtualObject(size_t numIn, Chunk* chunk); 314514f5e3Sopenharmony_ci void SetEscaped(); 324514f5e3Sopenharmony_ci bool IsEscaped() const; 334514f5e3Sopenharmony_ci ChunkVector<GateRef>& GetUsers(); 344514f5e3Sopenharmony_ci void ClearUsers(); 354514f5e3Sopenharmony_ci void AddUser(GateRef gate); 364514f5e3Sopenharmony_ci FieldLocation GetField(size_t offset); 374514f5e3Sopenharmony_ciprivate: 384514f5e3Sopenharmony_ci ChunkVector<FieldLocation> fields_; 394514f5e3Sopenharmony_ci // Gates which use this virtual object 404514f5e3Sopenharmony_ci ChunkVector<GateRef> users_; 414514f5e3Sopenharmony_ci bool escaped_ {false}; 424514f5e3Sopenharmony_ci}; 434514f5e3Sopenharmony_ci 444514f5e3Sopenharmony_ciclass FieldLocation { 454514f5e3Sopenharmony_cipublic: 464514f5e3Sopenharmony_ci FieldLocation() : id_(maxid++) {} 474514f5e3Sopenharmony_ci FieldLocation(size_t id) : id_(id) {} 484514f5e3Sopenharmony_ci bool operator == (const FieldLocation &v) const 494514f5e3Sopenharmony_ci { 504514f5e3Sopenharmony_ci return id_ == v.id_; 514514f5e3Sopenharmony_ci } 524514f5e3Sopenharmony_ci bool operator != (const FieldLocation &v) const 534514f5e3Sopenharmony_ci { 544514f5e3Sopenharmony_ci return id_ != v.id_; 554514f5e3Sopenharmony_ci } 564514f5e3Sopenharmony_ci bool operator < (const FieldLocation &v) const 574514f5e3Sopenharmony_ci { 584514f5e3Sopenharmony_ci return id_ < v.id_; 594514f5e3Sopenharmony_ci } 604514f5e3Sopenharmony_ci static constexpr size_t invalid = -1; 614514f5e3Sopenharmony_ci static FieldLocation Invalid() 624514f5e3Sopenharmony_ci { 634514f5e3Sopenharmony_ci return FieldLocation(invalid); 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ciprivate: 664514f5e3Sopenharmony_ci static size_t maxid; 674514f5e3Sopenharmony_ci size_t id_; 684514f5e3Sopenharmony_ci}; 694514f5e3Sopenharmony_ci 704514f5e3Sopenharmony_ciclass State { 714514f5e3Sopenharmony_cipublic: 724514f5e3Sopenharmony_ci explicit State(Chunk* chunk) : map_(chunk) {} 734514f5e3Sopenharmony_ci void SetFieldValue(FieldLocation field, GateRef gate); 744514f5e3Sopenharmony_ci GateRef GetFieldValue(FieldLocation field) const; 754514f5e3Sopenharmony_ci bool IsMapEqual(const State &state) const; 764514f5e3Sopenharmony_ci auto begin() const { return map_.begin(); } 774514f5e3Sopenharmony_ci auto end() const { return map_.end(); } 784514f5e3Sopenharmony_ciprivate: 794514f5e3Sopenharmony_ci ChunkMap<FieldLocation, GateRef> map_; 804514f5e3Sopenharmony_ci}; 814514f5e3Sopenharmony_ci 824514f5e3Sopenharmony_ci// When we visit a gate, we first create a GateInfo which maintains results and all information 834514f5e3Sopenharmony_ci// that may be used in this visit. After finishing this visit, virtual object and replacement 844514f5e3Sopenharmony_ci// of this gate must be reset. 854514f5e3Sopenharmony_ciclass GateInfo { 864514f5e3Sopenharmony_cipublic: 874514f5e3Sopenharmony_ci GateInfo(Circuit* circuit, GateRef curGate, EscapeAnalysis* escapeAnalysis, Chunk* chunk); 884514f5e3Sopenharmony_ci ~GateInfo(); 894514f5e3Sopenharmony_ci GateRef GetCurrentGate() const; 904514f5e3Sopenharmony_ci GateRef GetFieldValue(FieldLocation field) const; 914514f5e3Sopenharmony_ci void SetFieldValue(FieldLocation field, GateRef value); 924514f5e3Sopenharmony_ci void SetEliminated(); 934514f5e3Sopenharmony_ci void SetVirtualObject(VirtualObject* object); 944514f5e3Sopenharmony_ci State MergeState(GateRef gate); 954514f5e3Sopenharmony_ci void SetReplacement(GateRef replacement); 964514f5e3Sopenharmony_ciprivate: 974514f5e3Sopenharmony_ci Circuit* circuit_; 984514f5e3Sopenharmony_ci GateAccessor acc_; 994514f5e3Sopenharmony_ci GateRef curGate_; 1004514f5e3Sopenharmony_ci EscapeAnalysis* escapeAnalysis_; 1014514f5e3Sopenharmony_ci State state_; 1024514f5e3Sopenharmony_ci VirtualObject* object_ {nullptr}; 1034514f5e3Sopenharmony_ci GateRef replacement_ {Circuit::NullGate()}; 1044514f5e3Sopenharmony_ci}; 1054514f5e3Sopenharmony_ci 1064514f5e3Sopenharmony_ciclass EscapeAnalysis : public PassVisitor { 1074514f5e3Sopenharmony_cipublic: 1084514f5e3Sopenharmony_ci EscapeAnalysis(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk, bool isTraced) 1094514f5e3Sopenharmony_ci : PassVisitor(circuit, chunk, visitor), circuit_(circuit), replacements_(chunk), gateToVirtualObject_(chunk), 1104514f5e3Sopenharmony_ci gateToState_(chunk), chunk_(chunk), isTraced_(isTraced) {} 1114514f5e3Sopenharmony_ci 1124514f5e3Sopenharmony_ci GateRef VisitGate(GateRef gate) override; 1134514f5e3Sopenharmony_ci void SetEscaped(GateRef gate); 1144514f5e3Sopenharmony_ci GateRef GetCurrentGate(GateRef gate) const; 1154514f5e3Sopenharmony_ci void RevisitUser(VirtualObject* vObj); 1164514f5e3Sopenharmony_ci GateRef TryGetReplacement(GateRef gate) const; 1174514f5e3Sopenharmony_ci void SetReplacement(GateRef gate, GateRef replacement); 1184514f5e3Sopenharmony_ci VirtualObject* TryGetVirtualObject(GateRef gate) const; 1194514f5e3Sopenharmony_ci VirtualObject* TryGetVirtualObjectAndAddUser(GateRef gate, GateRef currentGate); 1204514f5e3Sopenharmony_ci void SetVirtualObject(GateRef gate, VirtualObject* object); 1214514f5e3Sopenharmony_ci VirtualObject* GetOrCreateVirtualObject(size_t numIn, GateInfo* info); 1224514f5e3Sopenharmony_ci State& GetOrCreateState(GateRef gate); 1234514f5e3Sopenharmony_ci void SetState(GateRef gate, State state); 1244514f5e3Sopenharmony_ci void RevisitGate(GateRef gate); 1254514f5e3Sopenharmony_ci void SetReplaceGate(GateRef gate); 1264514f5e3Sopenharmony_ciprivate: 1274514f5e3Sopenharmony_ci GateRef VisitCreateObjectWithBuffer(GateRef gate, GateInfo* info); 1284514f5e3Sopenharmony_ci GateRef VisitLoadProperty(GateRef gate, GateInfo* info); 1294514f5e3Sopenharmony_ci GateRef VisitLoadConstOffset(GateRef gate, GateInfo* info); 1304514f5e3Sopenharmony_ci GateRef VisitStoreProperty(GateRef gate, GateInfo* info); 1314514f5e3Sopenharmony_ci GateRef VisitObjectTypeCheck(GateRef gate, GateInfo* info); 1324514f5e3Sopenharmony_ci 1334514f5e3Sopenharmony_ci Circuit *circuit_ {nullptr}; 1344514f5e3Sopenharmony_ci ChunkMap<GateRef, GateRef> replacements_; 1354514f5e3Sopenharmony_ci ChunkMap<GateRef, VirtualObject*> gateToVirtualObject_; 1364514f5e3Sopenharmony_ci ChunkMap<GateRef, State> gateToState_; 1374514f5e3Sopenharmony_ci GateRef replaceGate_ {Circuit::NullGate()}; 1384514f5e3Sopenharmony_ci Chunk* chunk_; 1394514f5e3Sopenharmony_ci bool isTraced_; 1404514f5e3Sopenharmony_ci}; 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_ci}; 1434514f5e3Sopenharmony_ci 1444514f5e3Sopenharmony_ci#endif