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)20void UselessGateElimination::PushGate(GateRef gate) 21 { 22 workList_.push_back(gate); 23 acc_.SetMark(gate, MarkCode::VISITED); 24 } 25 InitList()26void 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()44void 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)59void 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()68void UselessGateElimination::EliminateUnmarkedGate() 69 { 70 for (auto gate : gateList_) { 71 if (acc_.GetMark(gate) != MarkCode::VISITED) { 72 ReplaceDead(gate); 73 } 74 } 75 } 76 GetMethodName()77std::string UselessGateElimination::GetMethodName() 78 { 79 return methodName_; 80 } 81 Run()82void 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 }