// Copyright (c) 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_FUZZ_TRANSFORMATION_FLATTEN_CONDITIONAL_BRANCH_H
#define SOURCE_FUZZ_TRANSFORMATION_FLATTEN_CONDITIONAL_BRANCH_H

#include "source/fuzz/transformation.h"

namespace spvtools {
namespace fuzz {

class TransformationFlattenConditionalBranch : public Transformation {
 public:
  explicit TransformationFlattenConditionalBranch(
      const protobufs::TransformationFlattenConditionalBranch& message);

  TransformationFlattenConditionalBranch(
      uint32_t header_block_id, bool true_branch_first,
      const std::vector<protobufs::SideEffectWrapperInfo>&
          side_effect_wrappers_info);

  // - |message_.header_block_id| must be the label id of a reachable selection
  //   header, which ends with an OpBranchConditional instruction.
  // - The header block and the merge block must describe a single-entry,
  //   single-exit region.
  // - The region must not contain barrier or OpSampledImage instructions.
  // - The region must not contain selection or loop constructs.
  // - For each instruction that requires additional fresh ids, then:
  //   - if the instruction is mapped to the required ids for enclosing it by
  //     |message_.side_effect_wrapper_info|, these must be valid (the
  //     fresh ids must be non-zero, fresh and distinct);
  //   - if there is no such mapping, the transformation context must have
  //     overflow ids available.
  bool IsApplicable(
      opt::IRContext* ir_context,
      const TransformationContext& transformation_context) const override;

  // Flattens the selection construct with header |message_.header_block_id|,
  // changing any OpPhi in the block where the flow converges to OpSelect and
  // enclosing any instruction with side effects in conditionals so that
  // they are only executed when they should.
  void Apply(opt::IRContext* ir_context,
             TransformationContext* transformation_context) const override;

  protobufs::Transformation ToMessage() const override;

  // Returns true if the conditional headed by |header| can be flattened,
  // according to the conditions of the IsApplicable method, assuming that
  // enough fresh ids would be provided. In this case, it fills the
  // |instructions_that_need_ids| set with all the instructions that would
  // require fresh ids.
  // Returns false otherwise.
  // Assumes that |header| is the header of a conditional, so its last two
  // instructions are OpSelectionMerge and OpBranchConditional.
  static bool GetProblematicInstructionsIfConditionalCanBeFlattened(
      opt::IRContext* ir_context, opt::BasicBlock* header,
      std::set<opt::Instruction*>* instructions_that_need_ids);

  // Returns true iff the given instruction needs a placeholder to be enclosed
  // inside a conditional. So, it returns:
  // - true if the instruction has a non-void result id,
  // - false if the instruction does not have a result id or has a void result
  //   id.
  // Assumes that the instruction has side effects, requiring it to be enclosed
  // inside a conditional, and that it can be enclosed inside a conditional
  // keeping the module valid. Assumes that, if the instruction has a void
  // result type, its result id is not used in the module.
  static bool InstructionNeedsPlaceholder(opt::IRContext* ir_context,
                                          const opt::Instruction& instruction);

 private:
  // Returns an unordered_map mapping instructions to the info required to
  // enclose them inside a conditional. It maps the instructions to the
  // corresponding entry in |message_.side_effect_wrapper_info|.
  std::unordered_map<opt::Instruction*, protobufs::SideEffectWrapperInfo>
  GetInstructionsToWrapperInfo(opt::IRContext* ir_context) const;

  // Splits the given block, adding a new selection construct so that the given
  // instruction is only executed if the boolean value of |condition_id| matches
  // the value of |exec_if_cond_true|.
  // Assumes that all parameters are consistent.
  // 2 fresh ids are required if the instruction does not have a result id (the
  // first two ids in |wrapper_info| must be valid fresh ids), 5 otherwise.
  // Returns the merge block created.
  //
  // |dead_blocks| and |irrelevant_ids| are used to record the ids of blocks
  // and instructions for which dead block and irrelevant id facts should
  // ultimately be created.
  opt::BasicBlock* EncloseInstructionInConditional(
      opt::IRContext* ir_context,
      const TransformationContext& transformation_context,
      opt::BasicBlock* block, opt::Instruction* instruction,
      const protobufs::SideEffectWrapperInfo& wrapper_info,
      uint32_t condition_id, bool exec_if_cond_true,
      std::vector<uint32_t>* dead_blocks,
      std::vector<uint32_t>* irrelevant_ids) const;

  // Returns true if the given instruction either has no side effects or it can
  // be handled by being enclosed in a conditional.
  static bool InstructionCanBeHandled(opt::IRContext* ir_context,
                                      const opt::Instruction& instruction);

  protobufs::TransformationFlattenConditionalBranch message_;
};

}  // namespace fuzz
}  // namespace spvtools

#endif  // SOURCE_FUZZ_TRANSFORMATION_FLATTEN_CONDITIONAL_BRANCH_H
