1/* 2 * Copyright (c) 2023 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/combined_pass_visitor.h" 17#include "ecmascript/compiler/dead_code_elimination.h" 18#include "ecmascript/compiler/verifier.h" 19#include "ecmascript/tests/test_helper.h" 20 21namespace panda::test { 22class DeadCodeEliminationTests : public testing::Test { 23}; 24using ecmascript::kungfu::Chunk; 25using ecmascript::kungfu::CombinedPassVisitor; 26using ecmascript::kungfu::Circuit; 27using ecmascript::kungfu::CircuitBuilder; 28using ecmascript::kungfu::DeadCodeElimination; 29using ecmascript::kungfu::Environment; 30using ecmascript::kungfu::OpCode; 31using ecmascript::kungfu::GateType; 32using ecmascript::kungfu::MachineType; 33using ecmascript::kungfu::GateAccessor; 34using ecmascript::kungfu::GateRef; 35using ecmascript::kungfu::Verifier; 36using ecmascript::NativeAreaAllocator; 37 38HWTEST_F_L0(DeadCodeEliminationTests, CommonEliminationFramework) 39{ 40 // construct a circuit 41 ecmascript::NativeAreaAllocator allocator; 42 Circuit circuit(&allocator); 43 CircuitBuilder builder(&circuit); 44 GateAccessor acc(&circuit); 45 auto depend = acc.GetDependRoot(); 46 auto arg0 = builder.Arguments(0); 47 auto dead = circuit.DeadGate(); 48 auto ifBranch = circuit.NewGate(circuit.IfBranch(0), {dead, arg0}); 49 auto ifTrue = circuit.NewGate(circuit.IfTrue(), {ifBranch}); 50 auto ifFalse = circuit.NewGate(circuit.IfFalse(), {ifBranch}); 51 auto trueReturn = circuit.NewGate(circuit.Return(), {ifTrue, depend, arg0, circuit.GetReturnRoot()}); 52 auto falseReturn = circuit.NewGate(circuit.Return(), {ifFalse, depend, arg0, circuit.GetReturnRoot()}); 53 Chunk chunk(&allocator); 54 CombinedPassVisitor visitor(&circuit, false, "dead code elimination", &chunk); 55 DeadCodeElimination elimination(&circuit, &visitor, &chunk); 56 visitor.AddPass(&elimination); 57 visitor.VisitGraph(); 58 EXPECT_TRUE(acc.IsNop(ifBranch)); 59 EXPECT_TRUE(acc.IsNop(ifTrue)); 60 EXPECT_TRUE(acc.IsNop(ifFalse)); 61 EXPECT_TRUE(acc.IsNop(trueReturn)); 62 EXPECT_TRUE(acc.IsNop(falseReturn)); 63} 64 65HWTEST_F_L0(DeadCodeEliminationTests, MergeEliminationFramework) 66{ 67 // construct a circuit 68 ecmascript::NativeAreaAllocator allocator; 69 Circuit circuit(&allocator); 70 CircuitBuilder builder(&circuit); 71 Environment env(0, &builder); 72 builder.SetEnvironment(&env); 73 GateAccessor acc(&circuit); 74 auto entry = acc.GetStateRoot(); 75 auto depend = acc.GetDependRoot(); 76 auto arg0 = builder.Arguments(0); 77 auto arg1 = builder.Arguments(1); 78 auto arg2 = builder.Arguments(2); 79 auto dead = circuit.DeadGate(); 80 auto icmp = circuit.NewGate(circuit.Icmp(1), MachineType::I1, {arg0, arg1}, GateType::NJSValue()); 81 auto ifBranch = circuit.NewGate(circuit.IfBranch(0), {entry, icmp}); 82 circuit.NewGate(circuit.IfTrue(), {ifBranch}); 83 auto ifFalse = circuit.NewGate(circuit.IfFalse(), {ifBranch}); 84 auto merge = circuit.NewGate(circuit.Merge(2), {dead, ifFalse}); 85 auto valueSelector = circuit.NewGate(circuit.ValueSelector(2), {merge, arg1, arg2}); 86 auto circuitReturn = circuit.NewGate(circuit.Return(), {merge, depend, valueSelector, circuit.GetReturnRoot()}); 87 Chunk chunk(&allocator); 88 CombinedPassVisitor visitor(&circuit, false, "dead code elimination", &chunk); 89 DeadCodeElimination elimination(&circuit, &visitor, &chunk); 90 visitor.AddPass(&elimination); 91 visitor.VisitGraph(); 92 EXPECT_TRUE(acc.IsNop(merge)); 93 EXPECT_TRUE(acc.IsNop(valueSelector)); 94 EXPECT_TRUE(acc.GetValueIn(circuitReturn) == arg2); 95} 96 97HWTEST_F_L0(DeadCodeEliminationTests, MergeInputEliminationFramework) 98{ 99 // construct a circuit 100 ecmascript::NativeAreaAllocator allocator; 101 Circuit circuit(&allocator); 102 CircuitBuilder builder(&circuit); 103 Environment env(0, &builder); 104 builder.SetEnvironment(&env); 105 GateAccessor acc(&circuit); 106 auto entry = acc.GetStateRoot(); 107 auto depend = acc.GetDependRoot(); 108 auto arg0 = builder.Arguments(0); 109 auto arg1 = builder.Arguments(1); 110 auto arg2 = builder.Arguments(2); 111 auto dead = circuit.DeadGate(); 112 auto icmp = circuit.NewGate(circuit.Icmp(1), MachineType::I1, {arg0, arg1}, GateType::NJSValue()); 113 auto ifBranch = circuit.NewGate(circuit.IfBranch(0), {entry, icmp}); 114 auto ifTrue = circuit.NewGate(circuit.IfTrue(), {ifBranch}); 115 auto ifFalse = circuit.NewGate(circuit.IfFalse(), {ifBranch}); 116 auto ifBranch2 = circuit.NewGate(circuit.IfBranch(0), {ifTrue, icmp}); 117 auto ifTrue2 = circuit.NewGate(circuit.IfTrue(), {ifBranch2}); 118 circuit.NewGate(circuit.IfFalse(), {ifBranch2}); 119 auto merge = circuit.NewGate(circuit.Merge(3), {ifTrue2, dead, ifFalse}); 120 auto valueSelector = circuit.NewGate(circuit.ValueSelector(3), {merge, arg0, arg1, arg2}); 121 auto circuitReturn = circuit.NewGate(circuit.Return(), {merge, depend, valueSelector, circuit.GetReturnRoot()}); 122 Chunk chunk(&allocator); 123 CombinedPassVisitor visitor(&circuit, false, "dead code elimination", &chunk); 124 DeadCodeElimination elimination(&circuit, &visitor, &chunk); 125 visitor.AddPass(&elimination); 126 visitor.VisitGraph(); 127 EXPECT_TRUE(acc.GetOpCode(merge) == OpCode::MERGE); 128 EXPECT_TRUE(acc.GetOpCode(valueSelector) == OpCode::VALUE_SELECTOR); 129 EXPECT_TRUE(acc.GetValueIn(circuitReturn) == valueSelector); 130 EXPECT_TRUE(acc.GetNumIns(merge) == 2); 131 EXPECT_TRUE(acc.GetNumIns(valueSelector) == 3); 132 EXPECT_TRUE(acc.GetIn(merge, 0) == ifTrue2); 133 EXPECT_TRUE(acc.GetIn(merge, 1) == ifFalse); 134 EXPECT_TRUE(acc.GetIn(valueSelector, 1) == arg0); 135 EXPECT_TRUE(acc.GetIn(valueSelector, 2) == arg2); 136} 137 138}