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(const spvtools::fuzz::protobufs::TransformationSetSelectionControl & message)20 TransformationSetSelectionControl::TransformationSetSelectionControl(
21 const spvtools::fuzz::protobufs::TransformationSetSelectionControl& message)
22 : message_(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((message_.selection_control() == SpvSelectionControlMaskNone ||
33 message_.selection_control() == SpvSelectionControlFlattenMask ||
34 message_.selection_control() == SpvSelectionControlDontFlattenMask) &&
35 "Selection control should never be set to something other than "
36 "'None', 'Flatten' or 'DontFlatten'");
37 if (auto block = ir_context->get_instr_block(message_.block_id())) {
38 if (auto merge_inst = block->GetMergeInst()) {
39 return merge_inst->opcode() == SpvOpSelectionMerge;
40 }
41 }
42 // Either the block did not exit, or did not end with OpSelectionMerge.
43 return false;
44 }
45
Apply(opt::IRContext * ir_context,TransformationContext *) const46 void TransformationSetSelectionControl::Apply(
47 opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
48 ir_context->get_instr_block(message_.block_id())
49 ->GetMergeInst()
50 ->SetInOperand(1, {message_.selection_control()});
51 }
52
ToMessage() const53 protobufs::Transformation TransformationSetSelectionControl::ToMessage() const {
54 protobufs::Transformation result;
55 *result.mutable_set_selection_control() = message_;
56 return result;
57 }
58
GetFreshIds() const59 std::unordered_set<uint32_t> TransformationSetSelectionControl::GetFreshIds()
60 const {
61 return std::unordered_set<uint32_t>();
62 }
63
64 } // namespace fuzz
65 } // namespace spvtools
66