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