1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 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_instruction_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 "source/util/make_unique.h" 20fd4e5da5Sopenharmony_ci#include "test/reduce/reduce_test_util.h" 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_cinamespace spvtools { 23fd4e5da5Sopenharmony_cinamespace reduce { 24fd4e5da5Sopenharmony_cinamespace { 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciconst spv_target_env kEnv = SPV_ENV_UNIVERSAL_1_3; 27fd4e5da5Sopenharmony_ci 28fd4e5da5Sopenharmony_ciTEST(RemoveUnusedInstructionReductionPassTest, RemoveStores) { 29fd4e5da5Sopenharmony_ci // A module with some unused instructions, including some unused OpStore 30fd4e5da5Sopenharmony_ci // instructions. 31fd4e5da5Sopenharmony_ci 32fd4e5da5Sopenharmony_ci RemoveUnusedInstructionReductionOpportunityFinder finder(true); 33fd4e5da5Sopenharmony_ci 34fd4e5da5Sopenharmony_ci const std::string original = R"( 35fd4e5da5Sopenharmony_ci OpCapability Shader 36fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 37fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 38fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 39fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 40fd4e5da5Sopenharmony_ci OpSource ESSL 310 ; 0 41fd4e5da5Sopenharmony_ci OpName %4 "main" ; 1 42fd4e5da5Sopenharmony_ci OpName %8 "a" ; 2 43fd4e5da5Sopenharmony_ci OpName %10 "b" ; 3 44fd4e5da5Sopenharmony_ci OpName %12 "c" ; 4 45fd4e5da5Sopenharmony_ci OpName %14 "d" ; 5 46fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 47fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 48fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 49fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 50fd4e5da5Sopenharmony_ci %9 = OpConstant %6 10 51fd4e5da5Sopenharmony_ci %11 = OpConstant %6 20 52fd4e5da5Sopenharmony_ci %13 = OpConstant %6 30 53fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 54fd4e5da5Sopenharmony_ci %5 = OpLabel 55fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 56fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function 57fd4e5da5Sopenharmony_ci %12 = OpVariable %7 Function 58fd4e5da5Sopenharmony_ci %14 = OpVariable %7 Function 59fd4e5da5Sopenharmony_ci OpStore %8 %9 ; 6 60fd4e5da5Sopenharmony_ci OpStore %10 %11 ; 7 61fd4e5da5Sopenharmony_ci OpStore %12 %13 ; 8 62fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 63fd4e5da5Sopenharmony_ci OpStore %14 %15 ; 9 64fd4e5da5Sopenharmony_ci OpReturn 65fd4e5da5Sopenharmony_ci OpFunctionEnd 66fd4e5da5Sopenharmony_ci 67fd4e5da5Sopenharmony_ci )"; 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ci const MessageConsumer consumer = nullptr; 70fd4e5da5Sopenharmony_ci const auto context = 71fd4e5da5Sopenharmony_ci BuildModule(kEnv, consumer, original, kReduceAssembleOption); 72fd4e5da5Sopenharmony_ci 73fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 74fd4e5da5Sopenharmony_ci 75fd4e5da5Sopenharmony_ci auto ops = finder.GetAvailableOpportunities(context.get(), 0); 76fd4e5da5Sopenharmony_ci 77fd4e5da5Sopenharmony_ci ASSERT_EQ(10, ops.size()); 78fd4e5da5Sopenharmony_ci 79fd4e5da5Sopenharmony_ci for (auto& op : ops) { 80fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 81fd4e5da5Sopenharmony_ci op->TryToApply(); 82fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 83fd4e5da5Sopenharmony_ci } 84fd4e5da5Sopenharmony_ci 85fd4e5da5Sopenharmony_ci const std::string step_2 = R"( 86fd4e5da5Sopenharmony_ci OpCapability Shader 87fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 88fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 89fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 90fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 91fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 92fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 93fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 94fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 95fd4e5da5Sopenharmony_ci %9 = OpConstant %6 10 ; 0 96fd4e5da5Sopenharmony_ci %11 = OpConstant %6 20 ; 1 97fd4e5da5Sopenharmony_ci %13 = OpConstant %6 30 ; 2 98fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 99fd4e5da5Sopenharmony_ci %5 = OpLabel 100fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 101fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function ; 3 102fd4e5da5Sopenharmony_ci %12 = OpVariable %7 Function ; 4 103fd4e5da5Sopenharmony_ci %14 = OpVariable %7 Function ; 5 104fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 ; 6 105fd4e5da5Sopenharmony_ci OpReturn 106fd4e5da5Sopenharmony_ci OpFunctionEnd 107fd4e5da5Sopenharmony_ci )"; 108fd4e5da5Sopenharmony_ci 109fd4e5da5Sopenharmony_ci CheckEqual(kEnv, step_2, context.get()); 110fd4e5da5Sopenharmony_ci 111fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 112fd4e5da5Sopenharmony_ci 113fd4e5da5Sopenharmony_ci ASSERT_EQ(7, ops.size()); 114fd4e5da5Sopenharmony_ci 115fd4e5da5Sopenharmony_ci for (auto& op : ops) { 116fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 117fd4e5da5Sopenharmony_ci op->TryToApply(); 118fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 119fd4e5da5Sopenharmony_ci } 120fd4e5da5Sopenharmony_ci 121fd4e5da5Sopenharmony_ci const std::string step_3 = R"( 122fd4e5da5Sopenharmony_ci OpCapability Shader 123fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 124fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 125fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 126fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 127fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 128fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 129fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 130fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 131fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 132fd4e5da5Sopenharmony_ci %5 = OpLabel 133fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function ; 0 134fd4e5da5Sopenharmony_ci OpReturn 135fd4e5da5Sopenharmony_ci OpFunctionEnd 136fd4e5da5Sopenharmony_ci )"; 137fd4e5da5Sopenharmony_ci 138fd4e5da5Sopenharmony_ci CheckEqual(kEnv, step_3, context.get()); 139fd4e5da5Sopenharmony_ci 140fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 141fd4e5da5Sopenharmony_ci 142fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 143fd4e5da5Sopenharmony_ci 144fd4e5da5Sopenharmony_ci for (auto& op : ops) { 145fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 146fd4e5da5Sopenharmony_ci op->TryToApply(); 147fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 148fd4e5da5Sopenharmony_ci } 149fd4e5da5Sopenharmony_ci 150fd4e5da5Sopenharmony_ci const std::string step_4 = R"( 151fd4e5da5Sopenharmony_ci OpCapability Shader 152fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 153fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 154fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 155fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 156fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 157fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 158fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 159fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 ; 0 160fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 161fd4e5da5Sopenharmony_ci %5 = OpLabel 162fd4e5da5Sopenharmony_ci OpReturn 163fd4e5da5Sopenharmony_ci OpFunctionEnd 164fd4e5da5Sopenharmony_ci )"; 165fd4e5da5Sopenharmony_ci 166fd4e5da5Sopenharmony_ci CheckEqual(kEnv, step_4, context.get()); 167fd4e5da5Sopenharmony_ci 168fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 169fd4e5da5Sopenharmony_ci 170fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 171fd4e5da5Sopenharmony_ci 172fd4e5da5Sopenharmony_ci for (auto& op : ops) { 173fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 174fd4e5da5Sopenharmony_ci op->TryToApply(); 175fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 176fd4e5da5Sopenharmony_ci } 177fd4e5da5Sopenharmony_ci 178fd4e5da5Sopenharmony_ci const std::string step_5 = R"( 179fd4e5da5Sopenharmony_ci OpCapability Shader 180fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 181fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 182fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 183fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 184fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 185fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 186fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 ; 0 187fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 188fd4e5da5Sopenharmony_ci %5 = OpLabel 189fd4e5da5Sopenharmony_ci OpReturn 190fd4e5da5Sopenharmony_ci OpFunctionEnd 191fd4e5da5Sopenharmony_ci )"; 192fd4e5da5Sopenharmony_ci 193fd4e5da5Sopenharmony_ci CheckEqual(kEnv, step_5, context.get()); 194fd4e5da5Sopenharmony_ci 195fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 196fd4e5da5Sopenharmony_ci 197fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 198fd4e5da5Sopenharmony_ci 199fd4e5da5Sopenharmony_ci for (auto& op : ops) { 200fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 201fd4e5da5Sopenharmony_ci op->TryToApply(); 202fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 203fd4e5da5Sopenharmony_ci } 204fd4e5da5Sopenharmony_ci 205fd4e5da5Sopenharmony_ci const std::string step_6 = R"( 206fd4e5da5Sopenharmony_ci OpCapability Shader 207fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 208fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 209fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 210fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 211fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 212fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 213fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 214fd4e5da5Sopenharmony_ci %5 = OpLabel 215fd4e5da5Sopenharmony_ci OpReturn 216fd4e5da5Sopenharmony_ci OpFunctionEnd 217fd4e5da5Sopenharmony_ci )"; 218fd4e5da5Sopenharmony_ci 219fd4e5da5Sopenharmony_ci CheckEqual(kEnv, step_6, context.get()); 220fd4e5da5Sopenharmony_ci 221fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 222fd4e5da5Sopenharmony_ci 223fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 224fd4e5da5Sopenharmony_ci} 225fd4e5da5Sopenharmony_ci 226fd4e5da5Sopenharmony_ciTEST(RemoveUnusedInstructionReductionPassTest, Referenced) { 227fd4e5da5Sopenharmony_ci // A module with some unused global variables, constants, and types. Some will 228fd4e5da5Sopenharmony_ci // not be removed initially because of the OpDecorate instructions. 229fd4e5da5Sopenharmony_ci 230fd4e5da5Sopenharmony_ci RemoveUnusedInstructionReductionOpportunityFinder finder(true); 231fd4e5da5Sopenharmony_ci 232fd4e5da5Sopenharmony_ci const std::string shader = R"( 233fd4e5da5Sopenharmony_ci OpCapability Shader 234fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 235fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 236fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 237fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 238fd4e5da5Sopenharmony_ci OpSource ESSL 310 ; 1 239fd4e5da5Sopenharmony_ci OpName %4 "main" ; 2 240fd4e5da5Sopenharmony_ci OpName %12 "a" ; 3 241fd4e5da5Sopenharmony_ci OpDecorate %12 RelaxedPrecision ; 4 242fd4e5da5Sopenharmony_ci OpDecorate %13 RelaxedPrecision ; 5 243fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 244fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 245fd4e5da5Sopenharmony_ci %6 = OpTypeBool 246fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %6 ; 6 247fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 248fd4e5da5Sopenharmony_ci %11 = OpTypePointer Private %10 249fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Private 250fd4e5da5Sopenharmony_ci %13 = OpConstant %10 1 251fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 252fd4e5da5Sopenharmony_ci %5 = OpLabel 253fd4e5da5Sopenharmony_ci OpReturn 254fd4e5da5Sopenharmony_ci OpFunctionEnd 255fd4e5da5Sopenharmony_ci )"; 256fd4e5da5Sopenharmony_ci 257fd4e5da5Sopenharmony_ci auto context = BuildModule(kEnv, nullptr, shader, kReduceAssembleOption); 258fd4e5da5Sopenharmony_ci 259fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 260fd4e5da5Sopenharmony_ci 261fd4e5da5Sopenharmony_ci auto ops = finder.GetAvailableOpportunities(context.get(), 0); 262fd4e5da5Sopenharmony_ci 263fd4e5da5Sopenharmony_ci ASSERT_EQ(6, ops.size()); 264fd4e5da5Sopenharmony_ci 265fd4e5da5Sopenharmony_ci for (auto& op : ops) { 266fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 267fd4e5da5Sopenharmony_ci op->TryToApply(); 268fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 269fd4e5da5Sopenharmony_ci } 270fd4e5da5Sopenharmony_ci 271fd4e5da5Sopenharmony_ci std::string after = R"( 272fd4e5da5Sopenharmony_ci OpCapability Shader 273fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 274fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 275fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 276fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 277fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 278fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 279fd4e5da5Sopenharmony_ci %6 = OpTypeBool ; 1 280fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 281fd4e5da5Sopenharmony_ci %11 = OpTypePointer Private %10 282fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Private ; 2 283fd4e5da5Sopenharmony_ci %13 = OpConstant %10 1 ; 3 284fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 285fd4e5da5Sopenharmony_ci %5 = OpLabel 286fd4e5da5Sopenharmony_ci OpReturn 287fd4e5da5Sopenharmony_ci OpFunctionEnd 288fd4e5da5Sopenharmony_ci )"; 289fd4e5da5Sopenharmony_ci 290fd4e5da5Sopenharmony_ci CheckEqual(kEnv, after, context.get()); 291fd4e5da5Sopenharmony_ci 292fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 293fd4e5da5Sopenharmony_ci 294fd4e5da5Sopenharmony_ci ASSERT_EQ(3, ops.size()); 295fd4e5da5Sopenharmony_ci 296fd4e5da5Sopenharmony_ci for (auto& op : ops) { 297fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 298fd4e5da5Sopenharmony_ci op->TryToApply(); 299fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 300fd4e5da5Sopenharmony_ci } 301fd4e5da5Sopenharmony_ci 302fd4e5da5Sopenharmony_ci std::string after_2 = R"( 303fd4e5da5Sopenharmony_ci OpCapability Shader 304fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 305fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 306fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 307fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 308fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 309fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 310fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 311fd4e5da5Sopenharmony_ci %11 = OpTypePointer Private %10 ; 1 312fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 313fd4e5da5Sopenharmony_ci %5 = OpLabel 314fd4e5da5Sopenharmony_ci OpReturn 315fd4e5da5Sopenharmony_ci OpFunctionEnd 316fd4e5da5Sopenharmony_ci )"; 317fd4e5da5Sopenharmony_ci 318fd4e5da5Sopenharmony_ci CheckEqual(kEnv, after_2, context.get()); 319fd4e5da5Sopenharmony_ci 320fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 321fd4e5da5Sopenharmony_ci 322fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 323fd4e5da5Sopenharmony_ci 324fd4e5da5Sopenharmony_ci for (auto& op : ops) { 325fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 326fd4e5da5Sopenharmony_ci op->TryToApply(); 327fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 328fd4e5da5Sopenharmony_ci } 329fd4e5da5Sopenharmony_ci 330fd4e5da5Sopenharmony_ci std::string after_3 = R"( 331fd4e5da5Sopenharmony_ci OpCapability Shader 332fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 333fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 334fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 335fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 336fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 337fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 338fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 ; 1 339fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 340fd4e5da5Sopenharmony_ci %5 = OpLabel 341fd4e5da5Sopenharmony_ci OpReturn 342fd4e5da5Sopenharmony_ci OpFunctionEnd 343fd4e5da5Sopenharmony_ci )"; 344fd4e5da5Sopenharmony_ci 345fd4e5da5Sopenharmony_ci CheckEqual(kEnv, after_3, context.get()); 346fd4e5da5Sopenharmony_ci 347fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 348fd4e5da5Sopenharmony_ci 349fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 350fd4e5da5Sopenharmony_ci 351fd4e5da5Sopenharmony_ci for (auto& op : ops) { 352fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 353fd4e5da5Sopenharmony_ci op->TryToApply(); 354fd4e5da5Sopenharmony_ci CheckValid(kEnv, context.get()); 355fd4e5da5Sopenharmony_ci } 356fd4e5da5Sopenharmony_ci 357fd4e5da5Sopenharmony_ci std::string after_4 = R"( 358fd4e5da5Sopenharmony_ci OpCapability Shader 359fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 360fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 361fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 362fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 363fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 364fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 365fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 366fd4e5da5Sopenharmony_ci %5 = OpLabel 367fd4e5da5Sopenharmony_ci OpReturn 368fd4e5da5Sopenharmony_ci OpFunctionEnd 369fd4e5da5Sopenharmony_ci )"; 370fd4e5da5Sopenharmony_ci 371fd4e5da5Sopenharmony_ci CheckEqual(kEnv, after_4, context.get()); 372fd4e5da5Sopenharmony_ci 373fd4e5da5Sopenharmony_ci ops = finder.GetAvailableOpportunities(context.get(), 0); 374fd4e5da5Sopenharmony_ci 375fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 376fd4e5da5Sopenharmony_ci} 377fd4e5da5Sopenharmony_ci 378fd4e5da5Sopenharmony_ciTEST(RemoveUnusedResourceVariableTest, RemoveUnusedResourceVariables) { 379fd4e5da5Sopenharmony_ci std::string shader = R"( 380fd4e5da5Sopenharmony_ci OpCapability Shader 381fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 382fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 383fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 384fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 385fd4e5da5Sopenharmony_ci OpMemberDecorate %9 0 Offset 0 386fd4e5da5Sopenharmony_ci OpDecorate %9 Block 387fd4e5da5Sopenharmony_ci OpDecorate %11 DescriptorSet 0 388fd4e5da5Sopenharmony_ci OpDecorate %11 Binding 1 389fd4e5da5Sopenharmony_ci OpMemberDecorate %16 0 Offset 0 390fd4e5da5Sopenharmony_ci OpMemberDecorate %16 1 Offset 4 391fd4e5da5Sopenharmony_ci OpDecorate %16 Block 392fd4e5da5Sopenharmony_ci OpDecorate %18 DescriptorSet 0 393fd4e5da5Sopenharmony_ci OpDecorate %18 Binding 0 394fd4e5da5Sopenharmony_ci OpMemberDecorate %19 0 Offset 0 395fd4e5da5Sopenharmony_ci OpDecorate %19 BufferBlock 396fd4e5da5Sopenharmony_ci OpDecorate %21 DescriptorSet 1 397fd4e5da5Sopenharmony_ci OpDecorate %21 Binding 0 398fd4e5da5Sopenharmony_ci OpMemberDecorate %22 0 Offset 0 399fd4e5da5Sopenharmony_ci OpDecorate %22 Block 400fd4e5da5Sopenharmony_ci OpDecorate %29 DescriptorSet 1 401fd4e5da5Sopenharmony_ci OpDecorate %29 Binding 1 402fd4e5da5Sopenharmony_ci OpDecorate %32 DescriptorSet 1 403fd4e5da5Sopenharmony_ci OpDecorate %32 Binding 2 404fd4e5da5Sopenharmony_ci OpDecorate %32 NonReadable 405fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 406fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 407fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 408fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 409fd4e5da5Sopenharmony_ci %10 = OpTypePointer Uniform %9 410fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Uniform 411fd4e5da5Sopenharmony_ci %13 = OpTypePointer Uniform %6 412fd4e5da5Sopenharmony_ci %16 = OpTypeStruct %6 %6 413fd4e5da5Sopenharmony_ci %17 = OpTypePointer Uniform %16 414fd4e5da5Sopenharmony_ci %18 = OpVariable %17 Uniform 415fd4e5da5Sopenharmony_ci %19 = OpTypeStruct %6 416fd4e5da5Sopenharmony_ci %20 = OpTypePointer Uniform %19 417fd4e5da5Sopenharmony_ci %21 = OpVariable %20 Uniform 418fd4e5da5Sopenharmony_ci %22 = OpTypeStruct %6 419fd4e5da5Sopenharmony_ci %23 = OpTypePointer PushConstant %22 420fd4e5da5Sopenharmony_ci %24 = OpVariable %23 PushConstant 421fd4e5da5Sopenharmony_ci %25 = OpTypeFloat 32 422fd4e5da5Sopenharmony_ci %26 = OpTypeImage %25 2D 0 0 0 1 Unknown 423fd4e5da5Sopenharmony_ci %27 = OpTypeSampledImage %26 424fd4e5da5Sopenharmony_ci %28 = OpTypePointer UniformConstant %27 425fd4e5da5Sopenharmony_ci %29 = OpVariable %28 UniformConstant 426fd4e5da5Sopenharmony_ci %30 = OpTypeImage %25 2D 0 0 0 2 Unknown 427fd4e5da5Sopenharmony_ci %31 = OpTypePointer UniformConstant %30 428fd4e5da5Sopenharmony_ci %32 = OpVariable %31 UniformConstant 429fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 430fd4e5da5Sopenharmony_ci %5 = OpLabel 431fd4e5da5Sopenharmony_ci OpReturn 432fd4e5da5Sopenharmony_ci OpFunctionEnd 433fd4e5da5Sopenharmony_ci )"; 434fd4e5da5Sopenharmony_ci 435fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 436fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 437fd4e5da5Sopenharmony_ci const auto context = 438fd4e5da5Sopenharmony_ci BuildModule(env, consumer, shader, kReduceAssembleOption); 439fd4e5da5Sopenharmony_ci 440fd4e5da5Sopenharmony_ci auto ops = RemoveUnusedInstructionReductionOpportunityFinder(true) 441fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 442fd4e5da5Sopenharmony_ci ASSERT_EQ(7, ops.size()); 443fd4e5da5Sopenharmony_ci 444fd4e5da5Sopenharmony_ci for (auto& op : ops) { 445fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 446fd4e5da5Sopenharmony_ci op->TryToApply(); 447fd4e5da5Sopenharmony_ci } 448fd4e5da5Sopenharmony_ci 449fd4e5da5Sopenharmony_ci std::string expected_1 = R"( 450fd4e5da5Sopenharmony_ci OpCapability Shader 451fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 452fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 453fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 454fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 455fd4e5da5Sopenharmony_ci OpMemberDecorate %9 0 Offset 0 456fd4e5da5Sopenharmony_ci OpDecorate %9 Block 457fd4e5da5Sopenharmony_ci OpMemberDecorate %16 0 Offset 0 458fd4e5da5Sopenharmony_ci OpMemberDecorate %16 1 Offset 4 459fd4e5da5Sopenharmony_ci OpDecorate %16 Block 460fd4e5da5Sopenharmony_ci OpMemberDecorate %19 0 Offset 0 461fd4e5da5Sopenharmony_ci OpDecorate %19 BufferBlock 462fd4e5da5Sopenharmony_ci OpMemberDecorate %22 0 Offset 0 463fd4e5da5Sopenharmony_ci OpDecorate %22 Block 464fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 465fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 466fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 467fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 468fd4e5da5Sopenharmony_ci %10 = OpTypePointer Uniform %9 469fd4e5da5Sopenharmony_ci %16 = OpTypeStruct %6 %6 470fd4e5da5Sopenharmony_ci %17 = OpTypePointer Uniform %16 471fd4e5da5Sopenharmony_ci %19 = OpTypeStruct %6 472fd4e5da5Sopenharmony_ci %20 = OpTypePointer Uniform %19 473fd4e5da5Sopenharmony_ci %22 = OpTypeStruct %6 474fd4e5da5Sopenharmony_ci %23 = OpTypePointer PushConstant %22 475fd4e5da5Sopenharmony_ci %25 = OpTypeFloat 32 476fd4e5da5Sopenharmony_ci %26 = OpTypeImage %25 2D 0 0 0 1 Unknown 477fd4e5da5Sopenharmony_ci %27 = OpTypeSampledImage %26 478fd4e5da5Sopenharmony_ci %28 = OpTypePointer UniformConstant %27 479fd4e5da5Sopenharmony_ci %30 = OpTypeImage %25 2D 0 0 0 2 Unknown 480fd4e5da5Sopenharmony_ci %31 = OpTypePointer UniformConstant %30 481fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 482fd4e5da5Sopenharmony_ci %5 = OpLabel 483fd4e5da5Sopenharmony_ci OpReturn 484fd4e5da5Sopenharmony_ci OpFunctionEnd 485fd4e5da5Sopenharmony_ci )"; 486fd4e5da5Sopenharmony_ci 487fd4e5da5Sopenharmony_ci CheckEqual(env, expected_1, context.get()); 488fd4e5da5Sopenharmony_ci 489fd4e5da5Sopenharmony_ci ops = RemoveUnusedInstructionReductionOpportunityFinder(true) 490fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 491fd4e5da5Sopenharmony_ci ASSERT_EQ(6, ops.size()); 492fd4e5da5Sopenharmony_ci 493fd4e5da5Sopenharmony_ci for (auto& op : ops) { 494fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 495fd4e5da5Sopenharmony_ci op->TryToApply(); 496fd4e5da5Sopenharmony_ci } 497fd4e5da5Sopenharmony_ci 498fd4e5da5Sopenharmony_ci std::string expected_2 = R"( 499fd4e5da5Sopenharmony_ci OpCapability Shader 500fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 501fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 502fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 503fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 504fd4e5da5Sopenharmony_ci OpMemberDecorate %9 0 Offset 0 505fd4e5da5Sopenharmony_ci OpDecorate %9 Block 506fd4e5da5Sopenharmony_ci OpMemberDecorate %16 0 Offset 0 507fd4e5da5Sopenharmony_ci OpMemberDecorate %16 1 Offset 4 508fd4e5da5Sopenharmony_ci OpDecorate %16 Block 509fd4e5da5Sopenharmony_ci OpMemberDecorate %19 0 Offset 0 510fd4e5da5Sopenharmony_ci OpDecorate %19 BufferBlock 511fd4e5da5Sopenharmony_ci OpMemberDecorate %22 0 Offset 0 512fd4e5da5Sopenharmony_ci OpDecorate %22 Block 513fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 514fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 515fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 516fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 517fd4e5da5Sopenharmony_ci %16 = OpTypeStruct %6 %6 518fd4e5da5Sopenharmony_ci %19 = OpTypeStruct %6 519fd4e5da5Sopenharmony_ci %22 = OpTypeStruct %6 520fd4e5da5Sopenharmony_ci %25 = OpTypeFloat 32 521fd4e5da5Sopenharmony_ci %26 = OpTypeImage %25 2D 0 0 0 1 Unknown 522fd4e5da5Sopenharmony_ci %27 = OpTypeSampledImage %26 523fd4e5da5Sopenharmony_ci %30 = OpTypeImage %25 2D 0 0 0 2 Unknown 524fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 525fd4e5da5Sopenharmony_ci %5 = OpLabel 526fd4e5da5Sopenharmony_ci OpReturn 527fd4e5da5Sopenharmony_ci OpFunctionEnd 528fd4e5da5Sopenharmony_ci )"; 529fd4e5da5Sopenharmony_ci 530fd4e5da5Sopenharmony_ci CheckEqual(env, expected_2, context.get()); 531fd4e5da5Sopenharmony_ci 532fd4e5da5Sopenharmony_ci ops = RemoveUnusedInstructionReductionOpportunityFinder(true) 533fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 534fd4e5da5Sopenharmony_ci ASSERT_EQ(6, ops.size()); 535fd4e5da5Sopenharmony_ci 536fd4e5da5Sopenharmony_ci for (auto& op : ops) { 537fd4e5da5Sopenharmony_ci ASSERT_TRUE(op->PreconditionHolds()); 538fd4e5da5Sopenharmony_ci op->TryToApply(); 539fd4e5da5Sopenharmony_ci } 540fd4e5da5Sopenharmony_ci 541fd4e5da5Sopenharmony_ci std::string expected_3 = R"( 542fd4e5da5Sopenharmony_ci OpCapability Shader 543fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 544fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 545fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 546fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 547fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 548fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 549fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 550fd4e5da5Sopenharmony_ci %25 = OpTypeFloat 32 551fd4e5da5Sopenharmony_ci %26 = OpTypeImage %25 2D 0 0 0 1 Unknown 552fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 553fd4e5da5Sopenharmony_ci %5 = OpLabel 554fd4e5da5Sopenharmony_ci OpReturn 555fd4e5da5Sopenharmony_ci OpFunctionEnd 556fd4e5da5Sopenharmony_ci )"; 557fd4e5da5Sopenharmony_ci 558fd4e5da5Sopenharmony_ci CheckEqual(env, expected_3, context.get()); 559fd4e5da5Sopenharmony_ci} 560fd4e5da5Sopenharmony_ci 561fd4e5da5Sopenharmony_ci} // namespace 562fd4e5da5Sopenharmony_ci} // namespace reduce 563fd4e5da5Sopenharmony_ci} // namespace spvtools 564