• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "ecmascript/compiler/useless_gate_elimination.h"
17 
18 namespace panda::ecmascript::kungfu {
19 
PushGate(GateRef gate)20 void UselessGateElimination::PushGate(GateRef gate)
21 {
22     workList_.push_back(gate);
23     acc_.SetMark(gate, MarkCode::VISITED);
24 }
25 
InitList()26 void UselessGateElimination::InitList()
27 {
28     circuit_->AdvanceTime();
29     GateRef returnList = acc_.GetReturnRoot();
30     auto uses = acc_.Uses(returnList);
31     for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) {
32         PushGate(*useIt);
33     }
34     circuit_->GetAllGates(gateList_);
35     for (auto gate : gateList_) {
36         if (acc_.GetOpCode(gate) == OpCode::LOOP_BEGIN) {
37             PushGate(gate);
38         } else if (acc_.IsProlog(gate) || acc_.IsRoot(gate)) {
39             acc_.SetMark(gate, MarkCode::VISITED);
40         }
41     }
42 }
43 
MarkGate()44 void UselessGateElimination::MarkGate()
45 {
46     while (!workList_.empty()) {
47         GateRef gate = workList_.back();
48         workList_.pop_back();
49         std::vector<GateRef> ins;
50         acc_.GetIns(gate, ins);
51         for (auto in : ins) {
52             if (acc_.GetMark(in) != MarkCode::VISITED) {
53                 PushGate(in);
54             }
55         }
56     }
57 }
58 
ReplaceDead(GateRef gate)59 void UselessGateElimination::ReplaceDead(GateRef gate)
60 {
61     auto uses = acc_.Uses(gate);
62     for (auto it = uses.begin(); it != uses.end();) {
63         it = acc_.ReplaceIn(it, circuit_->DeadGate());
64     }
65     acc_.DeleteGate(gate);
66 }
67 
EliminateUnmarkedGate()68 void UselessGateElimination::EliminateUnmarkedGate()
69 {
70     for (auto gate : gateList_) {
71         if (acc_.GetMark(gate) != MarkCode::VISITED) {
72             ReplaceDead(gate);
73         }
74     }
75 }
76 
GetMethodName()77 std::string UselessGateElimination::GetMethodName()
78 {
79     return methodName_;
80 }
81 
Run()82 void UselessGateElimination::Run()
83 {
84     InitList();
85     MarkGate();
86     EliminateUnmarkedGate();
87     if (enableLog_) {
88         LOG_COMPILER(INFO) << "";
89         LOG_COMPILER(INFO) << "\033[34m"
90                            << "===================="
91                            << " After Useless Gate Elimination "
92                            << "[" << GetMethodName() << "]"
93                            << "===================="
94                            << "\033[0m";
95         circuit_->PrintAllGatesWithBytecode();
96         LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m";
97     }
98 }
99 
100 }