1 // Copyright (c) 2017 The Khronos Group Inc. 2 // Copyright (c) 2017 Valve Corporation 3 // Copyright (c) 2017 LunarG Inc. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #include "source/opt/local_ssa_elim_pass.h" 18 19 #include "source/cfa.h" 20 #include "source/opt/iterator.h" 21 #include "source/opt/ssa_rewrite_pass.h" 22 23 namespace spvtools { 24 namespace opt { 25 26 bool LocalMultiStoreElimPass::AllExtensionsSupported() const { 27 // If any extension not in whitelist, return false 28 for (auto& ei : get_module()->extensions()) { 29 const char* extName = 30 reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); 31 if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) 32 return false; 33 } 34 return true; 35 } 36 37 Pass::Status LocalMultiStoreElimPass::ProcessImpl() { 38 // Assumes relaxed logical addressing only (see instruction.h) 39 // TODO(greg-lunarg): Add support for physical addressing 40 if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses)) 41 return Status::SuccessWithoutChange; 42 // Do not process if module contains OpGroupDecorate. Additional 43 // support required in KillNamesAndDecorates(). 44 // TODO(greg-lunarg): Add support for OpGroupDecorate 45 for (auto& ai : get_module()->annotations()) 46 if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; 47 // Do not process if any disallowed extensions are enabled 48 if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; 49 // Process functions 50 ProcessFunction pfn = [this](Function* fp) { 51 return SSARewriter(this).RewriteFunctionIntoSSA(fp); 52 }; 53 bool modified = context()->ProcessEntryPointCallTree(pfn); 54 return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; 55 } 56 57 LocalMultiStoreElimPass::LocalMultiStoreElimPass() = default; 58 59 Pass::Status LocalMultiStoreElimPass::Process() { 60 // Initialize extension whitelist 61 InitExtensions(); 62 return ProcessImpl(); 63 } 64 65 void LocalMultiStoreElimPass::InitExtensions() { 66 extensions_whitelist_.clear(); 67 extensions_whitelist_.insert({ 68 "SPV_AMD_shader_explicit_vertex_parameter", 69 "SPV_AMD_shader_trinary_minmax", 70 "SPV_AMD_gcn_shader", 71 "SPV_KHR_shader_ballot", 72 "SPV_AMD_shader_ballot", 73 "SPV_AMD_gpu_shader_half_float", 74 "SPV_KHR_shader_draw_parameters", 75 "SPV_KHR_subgroup_vote", 76 "SPV_KHR_16bit_storage", 77 "SPV_KHR_device_group", 78 "SPV_KHR_multiview", 79 "SPV_NVX_multiview_per_view_attributes", 80 "SPV_NV_viewport_array2", 81 "SPV_NV_stereo_view_rendering", 82 "SPV_NV_sample_mask_override_coverage", 83 "SPV_NV_geometry_shader_passthrough", 84 "SPV_AMD_texture_gather_bias_lod", 85 "SPV_KHR_storage_buffer_storage_class", 86 // SPV_KHR_variable_pointers 87 // Currently do not support extended pointer expressions 88 "SPV_AMD_gpu_shader_int16", 89 "SPV_KHR_post_depth_coverage", 90 "SPV_KHR_shader_atomic_counter_ops", 91 "SPV_EXT_shader_stencil_export", 92 "SPV_EXT_shader_viewport_index_layer", 93 "SPV_AMD_shader_image_load_store_lod", 94 "SPV_AMD_shader_fragment_mask", 95 "SPV_EXT_fragment_fully_covered", 96 "SPV_AMD_gpu_shader_half_float_fetch", 97 "SPV_GOOGLE_decorate_string", 98 "SPV_GOOGLE_hlsl_functionality1", 99 "SPV_NV_shader_subgroup_partitioned", 100 "SPV_EXT_descriptor_indexing", 101 "SPV_NV_fragment_shader_barycentric", 102 "SPV_NV_compute_shader_derivatives", 103 "SPV_NV_shader_image_footprint", 104 "SPV_NV_shading_rate", 105 "SPV_NV_mesh_shader", 106 "SPV_NV_ray_tracing", 107 "SPV_EXT_fragment_invocation_density", 108 }); 109 } 110 111 } // namespace opt 112 } // namespace spvtools 113