1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_COMPILER_COMBINED_PASS_VISITOR_H
17#define ECMASCRIPT_COMPILER_COMBINED_PASS_VISITOR_H
18
19#include "ecmascript/compiler/circuit_builder.h"
20#include "ecmascript/compiler/gate_accessor.h"
21#include "ecmascript/mem/chunk_containers.h"
22
23namespace panda::ecmascript::kungfu {
24
25class RPOVisitor {
26public:
27    virtual ~RPOVisitor() = default;
28    virtual int32_t GetGateOrder(GateRef gate) = 0;
29    virtual void SetGateOrder(GateRef gate, int32_t orderId) = 0;
30    virtual void Resize(int32_t size, int32_t num) = 0;
31    virtual void ReVisitGate(GateRef gate) = 0;
32    virtual void LogicallyReplaceGate(GateRef gate, GateRef replacement) = 0;
33    virtual void RelaxStateAndDepend(GateRef gate) = 0;
34    virtual void ReplaceGate(GateRef gate, GateRef replacement) = 0;
35    virtual void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement) = 0;
36};
37
38class PassVisitor {
39public:
40    PassVisitor(Circuit* circuit, Chunk* chunk, RPOVisitor* visitor)
41        : circuit_(circuit), acc_(circuit), chunk_(chunk), visitor_(visitor) {}
42    virtual ~PassVisitor() = default;
43
44    virtual GateRef VisitGate(GateRef gate) = 0;
45    virtual void Initialize() {}
46    virtual void Finalize() {}
47protected:
48    void ReplaceGate(GateRef gate, GateRef replacement)
49    {
50        visitor_->ReplaceGate(gate, replacement);
51    }
52    void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement)
53    {
54        visitor_->ReplaceGate(gate, stateDepend, replacement);
55    }
56    Circuit* circuit_ {nullptr};
57    GateAccessor acc_;
58    Chunk* chunk_ {nullptr};
59    RPOVisitor* visitor_;
60};
61
62class CombinedPassVisitor : public RPOVisitor {
63public:
64    CombinedPassVisitor(Circuit* circuit, bool enableLog, const std::string& name, Chunk* chunk)
65        : enableLog_(enableLog), methodName_(name), circuit_(circuit), acc_(circuit),
66        chunk_(chunk), workList_(chunk), changedList_(chunk), orderList_(chunk), passList_(chunk) {}
67    virtual ~CombinedPassVisitor() = default;
68    void AddPass(PassVisitor* pass);
69
70    int32_t GetGateOrder(GateRef gate) override;
71    void SetGateOrder(GateRef gate, int32_t orderId) override;
72    void Resize(int32_t size, int32_t num) override;
73
74    void VisitGraph();
75    GateRef VisitGate(GateRef gate);
76    void ReVisitGate(GateRef gate) override;
77    void LogicallyReplaceGate(GateRef gate, GateRef replacement) override;
78    void RelaxStateAndDepend(GateRef gate) override;
79    void ReplaceGate(GateRef gate, GateRef replacement) override;
80    void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement) override;
81    void PrintLog(const std::string& phaseName);
82    void VistDependSelectorForLoop(GateRef gate);
83
84protected:
85
86    void VisitTopGate(Edge& current);
87
88    void PushGate(GateRef gate, size_t index)
89    {
90        workList_.push_back(Edge{gate, index});
91        acc_.SetMark(gate, MarkCode::VISITED);
92    }
93
94    void PushChangedGate(GateRef gate)
95    {
96        changedList_.push_back(gate);
97        acc_.SetMark(gate, MarkCode::PREVISIT);
98    }
99
100    void PopGate(GateRef gate)
101    {
102        workList_.pop_back();
103        acc_.SetMark(gate, MarkCode::FINISHED);
104    }
105
106    Chunk *GetChunk() const
107    {
108        return chunk_;
109    }
110    void PrintStack();
111
112private:
113    bool enableLog_ {false};
114    std::string methodName_;
115    Circuit* circuit_ {nullptr};
116    GateAccessor acc_;
117    Chunk* chunk_ {nullptr};
118    ChunkDeque<Edge> workList_;
119    ChunkDeque<GateRef> changedList_;
120    ChunkVector<int32_t> orderList_;
121    ChunkVector<PassVisitor*> passList_;
122    uint32_t orderCount_ {0};
123};
124}  // panda::ecmascript::kungfu
125#endif  // ECMASCRIPT_COMPILER_COMBINED_PASS_VISITOR_H
126