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_COMPILER_CIRCUIT_BUILDER_HELPER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_HELPER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_cinamespace panda::ecmascript { 224514f5e3Sopenharmony_ci class JSRuntimeOptions; 234514f5e3Sopenharmony_ci} // namespace panda::ecmascript 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_ciclass CompilationConfig { 284514f5e3Sopenharmony_cipublic: 294514f5e3Sopenharmony_ci explicit CompilationConfig(const std::string &triple, const JSRuntimeOptions *options = nullptr); 304514f5e3Sopenharmony_ci ~CompilationConfig() = default; 314514f5e3Sopenharmony_ci 324514f5e3Sopenharmony_ci inline bool Is32Bit() const 334514f5e3Sopenharmony_ci { 344514f5e3Sopenharmony_ci return triple_ == Triple::TRIPLE_ARM32; 354514f5e3Sopenharmony_ci } 364514f5e3Sopenharmony_ci 374514f5e3Sopenharmony_ci inline bool IsAArch64() const 384514f5e3Sopenharmony_ci { 394514f5e3Sopenharmony_ci return triple_ == Triple::TRIPLE_AARCH64; 404514f5e3Sopenharmony_ci } 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_ci inline bool IsAmd64() const 434514f5e3Sopenharmony_ci { 444514f5e3Sopenharmony_ci return triple_ == Triple::TRIPLE_AMD64; 454514f5e3Sopenharmony_ci } 464514f5e3Sopenharmony_ci 474514f5e3Sopenharmony_ci inline bool Is64Bit() const 484514f5e3Sopenharmony_ci { 494514f5e3Sopenharmony_ci return IsAArch64() || IsAmd64(); 504514f5e3Sopenharmony_ci } 514514f5e3Sopenharmony_ci 524514f5e3Sopenharmony_ci Triple GetTriple() const 534514f5e3Sopenharmony_ci { 544514f5e3Sopenharmony_ci return triple_; 554514f5e3Sopenharmony_ci } 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_ci std::string GetTripleStr() const 584514f5e3Sopenharmony_ci { 594514f5e3Sopenharmony_ci return tripleStr_; 604514f5e3Sopenharmony_ci } 614514f5e3Sopenharmony_ci 624514f5e3Sopenharmony_ci bool IsTraceBC() const 634514f5e3Sopenharmony_ci { 644514f5e3Sopenharmony_ci return isTraceBc_; 654514f5e3Sopenharmony_ci } 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_ci bool IsProfiling() const 684514f5e3Sopenharmony_ci { 694514f5e3Sopenharmony_ci return profiling_; 704514f5e3Sopenharmony_ci } 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_ci bool IsStressDeopt() const 734514f5e3Sopenharmony_ci { 744514f5e3Sopenharmony_ci return stressDeopt_; 754514f5e3Sopenharmony_ci } 764514f5e3Sopenharmony_ci 774514f5e3Sopenharmony_ci bool IsVerifyVTbale() const 784514f5e3Sopenharmony_ci { 794514f5e3Sopenharmony_ci return verifyVTable_; 804514f5e3Sopenharmony_ci } 814514f5e3Sopenharmony_ci 824514f5e3Sopenharmony_ci bool IsTypedOpProfiling() const 834514f5e3Sopenharmony_ci { 844514f5e3Sopenharmony_ci return typedOpProfiling_; 854514f5e3Sopenharmony_ci } 864514f5e3Sopenharmony_ci 874514f5e3Sopenharmony_ciprivate: 884514f5e3Sopenharmony_ci inline Triple GetTripleFromString(const std::string &triple) 894514f5e3Sopenharmony_ci { 904514f5e3Sopenharmony_ci if (triple.compare(TARGET_X64) == 0) { 914514f5e3Sopenharmony_ci return Triple::TRIPLE_AMD64; 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci 944514f5e3Sopenharmony_ci if (triple.compare(TARGET_AARCH64) == 0) { 954514f5e3Sopenharmony_ci return Triple::TRIPLE_AARCH64; 964514f5e3Sopenharmony_ci } 974514f5e3Sopenharmony_ci 984514f5e3Sopenharmony_ci if (triple.compare(TARGET_ARM32) == 0) { 994514f5e3Sopenharmony_ci return Triple::TRIPLE_ARM32; 1004514f5e3Sopenharmony_ci } 1014514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "this branch is unreachable"; 1024514f5e3Sopenharmony_ci UNREACHABLE(); 1034514f5e3Sopenharmony_ci } 1044514f5e3Sopenharmony_ci std::string tripleStr_; 1054514f5e3Sopenharmony_ci Triple triple_; 1064514f5e3Sopenharmony_ci bool isTraceBc_ {false}; 1074514f5e3Sopenharmony_ci bool profiling_ {false}; 1084514f5e3Sopenharmony_ci bool stressDeopt_ {false}; 1094514f5e3Sopenharmony_ci bool verifyVTable_ {false}; 1104514f5e3Sopenharmony_ci bool typedOpProfiling_ {false}; 1114514f5e3Sopenharmony_ci}; 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_ciclass Label { 1144514f5e3Sopenharmony_cipublic: 1154514f5e3Sopenharmony_ci Label() = default; 1164514f5e3Sopenharmony_ci explicit Label(Environment *env); 1174514f5e3Sopenharmony_ci explicit Label(CircuitBuilder *cirBuilder); 1184514f5e3Sopenharmony_ci ~Label() = default; 1194514f5e3Sopenharmony_ci Label(Label const &label) = default; 1204514f5e3Sopenharmony_ci Label &operator=(Label const &label) = default; 1214514f5e3Sopenharmony_ci Label(Label &&label) = default; 1224514f5e3Sopenharmony_ci Label &operator=(Label &&label) = default; 1234514f5e3Sopenharmony_ci inline void Seal() 1244514f5e3Sopenharmony_ci { 1254514f5e3Sopenharmony_ci return impl_->Seal(); 1264514f5e3Sopenharmony_ci } 1274514f5e3Sopenharmony_ci inline void WriteVariable(Variable *var, GateRef value) 1284514f5e3Sopenharmony_ci { 1294514f5e3Sopenharmony_ci impl_->WriteVariable(var, value); 1304514f5e3Sopenharmony_ci } 1314514f5e3Sopenharmony_ci inline GateRef ReadVariable(Variable *var) 1324514f5e3Sopenharmony_ci { 1334514f5e3Sopenharmony_ci return impl_->ReadVariable(var); 1344514f5e3Sopenharmony_ci } 1354514f5e3Sopenharmony_ci inline void Bind() 1364514f5e3Sopenharmony_ci { 1374514f5e3Sopenharmony_ci impl_->Bind(); 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci inline void MergeAllControl() 1404514f5e3Sopenharmony_ci { 1414514f5e3Sopenharmony_ci impl_->MergeAllControl(); 1424514f5e3Sopenharmony_ci } 1434514f5e3Sopenharmony_ci inline void MergeAllDepend() 1444514f5e3Sopenharmony_ci { 1454514f5e3Sopenharmony_ci impl_->MergeAllDepend(); 1464514f5e3Sopenharmony_ci } 1474514f5e3Sopenharmony_ci inline void AppendPredecessor(const Label *predecessor) 1484514f5e3Sopenharmony_ci { 1494514f5e3Sopenharmony_ci impl_->AppendPredecessor(predecessor->GetRawLabel()); 1504514f5e3Sopenharmony_ci } 1514514f5e3Sopenharmony_ci inline std::vector<Label> GetPredecessors() const 1524514f5e3Sopenharmony_ci { 1534514f5e3Sopenharmony_ci std::vector<Label> labels; 1544514f5e3Sopenharmony_ci for (auto rawlabel : impl_->GetPredecessors()) { 1554514f5e3Sopenharmony_ci labels.emplace_back(Label(rawlabel)); 1564514f5e3Sopenharmony_ci } 1574514f5e3Sopenharmony_ci return labels; 1584514f5e3Sopenharmony_ci } 1594514f5e3Sopenharmony_ci inline void SetControl(GateRef control) 1604514f5e3Sopenharmony_ci { 1614514f5e3Sopenharmony_ci impl_->SetControl(control); 1624514f5e3Sopenharmony_ci } 1634514f5e3Sopenharmony_ci inline void SetPreControl(GateRef control) 1644514f5e3Sopenharmony_ci { 1654514f5e3Sopenharmony_ci impl_->SetPreControl(control); 1664514f5e3Sopenharmony_ci } 1674514f5e3Sopenharmony_ci inline void MergeControl(GateRef control) 1684514f5e3Sopenharmony_ci { 1694514f5e3Sopenharmony_ci impl_->MergeControl(control); 1704514f5e3Sopenharmony_ci } 1714514f5e3Sopenharmony_ci inline GateRef GetControl() const 1724514f5e3Sopenharmony_ci { 1734514f5e3Sopenharmony_ci return impl_->GetControl(); 1744514f5e3Sopenharmony_ci } 1754514f5e3Sopenharmony_ci inline GateRef GetDepend() const 1764514f5e3Sopenharmony_ci { 1774514f5e3Sopenharmony_ci return impl_->GetDepend(); 1784514f5e3Sopenharmony_ci } 1794514f5e3Sopenharmony_ci inline void SetDepend(GateRef depend) 1804514f5e3Sopenharmony_ci { 1814514f5e3Sopenharmony_ci return impl_->SetDepend(depend); 1824514f5e3Sopenharmony_ci } 1834514f5e3Sopenharmony_ci 1844514f5e3Sopenharmony_ciprivate: 1854514f5e3Sopenharmony_ci class LabelImpl { 1864514f5e3Sopenharmony_ci public: 1874514f5e3Sopenharmony_ci LabelImpl(Environment *env, GateRef control) 1884514f5e3Sopenharmony_ci : env_(env), control_(control), predeControl_(-1), isSealed_(false) 1894514f5e3Sopenharmony_ci { 1904514f5e3Sopenharmony_ci } 1914514f5e3Sopenharmony_ci ~LabelImpl() = default; 1924514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(LabelImpl); 1934514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(LabelImpl); 1944514f5e3Sopenharmony_ci void Seal(); 1954514f5e3Sopenharmony_ci void WriteVariable(Variable *var, GateRef value); 1964514f5e3Sopenharmony_ci GateRef ReadVariable(Variable *var); 1974514f5e3Sopenharmony_ci void Bind(); 1984514f5e3Sopenharmony_ci void MergeAllControl(); 1994514f5e3Sopenharmony_ci void MergeAllDepend(); 2004514f5e3Sopenharmony_ci void AppendPredecessor(LabelImpl *predecessor); 2014514f5e3Sopenharmony_ci std::vector<LabelImpl *> GetPredecessors() const 2024514f5e3Sopenharmony_ci { 2034514f5e3Sopenharmony_ci return predecessors_; 2044514f5e3Sopenharmony_ci } 2054514f5e3Sopenharmony_ci void SetControl(GateRef control) 2064514f5e3Sopenharmony_ci { 2074514f5e3Sopenharmony_ci control_ = control; 2084514f5e3Sopenharmony_ci } 2094514f5e3Sopenharmony_ci void SetPreControl(GateRef control) 2104514f5e3Sopenharmony_ci { 2114514f5e3Sopenharmony_ci predeControl_ = control; 2124514f5e3Sopenharmony_ci } 2134514f5e3Sopenharmony_ci void MergeControl(GateRef control) 2144514f5e3Sopenharmony_ci { 2154514f5e3Sopenharmony_ci if (predeControl_ == Circuit::NullGate()) { 2164514f5e3Sopenharmony_ci predeControl_ = control; 2174514f5e3Sopenharmony_ci control_ = predeControl_; 2184514f5e3Sopenharmony_ci } else { 2194514f5e3Sopenharmony_ci otherPredeControls_.push_back(control); 2204514f5e3Sopenharmony_ci } 2214514f5e3Sopenharmony_ci } 2224514f5e3Sopenharmony_ci GateRef GetControl() const 2234514f5e3Sopenharmony_ci { 2244514f5e3Sopenharmony_ci return control_; 2254514f5e3Sopenharmony_ci } 2264514f5e3Sopenharmony_ci void SetDepend(GateRef depend) 2274514f5e3Sopenharmony_ci { 2284514f5e3Sopenharmony_ci depend_ = depend; 2294514f5e3Sopenharmony_ci } 2304514f5e3Sopenharmony_ci GateRef GetDepend() const 2314514f5e3Sopenharmony_ci { 2324514f5e3Sopenharmony_ci return depend_; 2334514f5e3Sopenharmony_ci } 2344514f5e3Sopenharmony_ci 2354514f5e3Sopenharmony_ci private: 2364514f5e3Sopenharmony_ci bool IsNeedSeal() const; 2374514f5e3Sopenharmony_ci bool IsSealed() const 2384514f5e3Sopenharmony_ci { 2394514f5e3Sopenharmony_ci return isSealed_; 2404514f5e3Sopenharmony_ci } 2414514f5e3Sopenharmony_ci bool IsLoopHead() const; 2424514f5e3Sopenharmony_ci bool IsControlCase() const; 2434514f5e3Sopenharmony_ci GateRef ReadVariableRecursive(Variable *var); 2444514f5e3Sopenharmony_ci Environment *env_; 2454514f5e3Sopenharmony_ci GateRef control_; 2464514f5e3Sopenharmony_ci GateRef predeControl_ {Circuit::NullGate()}; 2474514f5e3Sopenharmony_ci GateRef depend_ {Circuit::NullGate()}; 2484514f5e3Sopenharmony_ci GateRef loopDepend_ {Circuit::NullGate()}; 2494514f5e3Sopenharmony_ci std::vector<GateRef> otherPredeControls_; 2504514f5e3Sopenharmony_ci bool isSealed_ {false}; 2514514f5e3Sopenharmony_ci std::map<Variable *, GateRef> valueMap_; 2524514f5e3Sopenharmony_ci std::vector<GateRef> phi; 2534514f5e3Sopenharmony_ci std::vector<LabelImpl *> predecessors_; 2544514f5e3Sopenharmony_ci std::map<Variable *, GateRef> incompletePhis_; 2554514f5e3Sopenharmony_ci }; 2564514f5e3Sopenharmony_ci 2574514f5e3Sopenharmony_ci explicit Label(LabelImpl *impl) : impl_(impl) {} 2584514f5e3Sopenharmony_ci friend class Environment; 2594514f5e3Sopenharmony_ci LabelImpl *GetRawLabel() const 2604514f5e3Sopenharmony_ci { 2614514f5e3Sopenharmony_ci return impl_; 2624514f5e3Sopenharmony_ci } 2634514f5e3Sopenharmony_ci LabelImpl *impl_ {nullptr}; 2644514f5e3Sopenharmony_ci}; 2654514f5e3Sopenharmony_ci 2664514f5e3Sopenharmony_ciclass Environment { 2674514f5e3Sopenharmony_cipublic: 2684514f5e3Sopenharmony_ci using LabelImpl = Label::LabelImpl; 2694514f5e3Sopenharmony_ci Environment(GateRef hir, Circuit *circuit, CircuitBuilder *builder); 2704514f5e3Sopenharmony_ci Environment(GateRef stateEntry, GateRef dependEntry, const std::initializer_list<GateRef>& args, 2714514f5e3Sopenharmony_ci Circuit *circuit, CircuitBuilder *builder); 2724514f5e3Sopenharmony_ci Environment(size_t arguments, CircuitBuilder *builder); 2734514f5e3Sopenharmony_ci ~Environment(); 2744514f5e3Sopenharmony_ci Label *GetCurrentLabel() const 2754514f5e3Sopenharmony_ci { 2764514f5e3Sopenharmony_ci return currentLabel_; 2774514f5e3Sopenharmony_ci } 2784514f5e3Sopenharmony_ci void SetCurrentLabel(Label *label) 2794514f5e3Sopenharmony_ci { 2804514f5e3Sopenharmony_ci currentLabel_ = label; 2814514f5e3Sopenharmony_ci } 2824514f5e3Sopenharmony_ci CircuitBuilder *GetBuilder() const 2834514f5e3Sopenharmony_ci { 2844514f5e3Sopenharmony_ci return circuitBuilder_; 2854514f5e3Sopenharmony_ci } 2864514f5e3Sopenharmony_ci Circuit *GetCircuit() const 2874514f5e3Sopenharmony_ci { 2884514f5e3Sopenharmony_ci return circuit_; 2894514f5e3Sopenharmony_ci } 2904514f5e3Sopenharmony_ci int NextVariableId() 2914514f5e3Sopenharmony_ci { 2924514f5e3Sopenharmony_ci return nextVariableId_++; 2934514f5e3Sopenharmony_ci } 2944514f5e3Sopenharmony_ci void SetCompilationConfig(const CompilationConfig *cfg) 2954514f5e3Sopenharmony_ci { 2964514f5e3Sopenharmony_ci ccfg_ = cfg; 2974514f5e3Sopenharmony_ci } 2984514f5e3Sopenharmony_ci const CompilationConfig *GetCompilationConfig() const 2994514f5e3Sopenharmony_ci { 3004514f5e3Sopenharmony_ci return ccfg_; 3014514f5e3Sopenharmony_ci } 3024514f5e3Sopenharmony_ci inline bool Is32Bit() const 3034514f5e3Sopenharmony_ci { 3044514f5e3Sopenharmony_ci return ccfg_->Is32Bit(); 3054514f5e3Sopenharmony_ci } 3064514f5e3Sopenharmony_ci inline bool IsAArch64() const 3074514f5e3Sopenharmony_ci { 3084514f5e3Sopenharmony_ci return ccfg_->IsAArch64(); 3094514f5e3Sopenharmony_ci } 3104514f5e3Sopenharmony_ci inline bool IsAmd64() const 3114514f5e3Sopenharmony_ci { 3124514f5e3Sopenharmony_ci return ccfg_->IsAmd64(); 3134514f5e3Sopenharmony_ci } 3144514f5e3Sopenharmony_ci inline bool IsArch64Bit() const 3154514f5e3Sopenharmony_ci { 3164514f5e3Sopenharmony_ci return ccfg_->IsAmd64() || ccfg_->IsAArch64(); 3174514f5e3Sopenharmony_ci } 3184514f5e3Sopenharmony_ci inline bool IsAsmInterp() const 3194514f5e3Sopenharmony_ci { 3204514f5e3Sopenharmony_ci return circuit_->GetFrameType() == FrameType::ASM_INTERPRETER_FRAME; 3214514f5e3Sopenharmony_ci } 3224514f5e3Sopenharmony_ci inline bool IsBaselineBuiltin() const 3234514f5e3Sopenharmony_ci { 3244514f5e3Sopenharmony_ci return circuit_->GetFrameType() == FrameType::BASELINE_BUILTIN_FRAME; 3254514f5e3Sopenharmony_ci } 3264514f5e3Sopenharmony_ci inline bool IsArch32Bit() const 3274514f5e3Sopenharmony_ci { 3284514f5e3Sopenharmony_ci return ccfg_->Is32Bit(); 3294514f5e3Sopenharmony_ci } 3304514f5e3Sopenharmony_ci inline GateRef GetArgument(size_t index) const 3314514f5e3Sopenharmony_ci { 3324514f5e3Sopenharmony_ci return arguments_.at(index); 3334514f5e3Sopenharmony_ci } 3344514f5e3Sopenharmony_ci inline Label GetLabelFromSelector(GateRef sel) 3354514f5e3Sopenharmony_ci { 3364514f5e3Sopenharmony_ci Label::LabelImpl *rawlabel = phiToLabels_[sel]; 3374514f5e3Sopenharmony_ci return Label(rawlabel); 3384514f5e3Sopenharmony_ci } 3394514f5e3Sopenharmony_ci inline void AddSelectorToLabel(GateRef sel, Label label) 3404514f5e3Sopenharmony_ci { 3414514f5e3Sopenharmony_ci phiToLabels_[sel] = label.GetRawLabel(); 3424514f5e3Sopenharmony_ci } 3434514f5e3Sopenharmony_ci inline LabelImpl *NewLabel(Environment *env, GateRef control = -1) 3444514f5e3Sopenharmony_ci { 3454514f5e3Sopenharmony_ci auto impl = new Label::LabelImpl(env, control); 3464514f5e3Sopenharmony_ci rawLabels_.emplace_back(impl); 3474514f5e3Sopenharmony_ci return impl; 3484514f5e3Sopenharmony_ci } 3494514f5e3Sopenharmony_ci void SubCfgEntry(Label *entry) 3504514f5e3Sopenharmony_ci { 3514514f5e3Sopenharmony_ci if (currentLabel_ != nullptr) { 3524514f5e3Sopenharmony_ci GateRef control = currentLabel_->GetControl(); 3534514f5e3Sopenharmony_ci GateRef depend = currentLabel_->GetDepend(); 3544514f5e3Sopenharmony_ci stack_.push(currentLabel_); 3554514f5e3Sopenharmony_ci currentLabel_ = entry; 3564514f5e3Sopenharmony_ci currentLabel_->SetControl(control); 3574514f5e3Sopenharmony_ci currentLabel_->SetDepend(depend); 3584514f5e3Sopenharmony_ci } 3594514f5e3Sopenharmony_ci } 3604514f5e3Sopenharmony_ci void SubCfgExit() 3614514f5e3Sopenharmony_ci { 3624514f5e3Sopenharmony_ci if (currentLabel_ != nullptr) { 3634514f5e3Sopenharmony_ci GateRef control = currentLabel_->GetControl(); 3644514f5e3Sopenharmony_ci GateRef depend = currentLabel_->GetDepend(); 3654514f5e3Sopenharmony_ci if (!stack_.empty()) { 3664514f5e3Sopenharmony_ci currentLabel_ = stack_.top(); 3674514f5e3Sopenharmony_ci currentLabel_->SetControl(control); 3684514f5e3Sopenharmony_ci currentLabel_->SetDepend(depend); 3694514f5e3Sopenharmony_ci stack_.pop(); 3704514f5e3Sopenharmony_ci } 3714514f5e3Sopenharmony_ci } 3724514f5e3Sopenharmony_ci } 3734514f5e3Sopenharmony_ci inline GateRef GetInput(size_t index) const 3744514f5e3Sopenharmony_ci { 3754514f5e3Sopenharmony_ci return inputList_.at(index); 3764514f5e3Sopenharmony_ci } 3774514f5e3Sopenharmony_ci 3784514f5e3Sopenharmony_ciprivate: 3794514f5e3Sopenharmony_ci Label *currentLabel_ {nullptr}; 3804514f5e3Sopenharmony_ci Circuit *circuit_ {nullptr}; 3814514f5e3Sopenharmony_ci CircuitBuilder *circuitBuilder_ {nullptr}; 3824514f5e3Sopenharmony_ci std::unordered_map<GateRef, LabelImpl *> phiToLabels_; 3834514f5e3Sopenharmony_ci std::vector<GateRef> inputList_; 3844514f5e3Sopenharmony_ci Label entry_; 3854514f5e3Sopenharmony_ci std::vector<LabelImpl *> rawLabels_; 3864514f5e3Sopenharmony_ci std::stack<Label *> stack_; 3874514f5e3Sopenharmony_ci int nextVariableId_ {0}; 3884514f5e3Sopenharmony_ci std::vector<GateRef> arguments_; 3894514f5e3Sopenharmony_ci const CompilationConfig *ccfg_ {nullptr}; 3904514f5e3Sopenharmony_ci}; 3914514f5e3Sopenharmony_ci 3924514f5e3Sopenharmony_ciclass Variable { 3934514f5e3Sopenharmony_cipublic: 3944514f5e3Sopenharmony_ci Variable(Environment *env, VariableType type, uint32_t id, GateRef value) : id_(id), type_(type), env_(env) 3954514f5e3Sopenharmony_ci { 3964514f5e3Sopenharmony_ci Bind(value); 3974514f5e3Sopenharmony_ci env_->GetCurrentLabel()->WriteVariable(this, value); 3984514f5e3Sopenharmony_ci } 3994514f5e3Sopenharmony_ci Variable(CircuitBuilder *cirbuilder, VariableType type, uint32_t id, GateRef value) 4004514f5e3Sopenharmony_ci : id_(id), type_(type), env_(cirbuilder->GetCurrentEnvironment()) 4014514f5e3Sopenharmony_ci { 4024514f5e3Sopenharmony_ci Bind(value); 4034514f5e3Sopenharmony_ci env_->GetCurrentLabel()->WriteVariable(this, value); 4044514f5e3Sopenharmony_ci } 4054514f5e3Sopenharmony_ci ~Variable() = default; 4064514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(Variable); 4074514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(Variable); 4084514f5e3Sopenharmony_ci void Bind(GateRef value) 4094514f5e3Sopenharmony_ci { 4104514f5e3Sopenharmony_ci currentValue_ = value; 4114514f5e3Sopenharmony_ci } 4124514f5e3Sopenharmony_ci GateRef Value() const 4134514f5e3Sopenharmony_ci { 4144514f5e3Sopenharmony_ci return currentValue_; 4154514f5e3Sopenharmony_ci } 4164514f5e3Sopenharmony_ci VariableType Type() const 4174514f5e3Sopenharmony_ci { 4184514f5e3Sopenharmony_ci return type_; 4194514f5e3Sopenharmony_ci } 4204514f5e3Sopenharmony_ci bool IsBound() const 4214514f5e3Sopenharmony_ci { 4224514f5e3Sopenharmony_ci return currentValue_ != 0; 4234514f5e3Sopenharmony_ci } 4244514f5e3Sopenharmony_ci Variable &operator=(const GateRef value) 4254514f5e3Sopenharmony_ci { 4264514f5e3Sopenharmony_ci env_->GetCurrentLabel()->WriteVariable(this, value); 4274514f5e3Sopenharmony_ci Bind(value); 4284514f5e3Sopenharmony_ci return *this; 4294514f5e3Sopenharmony_ci } 4304514f5e3Sopenharmony_ci GateRef operator*() 4314514f5e3Sopenharmony_ci { 4324514f5e3Sopenharmony_ci return env_->GetCurrentLabel()->ReadVariable(this); 4334514f5e3Sopenharmony_ci } 4344514f5e3Sopenharmony_ci GateRef ReadVariable() 4354514f5e3Sopenharmony_ci { 4364514f5e3Sopenharmony_ci return env_->GetCurrentLabel()->ReadVariable(this); 4374514f5e3Sopenharmony_ci } 4384514f5e3Sopenharmony_ci void WriteVariable(GateRef value) 4394514f5e3Sopenharmony_ci { 4404514f5e3Sopenharmony_ci env_->GetCurrentLabel()->WriteVariable(this, value); 4414514f5e3Sopenharmony_ci Bind(value); 4424514f5e3Sopenharmony_ci } 4434514f5e3Sopenharmony_ci GateRef AddPhiOperand(GateRef val); 4444514f5e3Sopenharmony_ci GateRef AddOperandToSelector(GateRef val, size_t idx, GateRef in); 4454514f5e3Sopenharmony_ci GateRef TryRemoveTrivialPhi(GateRef phi); 4464514f5e3Sopenharmony_ci uint32_t GetId() const 4474514f5e3Sopenharmony_ci { 4484514f5e3Sopenharmony_ci return id_; 4494514f5e3Sopenharmony_ci } 4504514f5e3Sopenharmony_ci 4514514f5e3Sopenharmony_ciprivate: 4524514f5e3Sopenharmony_ci Circuit* GetCircuit() const 4534514f5e3Sopenharmony_ci { 4544514f5e3Sopenharmony_ci return env_->GetCircuit(); 4554514f5e3Sopenharmony_ci } 4564514f5e3Sopenharmony_ci 4574514f5e3Sopenharmony_ci uint32_t id_; 4584514f5e3Sopenharmony_ci VariableType type_; 4594514f5e3Sopenharmony_ci GateRef currentValue_ {0}; 4604514f5e3Sopenharmony_ci Environment *env_; 4614514f5e3Sopenharmony_ci}; 4624514f5e3Sopenharmony_ci 4634514f5e3Sopenharmony_ci} 4644514f5e3Sopenharmony_ci 4654514f5e3Sopenharmony_ci#endif // ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H 466