// Copyright (c) 2019 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_OUTLINE_FUNCTION_H_
#define SOURCE_FUZZ_TRANSFORMATION_OUTLINE_FUNCTION_H_

#include <map>
#include <set>
#include <vector>

#include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
#include "source/fuzz/transformation.h"
#include "source/fuzz/transformation_context.h"
#include "source/opt/ir_context.h"

namespace spvtools {
namespace fuzz {

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

  TransformationOutlineFunction(
      uint32_t entry_block, uint32_t exit_block,
      uint32_t new_function_struct_return_type_id,
      uint32_t new_function_type_id, uint32_t new_function_id,
      uint32_t new_function_region_entry_block, uint32_t new_caller_result_id,
      uint32_t new_callee_result_id,
      const std::map<uint32_t, uint32_t>& input_id_to_fresh_id,
      const std::map<uint32_t, uint32_t>& output_id_to_fresh_id);

  // - All the fresh ids occurring in the transformation must be distinct and
  //   fresh
  // - |message_.entry_block| and |message_.exit_block| must form a single-entry
  //   single-exit control flow graph region
  // - |message_.entry_block| must not start with OpVariable
  // - |message_.entry_block| must not be a loop header
  // - |message_.exit_block| must not be a merge block or the continue target
  //   of a loop
  // - A structured control flow construct must lie either completely within the
  //   region or completely outside it
  // - |message.entry_block| must not start with OpPhi; this is to keep the
  //   transformation simple - another transformation should be used to split
  //   a desired entry block that starts with OpPhi if needed
  // - |message_.input_id_to_fresh_id| must contain an entry for every id
  //   defined outside the region but used in the region
  // - |message_.output_id_to_fresh_id| must contain an entry for every id
  //   defined in the region but used outside the region
  bool IsApplicable(
      opt::IRContext* ir_context,
      const TransformationContext& transformation_context) const override;

  // - A new function with id |message_.new_function_id| is added to the module.
  // - If the region generates output ids, the return type of this function is
  //   a new struct type with one field per output id, and with type id
  //   |message_.new_function_struct_return_type|, otherwise the function return
  //   types is void and |message_.new_function_struct_return_type| is not used.
  // - If the region generates input ids, the new function has one parameter per
  //   input id.  Fresh ids for these parameters are provided by
  //   |message_.input_id_to_fresh_id|.
  // - Unless the type required for the new function is already known,
  //   |message_.new_function_type_id| is used as the type id for a new function
  //   type, and the new function uses this type.
  // - The new function starts with a placeholder block with id
  //   |message_.new_function_first_block|, which jumps straight to a successor
  //   block, to avoid violating rules on what the first block in a function may
  //   look like.
  // - The outlined region is replaced with a single block, with the same id
  //   as |message_.entry_block|, and which calls the new function, passing the
  //   region's input ids as parameters.  The result is  stored in
  //   |message_.new_caller_result_id|, which has type
  //   |message_.new_function_struct_return_type| (unless there are
  //   no output ids, in which case the return type is void).  The components
  //   of this returned struct are then copied out into the region's output ids.
  //   The block ends with the merge instruction (if any) and terminator of
  //   |message_.exit_block|.
  // - The body of the new function is identical to the outlined region, except
  //   that (a) the region's entry block has id
  //   |message_.new_function_region_entry_block|, (b) input id uses are
  //   replaced with parameter accesses, (c) and definitions of output ids are
  //   replaced with definitions of corresponding fresh ids provided by
  //   |message_.output_id_to_fresh_id|, and (d) the block of the function
  //   ends by returning a composite of type
  //   |message_.new_function_struct_return_type| comprised of all the fresh
  //   output ids (unless the return type is void, in which case no value is
  //   returned.
  void Apply(opt::IRContext* ir_context,
             TransformationContext* transformation_context) const override;

  std::unordered_set<uint32_t> GetFreshIds() const override;

  protobufs::Transformation ToMessage() const override;

  // Returns the set of blocks dominated by |entry_block| and post-dominated
  // by |exit_block|.
  static std::set<opt::BasicBlock*> GetRegionBlocks(
      opt::IRContext* ir_context, opt::BasicBlock* entry_block,
      opt::BasicBlock* exit_block);

  // Yields ids that are used in |region_set| and that are either parameters
  // to the function containing |region_set|, or are defined by blocks of this
  // function that are outside |region_set|.
  //
  // Special cases: OpPhi instructions in |region_entry_block| and the
  // terminator of |region_exit_block| do not get outlined, therefore
  // - id uses in OpPhi instructions in |region_entry_block| are ignored
  // - id uses in the terminator instruction of |region_exit_block| are ignored
  static std::vector<uint32_t> GetRegionInputIds(
      opt::IRContext* ir_context, const std::set<opt::BasicBlock*>& region_set,
      opt::BasicBlock* region_exit_block);

