1 // Copyright (c) 2019 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/fuzz/transformation_set_selection_control.h"
16
17 namespace spvtools {
18 namespace fuzz {
19
TransformationSetSelectionControl(protobufs::TransformationSetSelectionControl message)20 TransformationSetSelectionControl::TransformationSetSelectionControl(
21 protobufs::TransformationSetSelectionControl message)
22 : message_(std::move(message)) {}
23
TransformationSetSelectionControl(uint32_t block_id,uint32_t selection_control)24 TransformationSetSelectionControl::TransformationSetSelectionControl(
25 uint32_t block_id, uint32_t selection_control) {
26 message_.set_block_id(block_id);
27 message_.set_selection_control(selection_control);
28 }
29
IsApplicable(opt::IRContext * ir_context,const TransformationContext &) const30 bool TransformationSetSelectionControl::IsApplicable(
31 opt::IRContext* ir_context, const TransformationContext& /*unused*/) const {
32 assert((spv::SelectionControlMask(message_.selection_control()) ==
33 spv::SelectionControlMask::MaskNone ||
34 spv::SelectionControlMask(message_.selection_control()) ==
35 spv::SelectionControlMask::Flatten ||
36 spv::SelectionControlMask(message_.selection_control()) ==
37 spv::SelectionControlMask::DontFlatten) &&
38 "Selection control should never be set to something other than "
39 "'None', 'Flatten' or 'DontFlatten'");
40 if (auto block = ir_context->get_instr_block(message_.block_id())) {
41 if (auto merge_inst = block->GetMergeInst()) {
42 return merge_inst->opcode() == spv::Op::OpSelectionMerge;
43 }
44 }
45 // Either the block did not exit, or did not end with OpSelectionMerge.
46 return false;
47 }
48
Apply(opt::IRContext * ir_context,TransformationContext *) const49 void TransformationSetSelectionControl::Apply(
50 opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
51 ir_context->get_instr_block(message_.block_id())
52 ->GetMergeInst()
53 ->SetInOperand(1, {message_.selection_control()});
54 }
55
ToMessage() const56 protobufs::Transformation TransformationSetSelectionControl::ToMessage() const {
57 protobufs::Transformation result;
58 *result.mutable_set_selection_control() = message_;
59 return result;
60 }
61
GetFreshIds() const62 std::unordered_set<uint32_t> TransformationSetSelectionControl::GetFreshIds()
63 const {
64 return std::unordered_set<uint32_t>();
65 }
66
67 } // namespace fuzz
68 } // namespace spvtools
69