14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 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_EARLY_ELIMINATION_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_EARLY_ELIMINATION_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder.h"
204514f5e3Sopenharmony_ci#include "ecmascript/compiler/combined_pass_visitor.h"
214514f5e3Sopenharmony_ci#include "ecmascript/compiler/gate_accessor.h"
224514f5e3Sopenharmony_ci#include "ecmascript/mem/chunk_containers.h"
234514f5e3Sopenharmony_ci
244514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
254514f5e3Sopenharmony_ciclass EarlyElimination;
264514f5e3Sopenharmony_ci
274514f5e3Sopenharmony_ciclass DependInfoNode : public ChunkObject {
284514f5e3Sopenharmony_cipublic:
294514f5e3Sopenharmony_ci    DependInfoNode(Chunk* chunk) : chunk_(chunk) {}
304514f5e3Sopenharmony_ci    ~DependInfoNode() = default;
314514f5e3Sopenharmony_ci
324514f5e3Sopenharmony_ci    GateRef LookupFrameState() const;
334514f5e3Sopenharmony_ci    GateRef LookupNode(EarlyElimination* elimination, GateRef gate);
344514f5e3Sopenharmony_ci    GateRef LookupCheckedNode(EarlyElimination* elimination, GateRef gate);
354514f5e3Sopenharmony_ci    DependInfoNode* UpdateNode(GateRef gate);
364514f5e3Sopenharmony_ci    DependInfoNode* UpdateFrameState(GateRef framestate);
374514f5e3Sopenharmony_ci    DependInfoNode* UpdateStoreProperty(EarlyElimination* elimination, GateRef gate);
384514f5e3Sopenharmony_ci    bool Equals(DependInfoNode* that);
394514f5e3Sopenharmony_ci    void Merge(EarlyElimination* elimination, DependInfoNode* that);
404514f5e3Sopenharmony_ci    void GetGates(std::vector<GateRef>& gates) const;
414514f5e3Sopenharmony_ci    void CopyFrom(DependInfoNode *other)
424514f5e3Sopenharmony_ci    {
434514f5e3Sopenharmony_ci        head_ = other->head_;
444514f5e3Sopenharmony_ci        size_ = other->size_;
454514f5e3Sopenharmony_ci        frameState_ = other->frameState_;
464514f5e3Sopenharmony_ci    }
474514f5e3Sopenharmony_ciprivate:
484514f5e3Sopenharmony_ci    struct Node {
494514f5e3Sopenharmony_ci        Node(GateRef gate, Node* next) : gate(gate), next(next) {}
504514f5e3Sopenharmony_ci        GateRef gate;
514514f5e3Sopenharmony_ci        Node *next;
524514f5e3Sopenharmony_ci    };
534514f5e3Sopenharmony_ci
544514f5e3Sopenharmony_ci    GateRef frameState_ {Circuit::NullGate()};
554514f5e3Sopenharmony_ci    Node *head_{nullptr};
564514f5e3Sopenharmony_ci    size_t size_ {0};
574514f5e3Sopenharmony_ci    Chunk* chunk_;
584514f5e3Sopenharmony_ci};
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_ciclass EarlyElimination : public PassVisitor {
614514f5e3Sopenharmony_cipublic:
624514f5e3Sopenharmony_ci    EarlyElimination(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk,
634514f5e3Sopenharmony_ci        bool enableMemoryAnalysis, bool enableFrameStateElimination)
644514f5e3Sopenharmony_ci        : PassVisitor(circuit, chunk, visitor), dependChains_(chunk), renames_(chunk),
654514f5e3Sopenharmony_ci          enableMemoryAnalysis_(enableMemoryAnalysis),
664514f5e3Sopenharmony_ci          enableFrameStateElimination_(enableFrameStateElimination) {}
674514f5e3Sopenharmony_ci
684514f5e3Sopenharmony_ci    ~EarlyElimination() = default;
694514f5e3Sopenharmony_ci
704514f5e3Sopenharmony_ci    void Initialize() override;
714514f5e3Sopenharmony_ci    GateRef VisitGate(GateRef gate) override;
724514f5e3Sopenharmony_ci    bool CheckReplacement(GateRef lhs, GateRef rhs);
734514f5e3Sopenharmony_ci    bool CheckRenameReplacement(GateRef lhs, GateRef rhs);
744514f5e3Sopenharmony_ci    bool MayAccessOneMemory(GateRef lhs, GateRef rhs);
754514f5e3Sopenharmony_ci    bool CompareOrder(GateRef lhs, GateRef rhs);
764514f5e3Sopenharmony_ciprivate:
774514f5e3Sopenharmony_ci
784514f5e3Sopenharmony_ci    DependInfoNode* GetDependChain(GateRef dependIn)
794514f5e3Sopenharmony_ci    {
804514f5e3Sopenharmony_ci        size_t idx = acc_.GetId(dependIn);
814514f5e3Sopenharmony_ci        ASSERT(idx <= circuit_->GetMaxGateId());
824514f5e3Sopenharmony_ci        return dependChains_[idx];
834514f5e3Sopenharmony_ci    }
844514f5e3Sopenharmony_ci
854514f5e3Sopenharmony_ci    GateRef VisitDependEntry(GateRef gate);
864514f5e3Sopenharmony_ci    GateRef UpdateDependChain(GateRef gate, DependInfoNode* dependInfo);
874514f5e3Sopenharmony_ci    DependInfoNode* UpdateWrite(GateRef gate, DependInfoNode* dependInfo);
884514f5e3Sopenharmony_ci    GateRef TryEliminateGate(GateRef gate);
894514f5e3Sopenharmony_ci    GateRef TryEliminateFrameState(GateRef gate);
904514f5e3Sopenharmony_ci    GateRef TryEliminateOther(GateRef gate);
914514f5e3Sopenharmony_ci    GateRef TryEliminateDependSelector(GateRef gate);
924514f5e3Sopenharmony_ci    DependInfoNode* GetLoopDependInfo(GateRef depend);
934514f5e3Sopenharmony_ci    GateRef Rename(GateRef gate);
944514f5e3Sopenharmony_ci
954514f5e3Sopenharmony_ci    ChunkVector<DependInfoNode*> dependChains_;
964514f5e3Sopenharmony_ci    ChunkVector<GateRef> renames_;
974514f5e3Sopenharmony_ci    bool enableMemoryAnalysis_ {true};
984514f5e3Sopenharmony_ci    bool enableFrameStateElimination_ {true};
994514f5e3Sopenharmony_ci};
1004514f5e3Sopenharmony_ci}  // panda::ecmascript::kungfu
1014514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_COMPILER_EARLY_ELIMINATION_H
102