1 /**
2 * Copyright (c) 2021-2022 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 "unit_test.h"
17
18 namespace panda::compiler {
19 class GraphComparatorTest : public CommonTest {
20 public:
GraphComparatorTest()21 GraphComparatorTest() {}
22
CreateGraph(std::initializer_list<std::pair<int,int>> inputs)23 Graph *CreateGraph(std::initializer_list<std::pair<int, int>> inputs)
24 {
25 auto graph = CreateEmptyGraph();
26 GRAPH(graph)
27 {
28 CONSTANT(0, 10);
29 PARAMETER(1, 0).s32();
30 PARAMETER(2, 1).b();
31 BASIC_BLOCK(2, 3, 4)
32 {
33 INST(3, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(2);
34 }
35 BASIC_BLOCK(3, 7)
36 {
37 INST(4, Opcode::Add).s32().Inputs(0, 1);
38 }
39 BASIC_BLOCK(4, 5, 6)
40 {
41 INST(5, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(2);
42 }
43 BASIC_BLOCK(5, 7)
44 {
45 INST(6, Opcode::Sub).s32().Inputs(0, 1);
46 }
47 BASIC_BLOCK(6, 7)
48 {
49 INST(7, Opcode::Mul).s32().Inputs(0, 1);
50 }
51 BASIC_BLOCK(7, 1)
52 {
53 INST(8, Opcode::Phi).s32().Inputs(inputs);
54 INST(9, Opcode::Return).s32().Inputs(8);
55 }
56 }
57 return graph;
58 }
59 };
60
TEST_F(GraphComparatorTest,CompareIDs)61 TEST_F(GraphComparatorTest, CompareIDs)
62 {
63 // graph1 and graph2 is equal but have different ids
64 auto graph1 = CreateEmptyGraph();
65 GRAPH(graph1)
66 {
67 CONSTANT(0, 10);
68 PARAMETER(1, 0).s32();
69 BASIC_BLOCK(2, 3)
70 {
71 INST(2, Opcode::Add).s32().Inputs(0, 1);
72 }
73 BASIC_BLOCK(3, 1)
74 {
75 INST(4, Opcode::Return).s32().Inputs(2);
76 }
77 }
78 auto graph2 = CreateEmptyGraph();
79 GRAPH(graph2)
80 {
81 CONSTANT(23, 10);
82 PARAMETER(3, 0).s32();
83 BASIC_BLOCK(15, 25)
84 {
85 INST(6, Opcode::Add).s32().Inputs(23, 3);
86 }
87 BASIC_BLOCK(25, 1)
88 {
89 INST(7, Opcode::Return).s32().Inputs(6);
90 }
91 }
92 ASSERT_TRUE(GraphComparator().Compare(graph1, graph2));
93 }
94
TEST_F(GraphComparatorTest,ComparePhi1)95 TEST_F(GraphComparatorTest, ComparePhi1)
96 {
97 // graph1 and graph2 is equal but have different ids
98 auto graph1 = CreateEmptyGraph();
99 GRAPH(graph1)
100 {
101 CONSTANT(0, 10);
102 PARAMETER(1, 0).s32();
103 PARAMETER(2, 1).b();
104 BASIC_BLOCK(2, 3, 4)
105 {
106 INST(3, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(2);
107 }
108 BASIC_BLOCK(3, 5)
109 {
110 INST(4, Opcode::Add).s32().Inputs(0, 1);
111 }
112 BASIC_BLOCK(4, 5)
113 {
114 INST(5, Opcode::Sub).s32().Inputs(0, 1);
115 }
116 BASIC_BLOCK(5, 1)
117 {
118 INST(6, Opcode::Phi).s32().Inputs({{3, 4}, {4, 5}});
119 INST(7, Opcode::Return).s32().Inputs(6);
120 }
121 }
122 auto graph2 = CreateEmptyGraph();
123 GRAPH(graph2)
124 {
125 CONSTANT(0, 10);
126 PARAMETER(1, 0).s32();
127 PARAMETER(2, 1).b();
128 BASIC_BLOCK(2, 3, 4)
129 {
130 INST(3, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(2);
131 }
132 BASIC_BLOCK(3, 5)
133 {
134 INST(4, Opcode::Add).s32().Inputs(0, 1);
135 }
136 BASIC_BLOCK(4, 5)
137 {
138 INST(5, Opcode::Sub).s32().Inputs(0, 1);
139 }
140 BASIC_BLOCK(5, 1)
141 {
142 INST(6, Opcode::Phi).s32().Inputs({{4, 5}, {3, 4}});
143 INST(7, Opcode::Return).s32().Inputs(6);
144 }
145 }
146 ASSERT_TRUE(GraphComparator().Compare(graph1, graph2));
147 }
148
TEST_F(GraphComparatorTest,ComparePhi2)149 TEST_F(GraphComparatorTest, ComparePhi2)
150 {
151 auto graph1 = CreateGraph({{3, 4}, {5, 6}, {6, 7}});
152 auto graph2 = CreateGraph({{3, 4}, {6, 7}, {5, 6}});
153 auto graph3 = CreateGraph({{5, 6}, {3, 4}, {6, 7}});
154 auto graph4 = CreateGraph({{5, 6}, {6, 7}, {3, 4}});
155 auto graph5 = CreateGraph({{6, 7}, {3, 4}, {5, 6}});
156 auto graph6 = CreateGraph({{6, 7}, {5, 6}, {3, 4}});
157 ASSERT_TRUE(GraphComparator().Compare(graph1, graph2));
158 ASSERT_TRUE(GraphComparator().Compare(graph1, graph3));
159 ASSERT_TRUE(GraphComparator().Compare(graph1, graph4));
160 ASSERT_TRUE(GraphComparator().Compare(graph1, graph5));
161 ASSERT_TRUE(GraphComparator().Compare(graph1, graph6));
162 ASSERT_TRUE(GraphComparator().Compare(graph2, graph3));
163 ASSERT_TRUE(GraphComparator().Compare(graph2, graph4));
164 ASSERT_TRUE(GraphComparator().Compare(graph2, graph5));
165 ASSERT_TRUE(GraphComparator().Compare(graph2, graph6));
166 ASSERT_TRUE(GraphComparator().Compare(graph3, graph4));
167 ASSERT_TRUE(GraphComparator().Compare(graph3, graph5));
168 ASSERT_TRUE(GraphComparator().Compare(graph3, graph6));
169 ASSERT_TRUE(GraphComparator().Compare(graph4, graph5));
170 ASSERT_TRUE(GraphComparator().Compare(graph4, graph6));
171 ASSERT_TRUE(GraphComparator().Compare(graph5, graph6));
172 }
173
TEST_F(GraphComparatorTest,CompareDifferentInstCount)174 TEST_F(GraphComparatorTest, CompareDifferentInstCount)
175 {
176 auto graph1 = CreateEmptyGraph();
177 GRAPH(graph1)
178 {
179 CONSTANT(0, 10);
180 PARAMETER(1, 0).s32();
181 PARAMETER(2, 1).b();
182 BASIC_BLOCK(2, 3, 4)
183 {
184 INST(3, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(2);
185 }
186 BASIC_BLOCK(3, 5)
187 {
188 INST(4, Opcode::Add).s32().Inputs(0, 1);
189 INST(20, Opcode::SaveState).NoVregs();
190 INST(8, Opcode::CallStatic).v0id().InputsAutoType(20);
191 }
192 BASIC_BLOCK(4, 5)
193 {
194 INST(5, Opcode::Sub).s32().Inputs(0, 1);
195 }
196 BASIC_BLOCK(5, 1)
197 {
198 INST(6, Opcode::Phi).s32().Inputs({{3, 4}, {4, 5}});
199 INST(7, Opcode::Return).s32().Inputs(6);
200 }
201 }
202
203 auto graph2 = CreateEmptyGraph();
204 GRAPH(graph2)
205 {
206 CONSTANT(0, 10);
207 PARAMETER(1, 0).s32();
208 PARAMETER(2, 1).b();
209 BASIC_BLOCK(2, 3, 4)
210 {
211 INST(3, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(2);
212 }
213 BASIC_BLOCK(3, 5)
214 {
215 INST(4, Opcode::Add).s32().Inputs(0, 1);
216 }
217 BASIC_BLOCK(4, 5)
218 {
219 INST(5, Opcode::Sub).s32().Inputs(0, 1);
220 INST(20, Opcode::SaveState).NoVregs();
221 INST(8, Opcode::CallStatic).v0id().InputsAutoType(20);
222 }
223 BASIC_BLOCK(5, 1)
224 {
225 INST(6, Opcode::Phi).s32().Inputs({{3, 4}, {4, 5}});
226 INST(7, Opcode::Return).s32().Inputs(6);
227 }
228 }
229 ASSERT_FALSE(GraphComparator().Compare(graph1, graph2));
230 }
231 } // namespace panda::compiler
232