  // Yields all ids that are defined in |region_set| and used outside
  // |region_set|.
  //
  // Special cases: for similar reasons as for |GetRegionInputIds|,
  // - ids defined in the region and used in the terminator of
  //   |region_exit_block| count as output ids
  static std::vector<uint32_t> GetRegionOutputIds(
      opt::IRContext* ir_context, const std::set<opt::BasicBlock*>& region_set,
      opt::BasicBlock* region_exit_block);

 private:
  // Ensures that the module's id bound is at least the maximum of any fresh id
  // associated with the transformation.
  void UpdateModuleIdBoundForFreshIds(
      opt::IRContext* ir_context,
      const std::map<uint32_t, uint32_t>& input_id_to_fresh_id_map,
      const std::map<uint32_t, uint32_t>& output_id_to_fresh_id_map) const;

  // Uses |input_id_to_fresh_id_map| and |output_id_to_fresh_id_map| to convert,
  // in the region to be outlined, all the input ids in |region_input_ids| and
  // the output ids in |region_output_ids| to their fresh counterparts.
  // Parameters |region_blocks| provides access to the blocks that must be
  // modified, and |original_region_exit_block| allows for some special cases
  // where ids should not be remapped.
  void RemapInputAndOutputIdsInRegion(
      opt::IRContext* ir_context,
      const opt::BasicBlock& original_region_exit_block,
      const std::set<opt::BasicBlock*>& region_blocks,
      const std::vector<uint32_t>& region_input_ids,
      const std::vector<uint32_t>& region_output_ids,
      const std::map<uint32_t, uint32_t>& input_id_to_fresh_id_map,
      const std::map<uint32_t, uint32_t>& output_id_to_fresh_id_map) const;

  // Produce a Function object that has the right function type and parameter
  // declarations.  The function argument types and parameter ids are dictated
  // by |region_input_ids| and |input_id_to_fresh_id_map|.  The function return
  // type is dictated by |region_output_ids|.
  //
  // A new struct type to represent the function return type, and a new function
  // type for the function, will be added to the module (unless suitable types
  // are already present).
  //
  // Facts about the function containing the outlined region that are relevant
  // to the new function are propagated via the vact manager in
  // |transformation_context|.
  std::unique_ptr<opt::Function> PrepareFunctionPrototype(
      const std::vector<uint32_t>& region_input_ids,
      const std::vector<uint32_t>& region_output_ids,
      const std::map<uint32_t, uint32_t>& input_id_to_fresh_id_map,
      opt::IRContext* ir_context,
      TransformationContext* transformation_context) const;

  // Creates the body of the outlined function by cloning blocks from the
  // original region, given by |region_blocks|, adapting the cloned version
  // of |original_region_exit_block| so that it returns something appropriate,
  // and patching up branches to |original_region_entry_block| to refer to its
  // clone.  Parameters |region_output_ids| and |output_id_to_fresh_id_map| are
  // used to determine what the function should return.
  //
  // The |transformation_context| argument allow facts about blocks being
  // outlined, e.g. whether they are dead blocks, to be asserted about blocks
  // that get created during outlining.
  void PopulateOutlinedFunction(
      const opt::BasicBlock& original_region_entry_block,
      const opt::BasicBlock& original_region_exit_block,
      const std::set<opt::BasicBlock*>& region_blocks,
      const std::vector<uint32_t>& region_output_ids,
      const std::map<uint32_t, uint32_t>& output_id_to_fresh_id_map,
      opt::IRContext* ir_context, opt::Function* outlined_function) const;

  // Shrinks the outlined region, given by |region_blocks|, down to the single
  // block |original_region_entry_block|.  This block is itself shrunk to just
  // contain:
  // - any OpPhi instructions that were originally present
  // - a call to the outlined function, with parameters provided by
  //   |region_input_ids|
  // - instructions to route components of the call's return value into
  //   |region_output_ids|
  // - The merge instruction (if any) and terminator of the original region's
  //   exit block, given by |cloned_exit_block_merge| and
  //   |cloned_exit_block_terminator|
  // Parameters |output_id_to_type_id| and |return_type_id| provide the
  // provide types for the region's output ids, and the return type of the
  // outlined function: as the module is in an inconsistent state when this
  // function is called, this information cannot be gotten from the def-use
  // manager.
  void ShrinkOriginalRegion(
      opt::IRContext* ir_context,
      const std::set<opt::BasicBlock*>& region_blocks,
      const std::vector<uint32_t>& region_input_ids,
      const std::vector<uint32_t>& region_output_ids,
      const std::map<uint32_t, uint32_t>& output_id_to_type_id,
      uint32_t return_type_id,
      std::unique_ptr<opt::Instruction> cloned_exit_block_merge,
      std::unique_ptr<opt::Instruction> cloned_exit_block_terminator,
      opt::BasicBlock* original_region_entry_block) const;

  protobufs::TransformationOutlineFunction message_;
};

}  // namespace fuzz
}  // namespace spvtools

#endif  // SOURCE_FUZZ_TRANSFORMATION_OUTLINE_FUNCTION_H_
