1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#ifndef COMPILER_OPTIMIZER_OPTIMIZATIONS_CLEANUP_H
17b1994897Sopenharmony_ci#define COMPILER_OPTIMIZER_OPTIMIZATIONS_CLEANUP_H
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ci#include "optimizer/ir/graph.h"
20b1994897Sopenharmony_ci#include "optimizer/pass.h"
21b1994897Sopenharmony_ci
22b1994897Sopenharmony_cinamespace panda::compiler {
23b1994897Sopenharmony_ciclass Cleanup final : public Optimization {
24b1994897Sopenharmony_cipublic:
25b1994897Sopenharmony_ci    explicit Cleanup(Graph *graph)
26b1994897Sopenharmony_ci        : Optimization(graph),
27b1994897Sopenharmony_ci          empty1_(graph->GetLocalAllocator()->Adapter()),
28b1994897Sopenharmony_ci          empty2_(graph->GetLocalAllocator()->Adapter()),
29b1994897Sopenharmony_ci          saved_preds_(graph->GetLocalAllocator()->Adapter()),
30b1994897Sopenharmony_ci          dead_(graph->GetLocalAllocator()->Adapter()),
31b1994897Sopenharmony_ci          temp_(graph->GetLocalAllocator()->Adapter()),
32b1994897Sopenharmony_ci          ancestors_(graph->GetLocalAllocator()->Adapter()),
33b1994897Sopenharmony_ci          buckets_(graph->GetLocalAllocator()->Adapter()),
34b1994897Sopenharmony_ci          idoms_(graph->GetLocalAllocator()->Adapter()),
35b1994897Sopenharmony_ci          labels_(graph->GetLocalAllocator()->Adapter()),
36b1994897Sopenharmony_ci          parents_(graph->GetLocalAllocator()->Adapter()),
37b1994897Sopenharmony_ci          semi_(graph->GetLocalAllocator()->Adapter()),
38b1994897Sopenharmony_ci          vertices_(graph->GetLocalAllocator()->Adapter()),
39b1994897Sopenharmony_ci          map_(graph->GetLocalAllocator()->Adapter())
40b1994897Sopenharmony_ci    {
41b1994897Sopenharmony_ci    }
42b1994897Sopenharmony_ci
43b1994897Sopenharmony_ci    NO_MOVE_SEMANTIC(Cleanup);
44b1994897Sopenharmony_ci    NO_COPY_SEMANTIC(Cleanup);
45b1994897Sopenharmony_ci    ~Cleanup() override = default;
46b1994897Sopenharmony_ci
47b1994897Sopenharmony_ci    bool RunImpl() override;
48b1994897Sopenharmony_ci
49b1994897Sopenharmony_ci    const char *GetPassName() const override
50b1994897Sopenharmony_ci    {
51b1994897Sopenharmony_ci        return "Cleanup";
52b1994897Sopenharmony_ci    }
53b1994897Sopenharmony_ci
54b1994897Sopenharmony_ci    void InvalidateAnalyses() override;
55b1994897Sopenharmony_ci
56b1994897Sopenharmony_ciprivate:
57b1994897Sopenharmony_ci    bool RunOnce(ArenaSet<BasicBlock *> *empty_blocks, ArenaSet<BasicBlock *> *new_empty_blocks, bool simple_dce);
58b1994897Sopenharmony_ci    void RemoveDeadPhi(BasicBlock *bb, ArenaSet<BasicBlock *> *new_empty_blocks);
59b1994897Sopenharmony_ci    bool ProcessBB(BasicBlock *bb, Marker dead_mrk, ArenaSet<BasicBlock *> *new_empty_blocks);
60b1994897Sopenharmony_ci    bool CheckSpecialTriangle(BasicBlock *bb);
61b1994897Sopenharmony_ci
62b1994897Sopenharmony_ci    void MarkLiveRec(Marker live_mrk, Inst *inst);
63b1994897Sopenharmony_ci    bool Dce(Marker dead_mrk, ArenaSet<BasicBlock *> *new_empty_blocks);
64b1994897Sopenharmony_ci
65b1994897Sopenharmony_ci    void SetLiveRec(Inst *inst, Marker mrk, Marker live_mrk);
66b1994897Sopenharmony_ci    void LiveUserSearchRec(Inst *inst, Marker mrk, Marker live_mrk, Marker dead_mrk);
67b1994897Sopenharmony_ci    bool SimpleDce(Marker dead_mrk, ArenaSet<BasicBlock *> *new_empty_blocks);
68b1994897Sopenharmony_ci    void Marking(Marker dead_mrk, Marker mrk, Marker live_mrk);
69b1994897Sopenharmony_ci    bool Removal(ArenaSet<BasicBlock *> *new_empty_blocks);
70b1994897Sopenharmony_ci
71b1994897Sopenharmony_ci    bool PhiChecker();
72b1994897Sopenharmony_ci    void BuildDominators();
73b1994897Sopenharmony_ci
74b1994897Sopenharmony_ci    ArenaSet<BasicBlock *> empty1_;
75b1994897Sopenharmony_ci    ArenaSet<BasicBlock *> empty2_;
76b1994897Sopenharmony_ci    ArenaVector<BasicBlock *> saved_preds_;
77b1994897Sopenharmony_ci    InstVector dead_;
78b1994897Sopenharmony_ci    InstVector temp_;
79b1994897Sopenharmony_ci
80b1994897Sopenharmony_ci    InstVector ancestors_;
81b1994897Sopenharmony_ci    ArenaVector<InstVector> buckets_;
82b1994897Sopenharmony_ci    InstVector idoms_;
83b1994897Sopenharmony_ci    InstVector labels_;
84b1994897Sopenharmony_ci    InstVector parents_;
85b1994897Sopenharmony_ci    ArenaVector<int32_t> semi_;
86b1994897Sopenharmony_ci    InstVector vertices_;
87b1994897Sopenharmony_ci    ArenaUnorderedMap<Inst *, uint32_t> map_;
88b1994897Sopenharmony_ci
89b1994897Sopenharmony_ci    Inst *fake_root_ {nullptr};
90b1994897Sopenharmony_ci    static constexpr int32_t DEFAULT_DFS_VAL = 0;
91b1994897Sopenharmony_ci    // number of the inst according to the order it is reached during the DFS
92b1994897Sopenharmony_ci    int32_t dfs_num_ {DEFAULT_DFS_VAL};
93b1994897Sopenharmony_ci
94b1994897Sopenharmony_ci    inline uint32_t GetInstId(Inst *inst) const
95b1994897Sopenharmony_ci    {
96b1994897Sopenharmony_ci        ASSERT(map_.count(inst) > 0);
97b1994897Sopenharmony_ci        return map_.at(inst);
98b1994897Sopenharmony_ci    }
99b1994897Sopenharmony_ci
100b1994897Sopenharmony_ci    /*
101b1994897Sopenharmony_ci     * The immediate dominator of 'inst'
102b1994897Sopenharmony_ci     */
103b1994897Sopenharmony_ci    void SetIdom(Inst *inst, Inst *idom)
104b1994897Sopenharmony_ci    {
105b1994897Sopenharmony_ci        idoms_[GetInstId(inst)] = idom;
106b1994897Sopenharmony_ci    }
107b1994897Sopenharmony_ci    Inst *GetIdom(Inst *inst) const
108b1994897Sopenharmony_ci    {
109b1994897Sopenharmony_ci        return idoms_[GetInstId(inst)];
110b1994897Sopenharmony_ci    }
111b1994897Sopenharmony_ci
112b1994897Sopenharmony_ci    /*
113b1994897Sopenharmony_ci     * The ancestor of 'inst', fake_root_ for non-phi
114b1994897Sopenharmony_ci     */
115b1994897Sopenharmony_ci    void SetAncestor(Inst *inst, Inst *anc)
116b1994897Sopenharmony_ci    {
117b1994897Sopenharmony_ci        ancestors_[GetInstId(inst)] = anc;
118b1994897Sopenharmony_ci    }
119b1994897Sopenharmony_ci    Inst *GetAncestor(Inst *inst) const
120b1994897Sopenharmony_ci    {
121b1994897Sopenharmony_ci        return ancestors_[GetInstId(inst)];
122b1994897Sopenharmony_ci    }
123b1994897Sopenharmony_ci
124b1994897Sopenharmony_ci    /*
125b1994897Sopenharmony_ci     * A set of instructions whose semidominator is 'inst'
126b1994897Sopenharmony_ci     */
127b1994897Sopenharmony_ci    InstVector &GetBucket(Inst *inst)
128b1994897Sopenharmony_ci    {
129b1994897Sopenharmony_ci        return buckets_[GetInstId(inst)];
130b1994897Sopenharmony_ci    }
131b1994897Sopenharmony_ci
132b1994897Sopenharmony_ci    /*
133b1994897Sopenharmony_ci     * The inst in the ancestors chain with the minimal semidominator DFS-number for 'inst'
134b1994897Sopenharmony_ci     */
135b1994897Sopenharmony_ci    void SetLabel(Inst *inst, Inst *label)
136b1994897Sopenharmony_ci    {
137b1994897Sopenharmony_ci        labels_[GetInstId(inst)] = label;
138b1994897Sopenharmony_ci    }
139b1994897Sopenharmony_ci    Inst *GetLabel(Inst *inst) const
140b1994897Sopenharmony_ci    {
141b1994897Sopenharmony_ci        return labels_[GetInstId(inst)];
142b1994897Sopenharmony_ci    }
143b1994897Sopenharmony_ci
144b1994897Sopenharmony_ci    /*
145b1994897Sopenharmony_ci     * The parent of 'inst' in the spanning tree generated by DFS
146b1994897Sopenharmony_ci     */
147b1994897Sopenharmony_ci    void SetParent(Inst *inst, Inst *parent)
148b1994897Sopenharmony_ci    {
149b1994897Sopenharmony_ci        parents_[GetInstId(inst)] = parent;
150b1994897Sopenharmony_ci    }
151b1994897Sopenharmony_ci    Inst *GetParent(Inst *inst) const
152b1994897Sopenharmony_ci    {
153b1994897Sopenharmony_ci        return parents_[GetInstId(inst)];
154b1994897Sopenharmony_ci    }
155b1994897Sopenharmony_ci
156b1994897Sopenharmony_ci    /*
157b1994897Sopenharmony_ci     * The DFS-number of the semidominator of 'inst'
158b1994897Sopenharmony_ci     */
159b1994897Sopenharmony_ci    void SetSemi(Inst *inst, int32_t value)
160b1994897Sopenharmony_ci    {
161b1994897Sopenharmony_ci        semi_[GetInstId(inst)] = value;
162b1994897Sopenharmony_ci    }
163b1994897Sopenharmony_ci    int32_t GetSemi(Inst *inst) const
164b1994897Sopenharmony_ci    {
165b1994897Sopenharmony_ci        return semi_[GetInstId(inst)];
166b1994897Sopenharmony_ci    }
167b1994897Sopenharmony_ci
168b1994897Sopenharmony_ci    /*
169b1994897Sopenharmony_ci     * The inst whose DFS-number is 'index'
170b1994897Sopenharmony_ci     */
171b1994897Sopenharmony_ci    void SetVertex(size_t index, Inst *inst)
172b1994897Sopenharmony_ci    {
173b1994897Sopenharmony_ci        vertices_[index] = inst;
174b1994897Sopenharmony_ci    }
175b1994897Sopenharmony_ci    Inst *GetVertex(size_t index) const
176b1994897Sopenharmony_ci    {
177b1994897Sopenharmony_ci        return vertices_[index];
178b1994897Sopenharmony_ci    }
179b1994897Sopenharmony_ci
180b1994897Sopenharmony_ci    void AdjustImmediateDominators(Inst *inst);
181b1994897Sopenharmony_ci    void ComputeImmediateDominators(Inst *inst);
182b1994897Sopenharmony_ci    void Compress(Inst *inst);
183b1994897Sopenharmony_ci    void DfsNumbering(Inst *inst);
184b1994897Sopenharmony_ci    Inst *Eval(Inst *inst);
185b1994897Sopenharmony_ci    void Init(size_t count);
186b1994897Sopenharmony_ci};
187b1994897Sopenharmony_ci}  // namespace panda::compiler
188b1994897Sopenharmony_ci
189b1994897Sopenharmony_ci#endif  // COMPILER_OPTIMIZER_OPTIMIZATIONS_CLEANUP_H
190