1fd4e5da5Sopenharmony_ci// Copyright (c) 2020 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include "source/reduce/remove_unused_struct_member_reduction_opportunity_finder.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h" 18fd4e5da5Sopenharmony_ci#include "source/reduce/reduction_opportunity.h" 19fd4e5da5Sopenharmony_ci#include "test/reduce/reduce_test_util.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace reduce { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciTEST(RemoveUnusedStructMemberTest, RemoveOneMember) { 26fd4e5da5Sopenharmony_ci std::string shader = R"( 27fd4e5da5Sopenharmony_ci OpCapability Shader 28fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 29fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 30fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 31fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 32fd4e5da5Sopenharmony_ci OpSource ESSL 310 33fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 34fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 35fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 36fd4e5da5Sopenharmony_ci %7 = OpTypeStruct %6 %6 37fd4e5da5Sopenharmony_ci %8 = OpTypePointer Function %7 38fd4e5da5Sopenharmony_ci %50 = OpConstant %6 0 39fd4e5da5Sopenharmony_ci %10 = OpConstant %6 1 40fd4e5da5Sopenharmony_ci %11 = OpConstant %6 2 41fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %7 %10 %11 42fd4e5da5Sopenharmony_ci %13 = OpConstant %6 4 43fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %6 44fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 45fd4e5da5Sopenharmony_ci %5 = OpLabel 46fd4e5da5Sopenharmony_ci %9 = OpVariable %8 Function 47fd4e5da5Sopenharmony_ci OpStore %9 %12 48fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %9 %10 49fd4e5da5Sopenharmony_ci %22 = OpInBoundsAccessChain %14 %9 %10 50fd4e5da5Sopenharmony_ci %20 = OpLoad %7 %9 51fd4e5da5Sopenharmony_ci %21 = OpCompositeExtract %6 %20 1 52fd4e5da5Sopenharmony_ci %23 = OpCompositeInsert %7 %10 %20 1 53fd4e5da5Sopenharmony_ci OpStore %15 %13 54fd4e5da5Sopenharmony_ci OpReturn 55fd4e5da5Sopenharmony_ci OpFunctionEnd 56fd4e5da5Sopenharmony_ci )"; 57fd4e5da5Sopenharmony_ci 58fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 59fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 60fd4e5da5Sopenharmony_ci const auto context = 61fd4e5da5Sopenharmony_ci BuildModule(env, consumer, shader, kReduceAssembleOption); 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ci auto ops = RemoveUnusedStructMemberReductionOpportunityFinder() 64fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 65fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 66fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 67fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 70fd4e5da5Sopenharmony_ci 71fd4e5da5Sopenharmony_ci std::string expected = R"( 72fd4e5da5Sopenharmony_ci OpCapability Shader 73fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 74fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 75fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 76fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 77fd4e5da5Sopenharmony_ci OpSource ESSL 310 78fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 79fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 80fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 81fd4e5da5Sopenharmony_ci %7 = OpTypeStruct %6 82fd4e5da5Sopenharmony_ci %8 = OpTypePointer Function %7 83fd4e5da5Sopenharmony_ci %50 = OpConstant %6 0 84fd4e5da5Sopenharmony_ci %10 = OpConstant %6 1 85fd4e5da5Sopenharmony_ci %11 = OpConstant %6 2 86fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %7 %11 87fd4e5da5Sopenharmony_ci %13 = OpConstant %6 4 88fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %6 89fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 90fd4e5da5Sopenharmony_ci %5 = OpLabel 91fd4e5da5Sopenharmony_ci %9 = OpVariable %8 Function 92fd4e5da5Sopenharmony_ci OpStore %9 %12 93fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %9 %50 94fd4e5da5Sopenharmony_ci %22 = OpInBoundsAccessChain %14 %9 %50 95fd4e5da5Sopenharmony_ci %20 = OpLoad %7 %9 96fd4e5da5Sopenharmony_ci %21 = OpCompositeExtract %6 %20 0 97fd4e5da5Sopenharmony_ci %23 = OpCompositeInsert %7 %10 %20 0 98fd4e5da5Sopenharmony_ci OpStore %15 %13 99fd4e5da5Sopenharmony_ci OpReturn 100fd4e5da5Sopenharmony_ci OpFunctionEnd 101fd4e5da5Sopenharmony_ci )"; 102fd4e5da5Sopenharmony_ci 103fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 104fd4e5da5Sopenharmony_ci} 105fd4e5da5Sopenharmony_ci 106fd4e5da5Sopenharmony_ciTEST(RemoveUnusedStructMemberTest, RemoveUniformBufferMember) { 107fd4e5da5Sopenharmony_ci std::string shader = R"( 108fd4e5da5Sopenharmony_ci OpCapability Shader 109fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 110fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 111fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 112fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 113fd4e5da5Sopenharmony_ci OpSource ESSL 310 114fd4e5da5Sopenharmony_ci OpMemberDecorate %10 0 Offset 0 115fd4e5da5Sopenharmony_ci OpMemberDecorate %10 1 Offset 4 116fd4e5da5Sopenharmony_ci OpDecorate %10 Block 117fd4e5da5Sopenharmony_ci OpDecorate %12 DescriptorSet 0 118fd4e5da5Sopenharmony_ci OpDecorate %12 Binding 0 119fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 120fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 121fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 122fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 123fd4e5da5Sopenharmony_ci %9 = OpTypeInt 32 1 124fd4e5da5Sopenharmony_ci %10 = OpTypeStruct %9 %6 125fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %10 126fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Uniform 127fd4e5da5Sopenharmony_ci %13 = OpConstant %9 1 128fd4e5da5Sopenharmony_ci %20 = OpConstant %9 0 129fd4e5da5Sopenharmony_ci %14 = OpTypePointer Uniform %6 130fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 131fd4e5da5Sopenharmony_ci %5 = OpLabel 132fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 133fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %12 %13 134fd4e5da5Sopenharmony_ci %16 = OpLoad %6 %15 135fd4e5da5Sopenharmony_ci OpStore %8 %16 136fd4e5da5Sopenharmony_ci OpReturn 137fd4e5da5Sopenharmony_ci OpFunctionEnd 138fd4e5da5Sopenharmony_ci )"; 139fd4e5da5Sopenharmony_ci 140fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 141fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 142fd4e5da5Sopenharmony_ci const auto context = 143fd4e5da5Sopenharmony_ci BuildModule(env, consumer, shader, kReduceAssembleOption); 144fd4e5da5Sopenharmony_ci 145fd4e5da5Sopenharmony_ci auto ops = RemoveUnusedStructMemberReductionOpportunityFinder() 146fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 147fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 148fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 149fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 150fd4e5da5Sopenharmony_ci 151fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 152fd4e5da5Sopenharmony_ci 153fd4e5da5Sopenharmony_ci std::string expected = R"( 154fd4e5da5Sopenharmony_ci OpCapability Shader 155fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 156fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 157fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 158fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 159fd4e5da5Sopenharmony_ci OpSource ESSL 310 160fd4e5da5Sopenharmony_ci OpMemberDecorate %10 0 Offset 4 161fd4e5da5Sopenharmony_ci OpDecorate %10 Block 162fd4e5da5Sopenharmony_ci OpDecorate %12 DescriptorSet 0 163fd4e5da5Sopenharmony_ci OpDecorate %12 Binding 0 164fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 165fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 166fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 167fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 168fd4e5da5Sopenharmony_ci %9 = OpTypeInt 32 1 169fd4e5da5Sopenharmony_ci %10 = OpTypeStruct %6 170fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %10 171fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Uniform 172fd4e5da5Sopenharmony_ci %13 = OpConstant %9 1 173fd4e5da5Sopenharmony_ci %20 = OpConstant %9 0 174fd4e5da5Sopenharmony_ci %14 = OpTypePointer Uniform %6 175fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 176fd4e5da5Sopenharmony_ci %5 = OpLabel 177fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 178fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %12 %20 179fd4e5da5Sopenharmony_ci %16 = OpLoad %6 %15 180fd4e5da5Sopenharmony_ci OpStore %8 %16 181fd4e5da5Sopenharmony_ci OpReturn 182fd4e5da5Sopenharmony_ci OpFunctionEnd 183fd4e5da5Sopenharmony_ci )"; 184fd4e5da5Sopenharmony_ci 185fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 186fd4e5da5Sopenharmony_ci} 187fd4e5da5Sopenharmony_ci 188fd4e5da5Sopenharmony_ciTEST(RemoveUnusedStructMemberTest, DoNotRemoveNamedMemberRemoveOneMember) { 189fd4e5da5Sopenharmony_ci // This illustrates that naming a member is enough to prevent its removal. 190fd4e5da5Sopenharmony_ci // Removal of names is done by a different pass. 191fd4e5da5Sopenharmony_ci 192fd4e5da5Sopenharmony_ci std::string shader = R"( 193fd4e5da5Sopenharmony_ci OpCapability Shader 194fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 195fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 196fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 197fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 198fd4e5da5Sopenharmony_ci OpSource ESSL 310 199fd4e5da5Sopenharmony_ci OpMemberName %7 0 "someName" 200fd4e5da5Sopenharmony_ci OpMemberName %7 1 "someOtherName" 201fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 202fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 203fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 204fd4e5da5Sopenharmony_ci %7 = OpTypeStruct %6 %6 205fd4e5da5Sopenharmony_ci %8 = OpTypePointer Function %7 206fd4e5da5Sopenharmony_ci %50 = OpConstant %6 0 207fd4e5da5Sopenharmony_ci %10 = OpConstant %6 1 208fd4e5da5Sopenharmony_ci %11 = OpConstant %6 2 209fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %7 %10 %11 210fd4e5da5Sopenharmony_ci %13 = OpConstant %6 4 211fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %6 212fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 213fd4e5da5Sopenharmony_ci %5 = OpLabel 214fd4e5da5Sopenharmony_ci %9 = OpVariable %8 Function 215fd4e5da5Sopenharmony_ci OpStore %9 %12 216fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %9 %10 217fd4e5da5Sopenharmony_ci %22 = OpInBoundsAccessChain %14 %9 %10 218fd4e5da5Sopenharmony_ci %20 = OpLoad %7 %9 219fd4e5da5Sopenharmony_ci %21 = OpCompositeExtract %6 %20 1 220fd4e5da5Sopenharmony_ci %23 = OpCompositeInsert %7 %10 %20 1 221fd4e5da5Sopenharmony_ci OpStore %15 %13 222fd4e5da5Sopenharmony_ci OpReturn 223fd4e5da5Sopenharmony_ci OpFunctionEnd 224fd4e5da5Sopenharmony_ci )"; 225fd4e5da5Sopenharmony_ci 226fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 227fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 228fd4e5da5Sopenharmony_ci const auto context = 229fd4e5da5Sopenharmony_ci BuildModule(env, consumer, shader, kReduceAssembleOption); 230fd4e5da5Sopenharmony_ci 231fd4e5da5Sopenharmony_ci auto ops = RemoveUnusedStructMemberReductionOpportunityFinder() 232fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 233fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 234fd4e5da5Sopenharmony_ci} 235fd4e5da5Sopenharmony_ci 236fd4e5da5Sopenharmony_ci} // namespace 237fd4e5da5Sopenharmony_ci} // namespace reduce 238fd4e5da5Sopenharmony_ci} // namespace spvtools 239