• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 Google LLC
2 //
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 #include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
16 
17 #include "source/opt/build_module.h"
18 #include "source/reduce/reduction_opportunity.h"
19 #include "test/reduce/reduce_test_util.h"
20 
21 namespace spvtools {
22 namespace reduce {
23 namespace {
24 
TEST(OperandToConstantReductionPassTest,BasicCheck)25 TEST(OperandToConstantReductionPassTest, BasicCheck) {
26   std::string prologue = R"(
27                OpCapability Shader
28           %1 = OpExtInstImport "GLSL.std.450"
29                OpMemoryModel Logical GLSL450
30                OpEntryPoint Fragment %4 "main" %37
31                OpExecutionMode %4 OriginUpperLeft
32                OpSource ESSL 310
33                OpName %4 "main"
34                OpName %9 "buf1"
35                OpMemberName %9 0 "f"
36                OpName %11 ""
37                OpName %24 "buf2"
38                OpMemberName %24 0 "i"
39                OpName %26 ""
40                OpName %37 "_GLF_color"
41                OpMemberDecorate %9 0 Offset 0
42                OpDecorate %9 Block
43                OpDecorate %11 DescriptorSet 0
44                OpDecorate %11 Binding 1
45                OpMemberDecorate %24 0 Offset 0
46                OpDecorate %24 Block
47                OpDecorate %26 DescriptorSet 0
48                OpDecorate %26 Binding 2
49                OpDecorate %37 Location 0
50           %2 = OpTypeVoid
51           %3 = OpTypeFunction %2
52           %6 = OpTypeFloat 32
53           %9 = OpTypeStruct %6
54          %10 = OpTypePointer Uniform %9
55          %11 = OpVariable %10 Uniform
56          %12 = OpTypeInt 32 1
57          %13 = OpConstant %12 0
58          %14 = OpTypePointer Uniform %6
59          %20 = OpConstant %6 2
60          %24 = OpTypeStruct %12
61          %25 = OpTypePointer Uniform %24
62          %26 = OpVariable %25 Uniform
63          %27 = OpTypePointer Uniform %12
64          %33 = OpConstant %12 3
65          %35 = OpTypeVector %6 4
66          %36 = OpTypePointer Output %35
67          %37 = OpVariable %36 Output
68           %4 = OpFunction %2 None %3
69           %5 = OpLabel
70          %15 = OpAccessChain %14 %11 %13
71          %16 = OpLoad %6 %15
72          %19 = OpFAdd %6 %16 %16
73          %21 = OpFAdd %6 %19 %20
74          %28 = OpAccessChain %27 %26 %13
75          %29 = OpLoad %12 %28
76   )";
77 
78   std::string epilogue = R"(
79          %45 = OpConvertSToF %6 %34
80          %46 = OpCompositeConstruct %35 %16 %21 %43 %45
81                OpStore %37 %46
82                OpReturn
83                OpFunctionEnd
84   )";
85 
86   std::string original = prologue + R"(
87          %32 = OpIAdd %12 %29 %29
88          %34 = OpIAdd %12 %32 %33
89          %43 = OpConvertSToF %6 %29
90   )" + epilogue;
91 
92   std::string expected = prologue + R"(
93          %32 = OpIAdd %12 %13 %13 ; %29 -> %13 x 2
94          %34 = OpIAdd %12 %13 %33 ; %32 -> %13
95          %43 = OpConvertSToF %6 %13 ; %29 -> %13
96   )" + epilogue;
97 
98   const auto env = SPV_ENV_UNIVERSAL_1_3;
99   const auto consumer = nullptr;
100   const auto context =
101       BuildModule(env, consumer, original, kReduceAssembleOption);
102   const auto ops =
103       OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
104           context.get(), 0);
105   ASSERT_EQ(17, ops.size());
106   ASSERT_TRUE(ops[0]->PreconditionHolds());
107   ops[0]->TryToApply();
108   ASSERT_TRUE(ops[1]->PreconditionHolds());
109   ops[1]->TryToApply();
110   ASSERT_TRUE(ops[2]->PreconditionHolds());
111   ops[2]->TryToApply();
112   ASSERT_TRUE(ops[3]->PreconditionHolds());
113   ops[3]->TryToApply();
114 
115   CheckEqual(env, expected, context.get());
116 }
117 
TEST(OperandToConstantReductionPassTest,WithCalledFunction)118 TEST(OperandToConstantReductionPassTest, WithCalledFunction) {
119   std::string shader = R"(
120                OpCapability Shader
121           %1 = OpExtInstImport "GLSL.std.450"
122                OpMemoryModel Logical GLSL450
123                OpEntryPoint Fragment %4 "main" %10 %12
124                OpExecutionMode %4 OriginUpperLeft
125                OpSource ESSL 310
126           %2 = OpTypeVoid
127           %3 = OpTypeFunction %2
128           %6 = OpTypeFloat 32
129           %7 = OpTypeVector %6 4
130           %8 = OpTypeFunction %7
131           %9 = OpTypePointer Output %7
132          %10 = OpVariable %9 Output
133          %11 = OpTypePointer Input %7
134          %12 = OpVariable %11 Input
135          %13 = OpConstant %6 0
136          %14 = OpConstantComposite %7 %13 %13 %13 %13
137           %4 = OpFunction %2 None %3
138           %5 = OpLabel
139          %15 = OpFunctionCall %7 %16
140                OpReturn
141                OpFunctionEnd
142          %16 = OpFunction %7 None %8
143          %17 = OpLabel
144                OpReturnValue %14
145                OpFunctionEnd
146   )";
147 
148   const auto env = SPV_ENV_UNIVERSAL_1_3;
149   const auto consumer = nullptr;
150   const auto context =
151       BuildModule(env, consumer, shader, kReduceAssembleOption);
152   const auto ops =
153       OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
154           context.get(), 0);
155   ASSERT_EQ(0, ops.size());
156 }
157 
TEST(OperandToConstantReductionPassTest,TargetSpecificFunction)158 TEST(OperandToConstantReductionPassTest, TargetSpecificFunction) {
159   std::string shader = R"(
160                OpCapability Shader
161           %1 = OpExtInstImport "GLSL.std.450"
162                OpMemoryModel Logical GLSL450
163                OpEntryPoint Fragment %4 "main"
164                OpExecutionMode %4 OriginUpperLeft
165                OpSource ESSL 320
166           %2 = OpTypeVoid
167           %3 = OpTypeFunction %2
168           %6 = OpTypeInt 32 1
169           %7 = OpTypePointer Function %6
170           %8 = OpTypeFunction %6 %7
171          %17 = OpConstant %6 1
172          %20 = OpConstant %6 2
173          %23 = OpConstant %6 0
174          %24 = OpTypeBool
175          %35 = OpConstant %6 3
176          %53 = OpConstant %6 10
177           %4 = OpFunction %2 None %3
178           %5 = OpLabel
179          %65 = OpVariable %7 Function
180          %68 = OpVariable %7 Function
181          %73 = OpVariable %7 Function
182                OpStore %65 %35
183          %66 = OpLoad %6 %65
184          %67 = OpIAdd %6 %66 %17
185                OpStore %65 %67
186          %69 = OpLoad %6 %65
187                OpStore %68 %69
188          %70 = OpFunctionCall %6 %13 %68
189          %71 = OpLoad %6 %65
190          %72 = OpIAdd %6 %71 %70
191                OpStore %65 %72
192          %74 = OpLoad %6 %65
193                OpStore %73 %74
194          %75 = OpFunctionCall %6 %10 %73
195          %76 = OpLoad %6 %65
196          %77 = OpIAdd %6 %76 %75
197                OpStore %65 %77
198                OpReturn
199                OpFunctionEnd
200          %10 = OpFunction %6 None %8
201           %9 = OpFunctionParameter %7
202          %11 = OpLabel
203          %15 = OpVariable %7 Function
204          %16 = OpLoad %6 %9
205          %18 = OpIAdd %6 %16 %17
206                OpStore %15 %18
207          %19 = OpLoad %6 %15
208          %21 = OpIAdd %6 %19 %20
209                OpStore %15 %21
210          %22 = OpLoad %6 %15
211          %25 = OpSGreaterThan %24 %22 %23
212                OpSelectionMerge %27 None
213                OpBranchConditional %25 %26 %27
214          %26 = OpLabel
215          %28 = OpLoad %6 %9
216                OpReturnValue %28
217          %27 = OpLabel
218          %30 = OpLoad %6 %9
219          %31 = OpIAdd %6 %30 %17
220                OpReturnValue %31
221                OpFunctionEnd
222          %13 = OpFunction %6 None %8
223          %12 = OpFunctionParameter %7
224          %14 = OpLabel
225          %41 = OpVariable %7 Function
226          %46 = OpVariable %7 Function
227          %55 = OpVariable %7 Function
228          %34 = OpLoad %6 %12
229          %36 = OpIEqual %24 %34 %35
230                OpSelectionMerge %38 None
231                OpBranchConditional %36 %37 %38
232          %37 = OpLabel
233          %39 = OpLoad %6 %12
234          %40 = OpIMul %6 %20 %39
235                OpStore %41 %40
236          %42 = OpFunctionCall %6 %10 %41
237                OpReturnValue %42
238          %38 = OpLabel
239          %44 = OpLoad %6 %12
240          %45 = OpIAdd %6 %44 %17
241                OpStore %12 %45
242                OpStore %46 %23
243                OpBranch %47
244          %47 = OpLabel
245                OpLoopMerge %49 %50 None
246                OpBranch %51
247          %51 = OpLabel
248          %52 = OpLoad %6 %46
249          %54 = OpSLessThan %24 %52 %53
250                OpBranchConditional %54 %48 %49
251          %48 = OpLabel
252          %56 = OpLoad %6 %12
253                OpStore %55 %56
254          %57 = OpFunctionCall %6 %10 %55
255          %58 = OpLoad %6 %12
256          %59 = OpIAdd %6 %58 %57
257                OpStore %12 %59
258                OpBranch %50
259          %50 = OpLabel
260          %60 = OpLoad %6 %46
261          %61 = OpIAdd %6 %60 %17
262                OpStore %46 %61
263                OpBranch %47
264          %49 = OpLabel
265          %62 = OpLoad %6 %12
266                OpReturnValue %62
267                OpFunctionEnd
268   )";
269 
270   const auto env = SPV_ENV_UNIVERSAL_1_3;
271   const auto consumer = nullptr;
272   const auto context =
273       BuildModule(env, consumer, shader, kReduceAssembleOption);
274 
275   // Targeting all functions, there are quite a few opportunities.  To avoid
276   // making the test too sensitive, we check that there are more than a number
277   // somewhat lower than the real number.
278   const auto all_ops =
279       OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
280           context.get(), 0);
281   ASSERT_TRUE(all_ops.size() > 100);
282 
283   // Targeting individual functions, there are fewer opportunities.  Again, we
284   // avoid checking against an exact number so that the test is not too
285   // sensitive.
286   const auto ops_for_function_4 =
287       OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
288           context.get(), 4);
289   const auto ops_for_function_10 =
290       OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
291           context.get(), 10);
292   const auto ops_for_function_13 =
293       OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
294           context.get(), 13);
295   ASSERT_TRUE(ops_for_function_4.size() < 60);
296   ASSERT_TRUE(ops_for_function_10.size() < 50);
297   ASSERT_TRUE(ops_for_function_13.size() < 80);
298 
299   // The total number of opportunities should be the sum of the per-function
300   // opportunities.
301   ASSERT_EQ(all_ops.size(), ops_for_function_4.size() +
302                                 ops_for_function_10.size() +
303                                 ops_for_function_13.size());
304 }
305 
306 }  // namespace
307 }  // namespace reduce
308 }  // namespace spvtools
309