arkcompiler_ets_runtime/ecmascript/compiler/graph_editor.cpp
wu_zhang_da 0e0894618e Bugfix: RemoveGate
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7GJ6U

Signed-off-by: wu_zhang_da <wuzhangda@huawei.com>
Change-Id: I92b0eb86bee8cbd882799c8466709fd6fdb8929d
2023-06-27 22:14:19 +08:00

111 lines
3.4 KiB
C++

/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <queue>
#include <stack>
#include "ecmascript/compiler/graph_editor.h"
namespace panda::ecmascript::kungfu {
void GraphEditor::RemoveDeadState(Circuit* circuit, GateRef gate)
{
GraphEditor editor(circuit);
editor.ReplaceGate(gate);
editor.RemoveGate();
}
void GraphEditor::ReplaceGate(GateRef gate)
{
auto uses = acc_.Uses(gate);
for (auto useIt = uses.begin(); useIt != uses.end();) {
if (acc_.IsDependIn(useIt)) {
GateRef depend = acc_.GetDep(gate);
useIt = acc_.ReplaceIn(useIt, depend);
} else {
workList_.push_back(useIt.GetEdge());
useIt = acc_.ReplaceIn(useIt, circuit_->DeadGate());
}
}
acc_.DeleteGate(gate);
}
void GraphEditor::RemoveGate()
{
while (!workList_.empty()) {
Edge& edge = workList_.back();
GateRef gate = edge.GetGate();
workList_.pop_back();
auto opcode = acc_.GetOpCode(gate);
switch (opcode) {
case OpCode::NOP:
case OpCode::DEAD:
case OpCode::VALUE_SELECTOR:
case OpCode::DEPEND_SELECTOR:
// dead op, just continue
break;
case OpCode::LOOP_BEGIN:
case OpCode::MERGE:
PropagateMerge(edge);
break;
default:
PropagateGate(edge);
break;
}
}
}
void GraphEditor::PropagateGate(const Edge& edge)
{
GateRef gate = edge.GetGate();
// isStateIn
if (acc_.IsStateIn(gate, edge.GetIndex())) {
// 2: is loop begin
ASSERT(acc_.GetStateCount(gate) == 1 ||
acc_.GetStateCount(gate) == 2); // 2: LOOP_BEGIN
ReplaceGate(gate);
return;
}
// IsValueIn
if (acc_.IsValueIn(gate, edge.GetIndex())) {
// value gate
ReplaceGate(gate);
}
}
void GraphEditor::PropagateMerge(const Edge& edge)
{
GateRef gate = edge.GetGate();
auto numIns = acc_.GetNumIns(gate);
if (numIns == 1) {
ReplaceGate(gate);
} else {
auto uses = acc_.Uses(gate);
for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) {
GateRef use = *useIt;
// (Gate1) (Dead) (Gate2) (Gate1) (Gate2)
// | | | | |
// ___________________ ==> __________
// | |
// (phi) (phi)
if (acc_.GetOpCode(use) == OpCode::VALUE_SELECTOR ||
acc_.GetOpCode(use) == OpCode::DEPEND_SELECTOR) {
acc_.DecreaseIn(use, edge.GetIndex() + 1); // +1 skip state input
}
}
acc_.DecreaseIn(gate, edge.GetIndex());
}
}
} // namespace panda::ecmascript::kungfu