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