Coverage Report

Created: 2023-03-01 07:33

/src/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp
Line
Count
Source (jump to first uncovered line)
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/opt/strip_nonsemantic_info_pass.h"
16
17
#include <cstring>
18
#include <vector>
19
20
#include "source/opt/instruction.h"
21
#include "source/opt/ir_context.h"
22
#include "source/util/string_utils.h"
23
24
namespace spvtools {
25
namespace opt {
26
27
0
Pass::Status StripNonSemanticInfoPass::Process() {
28
0
  bool modified = false;
29
30
0
  std::vector<Instruction*> to_remove;
31
32
0
  bool other_uses_for_decorate_string = false;
33
0
  for (auto& inst : context()->module()->annotations()) {
34
0
    switch (inst.opcode()) {
35
0
      case spv::Op::OpDecorateStringGOOGLE:
36
0
        if (spv::Decoration(inst.GetSingleWordInOperand(1)) ==
37
0
                spv::Decoration::HlslSemanticGOOGLE ||
38
0
            spv::Decoration(inst.GetSingleWordInOperand(1)) ==
39
0
                spv::Decoration::UserTypeGOOGLE) {
40
0
          to_remove.push_back(&inst);
41
0
        } else {
42
0
          other_uses_for_decorate_string = true;
43
0
        }
44
0
        break;
45
46
0
      case spv::Op::OpMemberDecorateStringGOOGLE:
47
0
        if (spv::Decoration(inst.GetSingleWordInOperand(2)) ==
48
0
                spv::Decoration::HlslSemanticGOOGLE ||
49
0
            spv::Decoration(inst.GetSingleWordInOperand(2)) ==
50
0
                spv::Decoration::UserTypeGOOGLE) {
51
0
          to_remove.push_back(&inst);
52
0
        } else {
53
0
          other_uses_for_decorate_string = true;
54
0
        }
55
0
        break;
56
57
0
      case spv::Op::OpDecorateId:
58
0
        if (spv::Decoration(inst.GetSingleWordInOperand(1)) ==
59
0
            spv::Decoration::HlslCounterBufferGOOGLE) {
60
0
          to_remove.push_back(&inst);
61
0
        }
62
0
        break;
63
64
0
      default:
65
0
        break;
66
0
    }
67
0
  }
68
69
0
  for (auto& inst : context()->module()->extensions()) {
70
0
    const std::string ext_name = inst.GetInOperand(0).AsString();
71
0
    if (ext_name == "SPV_GOOGLE_hlsl_functionality1") {
72
0
      to_remove.push_back(&inst);
73
0
    } else if (ext_name == "SPV_GOOGLE_user_type") {
74
0
      to_remove.push_back(&inst);
75
0
    } else if (!other_uses_for_decorate_string &&
76
0
               ext_name == "SPV_GOOGLE_decorate_string") {
77
0
      to_remove.push_back(&inst);
78
0
    } else if (ext_name == "SPV_KHR_non_semantic_info") {
79
0
      to_remove.push_back(&inst);
80
0
    }
81
0
  }
82
83
  // remove any extended inst imports that are non semantic
84
0
  std::unordered_set<uint32_t> non_semantic_sets;
85
0
  for (auto& inst : context()->module()->ext_inst_imports()) {
86
0
    assert(inst.opcode() == spv::Op::OpExtInstImport &&
87
0
           "Expecting an import of an extension's instruction set.");
88
0
    const std::string extension_name = inst.GetInOperand(0).AsString();
89
0
    if (spvtools::utils::starts_with(extension_name, "NonSemantic.")) {
90
0
      non_semantic_sets.insert(inst.result_id());
91
0
      to_remove.push_back(&inst);
92
0
    }
93
0
  }
94
95
  // if we removed some non-semantic sets, then iterate over the instructions in
96
  // the module to remove any OpExtInst that referenced those sets
97
0
  if (!non_semantic_sets.empty()) {
98
0
    context()->module()->ForEachInst(
99
0
        [&non_semantic_sets, &to_remove](Instruction* inst) {
100
0
          if (inst->opcode() == spv::Op::OpExtInst) {
101
0
            if (non_semantic_sets.find(inst->GetSingleWordInOperand(0)) !=
102
0
                non_semantic_sets.end()) {
103
0
              to_remove.push_back(inst);
104
0
            }
105
0
          }
106
0
        },
107
0
        true);
108
0
  }
109
110
0
  for (auto* inst : to_remove) {
111
0
    modified = true;
112
0
    context()->KillInst(inst);
113
0
  }
114
115
0
  return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
116
0
}
117
118
}  // namespace opt
119
}  // namespace spvtools