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
AllExtensionsSupported() const26 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
ProcessImpl()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
Process()59 Pass::Status LocalMultiStoreElimPass::Process() {
60 // Initialize extension whitelist
61 InitExtensions();
62 return ProcessImpl();
63 }
64
InitExtensions()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