// Copyright 2020 The Tint Authors.
//
// 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 SRC_READER_SPIRV_FUNCTION_H_
#define SRC_READER_SPIRV_FUNCTION_H_

#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "src/program_builder.h"
#include "src/reader/spirv/construct.h"
#include "src/reader/spirv/parser_impl.h"

namespace tint {
namespace reader {
namespace spirv {

/// Kinds of CFG edges.
//
// The edge kinds are used in many ways.
//
// For example, consider the edges leaving a basic block and going to distinct
// targets. If the total number of kForward + kIfBreak + kCaseFallThrough edges
// is more than 1, then the block must be a structured header, i.e. it needs
// a merge instruction to declare the control flow divergence and associated
// reconvergence point.  Those those edge kinds count toward divergence
// because SPIR-v is designed to easily map back to structured control flow
// in GLSL (and C).  In GLSL and C, those forward-flow edges don't have a
// special statement to express them.  The other forward edges: kSwitchBreak,
// kLoopBreak, and kLoopContinue directly map to 'break', 'break', and
// 'continue', respectively.
enum class EdgeKind {
  // A back-edge: An edge from a node to one of its ancestors in a depth-first
  // search from the entry block.
  kBack,
  // An edge from a node to the merge block of the nearest enclosing switch,
  // where there is no intervening loop.
  kSwitchBreak,
  // An edge from a node to the merge block of the nearest enclosing loop, where
  // there is no intervening switch.
  // The source block is a "break block" as defined by SPIR-V.
  kLoopBreak,
  // An edge from a node in a loop body to the associated continue target, where
  // there are no other intervening loops or switches.
  // The source block is a "continue block" as defined by SPIR-V.
  kLoopContinue,
  // An edge from a node to the merge block of the nearest enclosing structured
  // construct, but which is neither a kSwitchBreak or a kLoopBreak.
  // This can only occur for an "if" selection, i.e. where the selection
  // header ends in OpBranchConditional.
  kIfBreak,
  // An edge from one switch case to the next sibling switch case.
  kCaseFallThrough,
  // None of the above.
  kForward
};

/// Bookkeeping info for a basic block.
struct BlockInfo {
  /// Constructor
  /// @param bb internal representation of the basic block
  explicit BlockInfo(const spvtools::opt::BasicBlock& bb);
  ~BlockInfo();

  /// The internal representation of the basic block.
  const spvtools::opt::BasicBlock* basic_block;

  /// The ID of the OpLabel instruction that starts this block.
  uint32_t id = 0;

  /// The position of this block in the reverse structured post-order.
  uint32_t pos = 0;

  /// If this block is a header, then this is the ID of the merge block.
  uint32_t merge_for_header = 0;
  /// If this block is a loop header, then this is the ID of the continue
  /// target.
  uint32_t continue_for_header = 0;
  /// If this block is a merge, then this is the ID of the header.
  uint32_t header_for_merge = 0;
  /// If this block is a continue target, then this is the ID of the loop
  /// header.
  uint32_t header_for_continue = 0;
  /// Is this block a continue target which is its own loop header block?
  /// In this case the continue construct is the entire loop.  The associated
  /// "loop construct" is empty, and not represented.
  bool is_continue_entire_loop = false;

  /// The immediately enclosing structured construct. If this block is not
  /// in the block order at all, then this is still nullptr.
  const Construct* construct = nullptr;

  /// Maps the ID of a successor block (in the CFG) to its edge classification.
  std::unordered_map<uint32_t, EdgeKind> succ_edge;

  /// The following fields record relationships among blocks in a selection
  /// construct for an OpSwitch instruction.

  /// If not null, then the pointed-at construct is a selection for an OpSwitch,
  /// and this block is a case target for it.  We say this block "heads" the
  /// case construct.
  const Construct* case_head_for = nullptr;
  /// If not null, then the pointed-at construct is a selection for an OpSwitch,
  /// and this block is the default target for it.  We say this block "heads"
  /// the default case construct.
  const Construct* default_head_for = nullptr;
  /// Is this a default target for a switch, and is it also the merge for its
  /// switch?
  bool default_is_merge = false;
  /// The list of switch values that cause a branch to this block.
  std::unique_ptr<std::vector<uint64_t>> case_values;

  /// The following fields record relationships among blocks in a selection
  /// construct for an OpBranchConditional instruction.

  /// When this block is an if-selection header, this is the edge kind
  /// for the true branch.
  EdgeKind true_kind = EdgeKind::kForward;
  /// When this block is an if-selection header, this is the edge kind
  /// for the false branch.
  EdgeKind false_kind = EdgeKind::kForward;
  /// If not 0, then this block is an if-selection header, and `true_head` is
  /// the target id of the true branch on the OpBranchConditional, and that
  /// target is inside the if-selection.
  uint32_t true_head = 0;
  /// If not 0, then this block is an if-selection header, and `false_head`
  /// is the target id of the false branch on the OpBranchConditional, and
  /// that target is inside the if-selection.
  uint32_t false_head = 0;
  /// If not 0, then this block is an if-selection header, and when following
  /// the flow via the true and false branches, control first reconverges at
  /// the block with ID `premerge_head`, and `premerge_head` is still inside
  /// the if-selection.
  uint32_t premerge_head = 0;
  /// If non-empty, then this block is an if-selection header, and control flow
  /// in the body must be guarded by a boolean flow variable with this name.
  /// This occurs when a block in this selection has both an if-break edge, and
  /// also a different normal forward edge but without a merge instruction.
  std::string flow_guard_name = "";

  /// The result IDs that this block is responsible for declaring as a
  /// hoisted variable.
  /// @see DefInfo#requires_hoisted_def
  std::vector<uint32_t> hoisted_ids;

  /// A PhiAssignment represents the assignment of a value to the state
  /// variable associated with an OpPhi in a successor block.
  struct PhiAssignment {
    /// The ID of an OpPhi receiving a value from this basic block.
    uint32_t phi_id;
    /// The the value carried to the given OpPhi.
    uint32_t value;
  };
  /// If this basic block branches to a visited basic block containing phis,
  /// then this is the list of writes to the variables associated those phis.
  std::vector<PhiAssignment> phi_assignments;
  /// The IDs of OpPhi instructions which require their associated state
  /// variable to be declared in this basic block.
  std::vector<uint32_t> phis_needing_state_vars;
};

inline std::ostream& operator<<(std::ostream& o, const BlockInfo& bi) {
  o << "BlockInfo{"
    << " id: " << bi.id << " pos: " << bi.pos
    << " merge_for_header: " << bi.merge_for_header
    << " continue_for_header: " << bi.continue_for_header
    << " header_for_merge: " << bi.header_for_merge
    << " is_continue_entire_loop: " << int(bi.is_continue_entire_loop) << "}";
  return o;
}

/// Reasons for avoiding generating an intermediate value.
enum class SkipReason {
  /// `kDontSkip`: The value should be generated. Used for most values.
  kDontSkip,

  /// For remaining cases, the value is not generated.

  /// `kOpaqueObject`: used for any intermediate value which is an sampler,
  /// image,
  /// or sampled image, or any pointer to such object. Code is generated
  /// for those objects only when emitting the image instructions that access
  /// the image (read, write, sample, gather, fetch, or query). For example,
  /// when encountering an OpImageSampleExplicitLod, a call to the
  /// textureSampleLevel builtin function will be emitted, and the call will
  /// directly reference the underlying texture and sampler (variable or
  /// function parameter).
  kOpaqueObject,

  /// `kPointSizeBuiltinPointer`: the value is a pointer to the Position builtin
  /// variable.  Don't generate its address.  Avoid generating stores to this
  /// pointer.
  kPointSizeBuiltinPointer,
  /// `kPointSizeBuiltinValue`: the value is the value loaded from the
  /// PointSize builtin. Use 1.0f instead, because that's the only value
  /// supported by WebGPU.
  kPointSizeBuiltinValue,

  /// `kSampleIdBuiltinPointer`: the value is a pointer to the SampleId builtin
  /// variable.  Don't generate its address.
  kSampleIdBuiltinPointer,

  /// `kVertexIndexBuiltinPointer`: the value is a pointer to the VertexIndex
  /// builtin variable.  Don't generate its address.
  kVertexIndexBuiltinPointer,

  /// `kInstanceIndexBuiltinPointer`: the value is a pointer to the
  /// InstanceIndex
  /// builtin variable.  Don't generate its address.
  kInstanceIndexBuiltinPointer,

  /// `kSampleMaskInBuiltinPointer`: the value is a pointer to the SampleMaskIn
  /// builtin input variable.  Don't generate its address.
  kSampleMaskInBuiltinPointer,

  /// `kSampleMaskOutBuiltinPointer`: the value is a pointer to the SampleMask
  /// builtin output variable.
  kSampleMaskOutBuiltinPointer,
};

/// Bookkeeping info for a SPIR-V ID defined in the function, or some
/// module-scope variables. This will be valid for result IDs that are:
/// - defined in the function and:
///    - instructions that are not OpLabel, and not OpFunctionParameter
///    - are defined in a basic block visited in the block-order for the
///    function.
/// - certain module-scope builtin variables.
struct DefInfo {
  /// Constructor.
  /// @param def_inst the SPIR-V instruction defining the ID
  /// @param block_pos the position of the basic block where the ID is defined.
  /// @param index an ordering index for this local definition
  DefInfo(const spvtools::opt::Instruction& def_inst,
          uint32_t block_pos,
          size_t index);
  /// Destructor.
  ~DefInfo();

  /// The SPIR-V instruction that defines the ID.
  const spvtools::opt::Instruction& inst;
  /// The position of the first block in which this ID is visible, in function
  /// block order.  For IDs defined outside of the function, it is 0.
  /// For IDs defined in the function, it is the position of the block
  /// containing the definition of the ID.
  /// See method `FunctionEmitter::ComputeBlockOrderAndPositions`
  const uint32_t block_pos = 0;

  /// An index for uniquely and deterministically ordering all DefInfo records
  /// in a function.
  const size_t index = 0;

  /// The number of uses of this ID.
  uint32_t num_uses = 0;

  /// The block position of the last use of this ID, or 0 if it is not used
  /// at all.  The "last" ordering is determined by the function block order.
  uint32_t last_use_pos = 0;

  /// Is this value used in a construct other than the one in which it was
  /// defined?
  bool used_in_another_construct = false;

  /// True if this ID requires a WGSL 'const' definition, due to context. It
  /// might get one anyway (so this is *not* an if-and-only-if condition).
  bool requires_named_const_def = false;

  /// True if this ID must map to a WGSL variable declaration before the
  /// corresponding position of the ID definition in SPIR-V.  This compensates
  /// for the difference between dominance and scoping. An SSA definition can
  /// dominate all its uses, but the construct where it is defined does not
  /// enclose all the uses, and so if it were declared as a WGSL constant
  /// definition at the point of its SPIR-V definition, then the WGSL name
  /// would go out of scope too early. Fix that by creating a variable at the
  /// top of the smallest construct that encloses both the definition and all
  /// its uses. Then the original SPIR-V definition maps to a WGSL assignment
  /// to that variable, and each SPIR-V use becomes a WGSL read from the
  /// variable.
  /// TODO(dneto): This works for constants of storable type, but not, for
  /// example, pointers.
  bool requires_hoisted_def = false;

  /// If the definition is an OpPhi, then `phi_var` is the name of the
  /// variable that stores the value carried from parent basic blocks into
  /// the basic block containing the OpPhi. Otherwise this is the empty string.
  std::string phi_var;

  /// The storage class to use for this value, if it is of pointer type.
  /// This is required to carry a storage class override from a storage
  /// buffer expressed in the old style (with Uniform storage class)
  /// that needs to be remapped to StorageBuffer storage class.
  /// This is kNone for non-pointers.
  ast::StorageClass storage_class = ast::StorageClass::kNone;

  /// The reason, if any, that this value should be ignored.
  /// Normally no values are ignored.  This field can be updated while
  /// generating code because sometimes we only discover necessary facts
  /// in the middle of generating code.
  SkipReason skip = SkipReason::kDontSkip;
};

inline std::ostream& operator<<(std::ostream& o, const DefInfo& di) {
  o << "DefInfo{"
    << " inst.result_id: " << di.inst.result_id()
    << " block_pos: " << di.block_pos << " num_uses: " << di.num_uses
    << " last_use_pos: " << di.last_use_pos << " requires_named_const_def: "
    << (di.requires_named_const_def ? "true" : "false")
    << " requires_hoisted_def: " << (di.requires_hoisted_def ? "true" : "false")
    << " phi_var: '" << di.phi_var << "'";
  if (di.storage_class != ast::StorageClass::kNone) {
    o << " sc:" << int(di.storage_class);
  }
  switch (di.skip) {
    case SkipReason::kDontSkip:
      break;
    case SkipReason::kOpaqueObject:
      o << " skip:opaque";
      break;
    case SkipReason::kPointSizeBuiltinPointer:
      o << " skip:pointsize_pointer";
      break;
    case SkipReason::kPointSizeBuiltinValue:
      o << " skip:pointsize_value";
      break;
    case SkipReason::kSampleIdBuiltinPointer:
      o << " skip:sampleid_pointer";
      break;
    case SkipReason::kVertexIndexBuiltinPointer:
      o << " skip:vertexindex_pointer";
      break;
    case SkipReason::kInstanceIndexBuiltinPointer:
      o << " skip:instanceindex_pointer";
      break;
    case SkipReason::kSampleMaskInBuiltinPointer:
      o << " skip:samplemaskin_pointer";
      break;
    case SkipReason::kSampleMaskOutBuiltinPointer:
      o << " skip:samplemaskout_pointer";
      break;
  }
  o << "}";
  return o;
}

/// A placeholder Statement that exists for the duration of building a
/// StatementBlock. Once the StatementBlock is built, Build() will be called to
/// construct the final AST node, which will be used in the place of this
/// StatementBuilder.
/// StatementBuilders are used to simplify construction of AST nodes that will
/// become immutable. The builders may hold mutable state while the
/// StatementBlock is being constructed, which becomes an immutable node on
/// StatementBlock::Finalize().
class StatementBuilder : public Castable<StatementBuilder, ast::Statement> {
 public:
  /// Constructor
  StatementBuilder() : Base(ProgramID(), Source{}) {}

  /// @param builder the program builder
  /// @returns the build AST node
  virtual ast::Statement* Build(ProgramBuilder* builder) const = 0;

 private:
  Node* Clone(CloneContext*) const override;
  void to_str(const semantic::Info& sem,
              std::ostream& out,
              size_t indent) const override;
};

/// A FunctionEmitter emits a SPIR-V function onto a Tint AST module.
class FunctionEmitter {
 public:
  /// Creates a FunctionEmitter, and prepares to write to the AST module
  /// in `pi`
  /// @param pi a ParserImpl which has already executed BuildInternalModule
  /// @param function the function to emit
  FunctionEmitter(ParserImpl* pi, const spvtools::opt::Function& function);
  /// Creates a FunctionEmitter, and prepares to write to the AST module
  /// in `pi`
  /// @param pi a ParserImpl which has already executed BuildInternalModule
  /// @param function the function to emit
  /// @param ep_info entry point information for this function, or nullptr
  FunctionEmitter(ParserImpl* pi,
                  const spvtools::opt::Function& function,
                  const EntryPointInfo* ep_info);
  /// Destructor
  ~FunctionEmitter();

  /// Emits the function to AST module.
  /// @return whether emission succeeded
  bool Emit();

  /// @returns true if emission has not yet failed.
  bool success() const { return fail_stream_.status(); }
  /// @returns true if emission has failed.
  bool failed() const { return !success(); }

  /// Finalizes any StatementBuilders returns the body of the function.
  /// Must only be called once, and to be used only for testing.
  /// @returns the body of the function.
  const ast::StatementList ast_body();

  /// Records failure.
  /// @returns a FailStream on which to emit diagnostics.
  FailStream& Fail() { return fail_stream_.Fail(); }

  /// @returns the parser implementation
  ParserImpl* parser() { return &parser_impl_; }

  /// Emits the function body, populating the bottom entry of the statements
  /// stack.
  /// @returns false if emission failed.
  bool EmitBody();

  /// Records a mapping from block ID to a BlockInfo struct.
  /// Populates `block_info_`
  void RegisterBasicBlocks();

  /// Verifies that terminators only branch to labels in the current function.
  /// Assumes basic blocks have been registered.
  /// @returns true if terminators are valid
  bool TerminatorsAreValid();

  /// Populates merge-header cross-links and BlockInfo#is_continue_entire_loop.
  /// Also verifies that merge instructions go to blocks in the same function.
  /// Assumes basic blocks have been registered, and terminators are valid.
  /// @returns false if registration fails
  bool RegisterMerges();

  /// Determines the output order for the basic blocks in the function.
  /// Populates `block_order_` and BlockInfo#pos.
  /// Assumes basic blocks have been registered.
  void ComputeBlockOrderAndPositions();

  /// @returns the reverse structured post order of the basic blocks in
  /// the function.
  const std::vector<uint32_t>& block_order() const { return block_order_; }

  /// Verifies that the orderings among a structured header, continue target,
  /// and merge block are valid. Assumes block order has been computed, and
  /// merges are valid and recorded.
  /// @returns false if invalid nesting was detected
  bool VerifyHeaderContinueMergeOrder();

  /// Labels each basic block with its nearest enclosing structured construct.
  /// Populates BlockInfo#construct and the `constructs_` list.
  /// Assumes terminators are valid and merges have been registered, block
  /// order has been computed, and each block is labeled with its position.
  /// Checks nesting of structured control flow constructs.
  /// @returns false if bad nesting has been detected
  bool LabelControlFlowConstructs();

  /// @returns the structured constructs
  const ConstructList& constructs() const { return constructs_; }

  /// Marks blocks targets of a switch, either as the head of a case or
  /// as the default target.
  /// @returns false on failure
  bool FindSwitchCaseHeaders();

  /// Classifies the successor CFG edges for the ordered basic blocks.
  /// Also checks validity of each edge (populates BlockInfo#succ_edge).
  /// Implicitly checks dominance rules for headers and continue constructs.
  /// Assumes each block has been labeled with its control flow construct.
  /// @returns false on failure
  bool ClassifyCFGEdges();

  /// Marks the blocks within a selection construct that are the first blocks
  /// in the "then" clause, the "else" clause, and the "premerge" clause.
  /// The head of the premerge clause is the block, if it exists, at which
  /// control flow reconverges from the "then" and "else" clauses, but before
  /// before the merge block for that selection.   The existence of a premerge
  /// should be an exceptional case, but is allowed by the structured control
  /// flow rules.
  /// @returns false if bad nesting has been detected.
  bool FindIfSelectionInternalHeaders();

  /// Creates a DefInfo record for each module-scope builtin variable
  /// that should be handled specially.  Either it's ignored, or its store
  /// type is converted on load.
  /// Populates the `def_info_` mapping for such IDs.
  /// @returns false on failure
  bool RegisterSpecialBuiltInVariables();

  /// Creates a DefInfo record for each locally defined SPIR-V ID.
  /// Populates the `def_info_` mapping with basic results for such IDs.
  /// @returns false on failure
  bool RegisterLocallyDefinedValues();

  /// Returns the Tint storage class for the given SPIR-V ID that is a
  /// pointer value.
  /// @param id a SPIR-V ID for a pointer value
  /// @returns the storage class
  ast::StorageClass GetStorageClassForPointerValue(uint32_t id);

  /// Remaps the storage class for the type of a locally-defined value,
  /// if necessary. If it's not a pointer type, or if its storage class
  /// already matches, then the result is a copy of the `type` argument.
  /// @param type the AST type
  /// @param result_id the SPIR-V ID for the locally defined value
  /// @returns an possibly updated type
  type::Type* RemapStorageClass(type::Type* type, uint32_t result_id);

  /// Marks locally defined values when they should get a 'const'
  /// definition in WGSL, or a 'var' definition at an outer scope.
  /// This occurs in several cases:
  ///  - When a SPIR-V instruction might use the dynamically computed value
  ///    only once, but the WGSL code might reference it multiple times.
  ///    For example, this occurs for the vector operands of OpVectorShuffle.
  ///    In this case the definition's DefInfo#requires_named_const_def property
  ///    is set to true.
  ///  - When a definition and at least one of its uses are not in the
  ///    same structured construct.
  ///    In this case the definition's DefInfo#requires_named_const_def property
  ///    is set to true.
  ///  - When a definition is in a construct that does not enclose all the
  ///    uses.  In this case the definition's DefInfo#requires_hoisted_def
  ///    property is set to true.
  /// Updates the `def_info_` mapping.
  void FindValuesNeedingNamedOrHoistedDefinition();

  /// Emits declarations of function variables.
  /// @returns false if emission failed.
  bool EmitFunctionVariables();

  /// Emits statements in the body.
  /// @returns false if emission failed.
  bool EmitFunctionBodyStatements();

  /// Emits a basic block.
  /// @param block_info the block to emit
  /// @returns false if emission failed.
  bool EmitBasicBlock(const BlockInfo& block_info);

  /// Emits an IfStatement, including its condition expression, and sets
  /// up the statement stack to accumulate subsequent basic blocks into
  /// the "then" and "else" clauses.
  /// @param block_info the if-selection header block
  /// @returns false if emission failed.
  bool EmitIfStart(const BlockInfo& block_info);

  /// Emits a SwitchStatement, including its condition expression, and sets
  /// up the statement stack to accumulate subsequent basic blocks into
  /// the default clause and case clauses.
  /// @param block_info the switch-selection header block
  /// @returns false if emission failed.
  bool EmitSwitchStart(const BlockInfo& block_info);

  /// Emits a LoopStatement, and pushes a new StatementBlock to accumulate
  /// the remaining instructions in the current block and subsequent blocks
  /// in the loop.
  /// @param construct the loop construct
  /// @returns false if emission failed.
  bool EmitLoopStart(const Construct* construct);

  /// Emits a ContinuingStatement, and pushes a new StatementBlock to accumulate
  /// the remaining instructions in the current block and subsequent blocks
  /// in the continue construct.
  /// @param construct the continue construct
  /// @returns false if emission failed.
  bool EmitContinuingStart(const Construct* construct);

  /// Emits the non-control-flow parts of a basic block, but only once.
  /// The `already_emitted` parameter indicates whether the code has already
  /// been emitted, and is used to signal that this invocation actually emitted
  /// it.
  /// @param block_info the block to emit
  /// @param already_emitted the block to emit
  /// @returns false if the code had not yet been emitted, but emission failed
  bool EmitStatementsInBasicBlock(const BlockInfo& block_info,
                                  bool* already_emitted);

  /// Emits code for terminators, but that aren't part of entering or
  /// resolving structured control flow. That is, if the basic block
  /// terminator calls for it, emit the fallthrough, break, continue, return,
  /// or kill commands.
  /// @param block_info the block with the terminator to emit (if any)
  /// @returns false if emission failed
  bool EmitNormalTerminator(const BlockInfo& block_info);

  /// Returns a new statement to represent the given branch representing a
  /// "normal" terminator, as in the sense of EmitNormalTerminator.  If no
  /// WGSL statement is required, the statement will be nullptr. This method
  /// tries to avoid emitting a 'break' statement when that would be redundant
  /// in WGSL due to implicit breaking out of a switch.
  /// @param src_info the source block
  /// @param dest_info the destination block
  /// @returns the new statement, or a null statement
  ast::Statement* MakeBranch(const BlockInfo& src_info,
                             const BlockInfo& dest_info) const {
    return MakeBranchDetailed(src_info, dest_info, false, nullptr);
  }

  /// Returns a new statement to represent the given branch representing a
  /// "normal" terminator, as in the sense of EmitNormalTerminator.  If no
  /// WGSL statement is required, the statement will be nullptr.
  /// @param src_info the source block
  /// @param dest_info the destination block
  /// @returns the new statement, or a null statement
  ast::Statement* MakeForcedBranch(const BlockInfo& src_info,
                                   const BlockInfo& dest_info) const {
    return MakeBranchDetailed(src_info, dest_info, true, nullptr);
  }

  /// Returns a new statement to represent the given branch representing a
  /// "normal" terminator, as in the sense of EmitNormalTerminator.  If no
  /// WGSL statement is required, the statement will be nullptr. When `forced`
  /// is false, this method tries to avoid emitting a 'break' statement when
  /// that would be redundant in WGSL due to implicit breaking out of a switch.
  /// When `forced` is true, the method won't try to avoid emitting that break.
  /// If the control flow edge is an if-break for an if-selection with a
  /// control flow guard, then return that guard name via `flow_guard_name_ptr`
  /// when that parameter is not null.
  /// @param src_info the source block
  /// @param dest_info the destination block
  /// @param forced if true, always emit the branch (if it exists in WGSL)
  /// @param flow_guard_name_ptr return parameter for control flow guard name
  /// @returns the new statement, or a null statement
  ast::Statement* MakeBranchDetailed(const BlockInfo& src_info,
                                     const BlockInfo& dest_info,
                                     bool forced,
                                     std::string* flow_guard_name_ptr) const;

  /// Returns a new if statement with the given statements as the then-clause
  /// and the else-clause.  Either or both clauses might be nullptr. If both
  /// are nullptr, then don't make a new statement and instead return nullptr.
  /// @param condition the branching condition
  /// @param then_stmt the statement for the then clause of the if, or nullptr
  /// @param else_stmt the statement for the else clause of the if, or nullptr
  /// @returns the new statement, or nullptr
  ast::Statement* MakeSimpleIf(ast::Expression* condition,
                               ast::Statement* then_stmt,
                               ast::Statement* else_stmt) const;

  /// Emits the statements for an normal-terminator OpBranchConditional
  /// where one branch is a case fall through (the true branch if and only
  /// if `fall_through_is_true_branch` is true), and the other branch is
  /// goes to a different destination, named by `other_dest`.
  /// @param src_info the basic block from which we're branching
  /// @param cond the branching condition
  /// @param other_edge_kind the edge kind from the source block to the other
  /// destination
  /// @param other_dest the other branching destination
  /// @param fall_through_is_true_branch true when the fall-through is the true
  /// branch
  /// @returns the false if emission fails
  bool EmitConditionalCaseFallThrough(const BlockInfo& src_info,
                                      ast::Expression* cond,
                                      EdgeKind other_edge_kind,
                                      const BlockInfo& other_dest,
                                      bool fall_through_is_true_branch);

  /// Emits a normal instruction: not a terminator, label, or variable
  /// declaration.
  /// @param inst the instruction
  /// @returns false if emission failed.
  bool EmitStatement(const spvtools::opt::Instruction& inst);

  /// Emits a const definition for the typed value in `ast_expr`, and
  /// records it as the translation for the result ID from `inst`.
  /// @param inst the SPIR-V instruction defining the value
  /// @param ast_expr the already-computed AST expression for the value
  /// @returns false if emission failed.
  bool EmitConstDefinition(const spvtools::opt::Instruction& inst,
                           TypedExpression ast_expr);

  /// Emits a write of the typed value in `ast_expr` to a hoisted variable
  /// for the given SPIR-V ID, if that ID has a hoisted declaration. Otherwise,
  /// emits a const definition instead.
  /// @param inst the SPIR-V instruction defining the value
  /// @param ast_expr the already-computed AST expression for the value
  /// @returns false if emission failed.
  bool EmitConstDefOrWriteToHoistedVar(const spvtools::opt::Instruction& inst,
                                       TypedExpression ast_expr);

  /// Makes an expression
  /// @param id the SPIR-V ID of the value
  /// @returns true if emission has not yet failed.
  TypedExpression MakeExpression(uint32_t id);

  /// Creates an expression and supporting statements for a combinatorial
  /// instruction, or returns null.  A SPIR-V instruction is combinatorial
  /// if it has no side effects and its result depends only on its operands,
  /// and not on accessing external state like memory or the state of other
  /// invocations.  Statements are only created if required to provide values
  /// to the expression. Supporting statements are not required to be
  /// combinatorial.
  /// @param inst a SPIR-V instruction representing an exrpression
  /// @returns an AST expression for the instruction, or nullptr.
  TypedExpression MaybeEmitCombinatorialValue(
      const spvtools::opt::Instruction& inst);

  /// Creates an expression and supporting statements for the a GLSL.std.450
  /// extended instruction.
  /// @param inst a SPIR-V OpExtInst instruction from GLSL.std.450
  /// @returns an AST expression for the instruction, or nullptr.
  TypedExpression EmitGlslStd450ExtInst(const spvtools::opt::Instruction& inst);

  /// Creates an expression for OpCompositeExtract
  /// @param inst an OpCompositeExtract instruction.
  /// @returns an AST expression for the instruction, or nullptr.
  TypedExpression MakeCompositeExtract(const spvtools::opt::Instruction& inst);

  /// Creates an expression for indexing into a composite value.  The literal
  /// indices that step into the value start at instruction input operand
  /// `start_index` and run to the end of the instruction.
  /// @param inst the original instruction
  /// @param composite the typed expression for the composite
  /// @param composite_type_id the SPIR-V type ID for the composite
  /// @param index_start the index of the first operand in `inst` that is an
  /// index into the composite type
  /// @returns an AST expression for the decomposed composite, or {} on error
  TypedExpression MakeCompositeValueDecomposition(
      const spvtools::opt::Instruction& inst,
      TypedExpression composite,
      uint32_t composite_type_id,
      int index_start);

  /// Creates an expression for OpVectorShuffle
  /// @param inst an OpVectorShuffle instruction.
  /// @returns an AST expression for the instruction, or nullptr.
  TypedExpression MakeVectorShuffle(const spvtools::opt::Instruction& inst);

  /// Creates an expression for a numeric conversion.
  /// @param inst a numeric conversion instruction
  /// @returns an AST expression for the instruction, or nullptr.
  TypedExpression MakeNumericConversion(const spvtools::opt::Instruction& inst);

  /// Gets the block info for a block ID, if any exists
  /// @param id the SPIR-V ID of the OpLabel instruction starting the block
  /// @returns the block info for the given ID, if it exists, or nullptr
  BlockInfo* GetBlockInfo(uint32_t id) const {
    auto where = block_info_.find(id);
    if (where == block_info_.end()) {
      return nullptr;
    }
    return where->second.get();
  }

  /// Gets the local definition info for a result ID.
  /// @param id the SPIR-V ID of local definition.
  /// @returns the definition info for the given ID, if it exists, or nullptr
  DefInfo* GetDefInfo(uint32_t id) const {
    auto where = def_info_.find(id);
    if (where == def_info_.end()) {
      return nullptr;
    }
    return where->second.get();
  }
  /// Returns the skip reason for a result ID.
  /// @param id SPIR-V result ID
  /// @returns the skip reason for the given ID, or SkipReason::kDontSkip
  SkipReason GetSkipReason(uint32_t id) const {
    if (auto* def_info = GetDefInfo(id)) {
      return def_info->skip;
    }
    return SkipReason::kDontSkip;
  }

  /// Returns the WGSL variable name for an input builtin variable whose
  /// translation is managed via the SkipReason mechanism.
  /// @param skip_reason the skip reason for the special variable
  /// @returns the variable name for a special builtin variable
  /// that is handled via the "skip" mechanism.
  std::string NameForSpecialInputBuiltin(SkipReason skip_reason);

  /// Returns the most deeply nested structured construct which encloses the
  /// WGSL scopes of names declared in both block positions. Each position must
  /// be a valid index into the function block order array.
  /// @param first_pos the first block position
  /// @param last_pos the last block position
  /// @returns the smallest construct containing both positions
  const Construct* GetEnclosingScope(uint32_t first_pos,
                                     uint32_t last_pos) const;

  /// Finds loop construct associated with a continue construct, if it exists.
  /// Returns nullptr if:
  ///  - the given construct is not a continue construct
  ///  - the continue construct does not have an associated loop construct
  ///    (the continue target is also the loop header block)
  /// @param c the continue construct
  /// @returns the associated loop construct, or nullptr
  const Construct* SiblingLoopConstruct(const Construct* c) const;

  /// Returns an identifier expression for the swizzle name of the given
  /// index into a vector.  Emits an error and returns nullptr if the
  /// index is out of range, i.e. 4 or higher.
  /// @param i index of the subcomponent
  /// @returns the identifier expression for the `i`'th component
  ast::IdentifierExpression* Swizzle(uint32_t i);

  /// Returns an identifier expression for the swizzle name of the first
  /// `n` elements of a vector.  Emits an error and returns nullptr if `n`
  /// is out of range, i.e. 4 or higher.
  /// @param n the number of components in the swizzle
  /// @returns the swizzle identifier for the first n elements of a vector
  ast::IdentifierExpression* PrefixSwizzle(uint32_t n);

  /// Converts SPIR-V image coordinates from an image access instruction
  /// (e.g. OpImageSampledImplicitLod) into an expression list consisting of
  /// the texture coordinates, and an integral array index if the texture is
  /// arrayed. The texture coordinate is a scalar for 1D textures, a vector of
  /// 2 elements for a 2D texture, and a vector of 3 elements for a 3D or
  /// Cube texture. Excess components are ignored, e.g. if the SPIR-V
  /// coordinate is a 4-element vector but the image is a 2D non-arrayed
  /// texture then the 3rd and 4th components are ignored.
  /// On failure, issues an error and returns an empty expression list.
  /// @param image_access the image access instruction
  /// @returns an ExpressionList of the coordinate and array index (if any)
  ast::ExpressionList MakeCoordinateOperandsForImageAccess(
      const spvtools::opt::Instruction& image_access);

  /// Returns the given value as an I32.  If it's already an I32 then this
  /// return the given value.  Otherwise, wrap the value in a TypeConstructor
  /// expression.
  /// @param value the value to pass through or convert
  /// @returns the value as an I32 value.
  TypedExpression ToI32(TypedExpression value);

  /// Returns the given value as a signed integer type of the same shape
  /// if the value is unsigned scalar or vector, by wrapping the value
  /// with a TypeConstructor expression.  Returns the value itself if the
  /// value otherwise.
  /// @param value the value to pass through or convert
  /// @returns the value itself, or converted to signed integral
  TypedExpression ToSignedIfUnsigned(TypedExpression value);

 private:
  /// FunctionDeclaration contains the parsed information for a function header.
  struct FunctionDeclaration {
    /// Constructor
    FunctionDeclaration();
    /// Destructor
    ~FunctionDeclaration();

    /// Parsed header source
    Source source;
    /// Function name
    std::string name;
    /// Function parameters
    ast::VariableList params;
    /// Function return type
    type::Type* return_type;
    /// Function decorations
    ast::DecorationList decorations;
  };

  /// Parse the function declaration, which comprises the name, parameters, and
  /// return type, populating `decl`.
  /// @param decl the FunctionDeclaration to populate
  /// @returns true if emission has not yet failed.
  bool ParseFunctionDeclaration(FunctionDeclaration* decl);

  /// @returns the store type for the OpVariable instruction, or
  /// null on failure.
  type::Type* GetVariableStoreType(
      const spvtools::opt::Instruction& var_decl_inst);

  /// Returns an expression for an instruction operand. Signedness conversion is
  /// performed to match the result type of the SPIR-V instruction.
  /// @param inst the SPIR-V instruction
  /// @param operand_index the index of the operand, counting 0 as the first
  /// input operand
  /// @returns a new expression node
  TypedExpression MakeOperand(const spvtools::opt::Instruction& inst,
                              uint32_t operand_index);

  /// Returns an expression for a SPIR-V OpAccessChain or OpInBoundsAccessChain
  /// instruction.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  TypedExpression MakeAccessChain(const spvtools::opt::Instruction& inst);

  /// Emits a function call.  On failure, emits a diagnostic and returns false.
  /// @param inst the SPIR-V function call instruction
  /// @returns false if emission failed
  bool EmitFunctionCall(const spvtools::opt::Instruction& inst);

  /// Emits a control barrier intrinsic.  On failure, emits a diagnostic and
  /// returns false.
  /// @param inst the SPIR-V control barrier instruction
  /// @returns false if emission failed
  bool EmitControlBarrier(const spvtools::opt::Instruction& inst);

  /// Returns an expression for a SPIR-V instruction that maps to a WGSL
  /// intrinsic function call.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  TypedExpression MakeIntrinsicCall(const spvtools::opt::Instruction& inst);

  /// Returns an expression for a SPIR-V OpArrayLength instruction.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  TypedExpression MakeArrayLength(const spvtools::opt::Instruction& inst);

  /// Generates an expression for a SPIR-V OpOuterProduct instruction.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  TypedExpression MakeOuterProduct(const spvtools::opt::Instruction& inst);

  /// Generates statements for a SPIR-V OpVectorInsertDynamic instruction.
  /// Registers a const declaration for the result.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  bool MakeVectorInsertDynamic(const spvtools::opt::Instruction& inst);

  /// Generates statements for a SPIR-V OpComposite instruction.
  /// Registers a const declaration for the result.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  bool MakeCompositeInsert(const spvtools::opt::Instruction& inst);

  /// Get the SPIR-V instruction for the image memory object declaration for
  /// the image operand to the given instruction.
  /// @param inst the SPIR-V instruction
  /// @returns a SPIR-V OpVariable or OpFunctionParameter instruction, or null
  /// on error
  const spvtools::opt::Instruction* GetImage(
      const spvtools::opt::Instruction& inst);

  /// Get the AST texture the SPIR-V image memory object declaration.
  /// @param inst the SPIR-V memory object declaration for the image.
  /// @returns a texture type, or null on error
  type::Texture* GetImageType(const spvtools::opt::Instruction& inst);

  /// Get the expression for the image operand from the first operand to the
  /// given instruction.
  /// @param inst the SPIR-V instruction
  /// @returns an identifier expression, or null on error
  ast::Expression* GetImageExpression(const spvtools::opt::Instruction& inst);

  /// Get the expression for the sampler operand from the first operand to the
  /// given instruction.
  /// @param inst the SPIR-V instruction
  /// @returns an identifier expression, or null on error
  ast::Expression* GetSamplerExpression(const spvtools::opt::Instruction& inst);

  /// Emits a texture builtin function call for a SPIR-V instruction that
  /// accesses an image or sampled image.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  bool EmitImageAccess(const spvtools::opt::Instruction& inst);

  /// Emits statements to implement a SPIR-V image query.
  /// @param inst the SPIR-V instruction
  /// @returns an expression
  bool EmitImageQuery(const spvtools::opt::Instruction& inst);

  /// Converts the given texel to match the type required for the storage
  /// texture with the given type. This can generate a swizzle to retain
  /// only the first few components of the texel vector, and maybe a bitcast
  /// to convert signedness.  Returns an expression, or emits an error and
  /// returns nullptr.
  /// @param inst the image access instruction (used for diagnostics)
  /// @param texel the texel
  /// @param texture_type the type of the storage texture
  /// @returns the texel, after necessary conversion.
  ast::Expression* ConvertTexelForStorage(
      const spvtools::opt::Instruction& inst,
      TypedExpression texel,
      type::Texture* texture_type);

  /// Returns an expression for an OpSelect, if its operands are scalars
  /// or vectors. These translate directly to WGSL select.  Otherwise, return
  /// an expression with a null owned expression
  /// @param inst the SPIR-V OpSelect instruction
  /// @returns a typed expression, or one with a null owned expression
  TypedExpression MakeSimpleSelect(const spvtools::opt::Instruction& inst);

  /// Finds the header block for a structured construct that we can "break"
  /// out from, from deeply nested control flow, if such a block exists.
  /// If the construct is:
  ///  - a switch selection: return the selection header (ending in OpSwitch)
  ///  - a loop construct: return the loop header block
  ///  - a continue construct: return the loop header block
  /// Otherwise, return nullptr.
  /// @param c a structured construct, or nullptr
  /// @returns the block info for the structured header we can "break" from,
  /// or nullptr
  BlockInfo* HeaderIfBreakable(const Construct* c);

  /// Appends a new statement to the top of the statement stack.
  /// Does nothing if the statement is null.
  /// @param statement the new statement
  /// @returns a pointer to the statement.
  ast::Statement* AddStatement(ast::Statement* statement);

  /// AddStatementBuilder() constructs and adds the StatementBuilder of type
  /// `T` to the top of the statement stack.
  /// @param args the arguments forwarded to the T constructor
  /// @return the built StatementBuilder
  template <typename T, typename... ARGS>
  T* AddStatementBuilder(ARGS&&... args) {
    TINT_ASSERT(!statements_stack_.empty());
    return statements_stack_.back().AddStatementBuilder<T>(
        std::forward<ARGS>(args)...);
  }

  /// Returns the source record for the given instruction.
  /// @param inst the SPIR-V instruction
  /// @return the Source record, or a default one
  Source GetSourceForInst(const spvtools::opt::Instruction& inst) const;

  /// @returns the last statetment in the top of the statement stack.
  ast::Statement* LastStatement();

  using CompletionAction = std::function<void(const ast::StatementList&)>;

  // A StatementBlock represents a braced-list of statements while it is being
  // constructed.
  class StatementBlock {
   public:
    StatementBlock(const Construct* construct,
                   uint32_t end_id,
                   CompletionAction completion_action);
    StatementBlock(StatementBlock&&);
    ~StatementBlock();

    StatementBlock(const StatementBlock&) = delete;
    StatementBlock& operator=(const StatementBlock&) = delete;

    /// Replaces any StatementBuilders with the built result, and calls the
    /// completion callback (if set). Must only be called once, after all
    /// statements have been added with Add().
    /// @param builder the program builder
    void Finalize(ProgramBuilder* builder);

    /// Add() adds `statement` to the block.
    /// Add() must not be called after calling Finalize().
    void Add(ast::Statement* statement);

    /// AddStatementBuilder() constructs and adds the StatementBuilder of type
    /// `T` to the block.
    /// Add() must not be called after calling Finalize().
    /// @param args the arguments forwarded to the T constructor
    /// @return the built StatementBuilder
    template <typename T, typename... ARGS>
    T* AddStatementBuilder(ARGS&&... args) {
      auto builder = std::make_unique<T>(std::forward<ARGS>(args)...);
      auto* ptr = builder.get();
      Add(ptr);
      builders_.emplace_back(std::move(builder));
      return ptr;
    }

    /// @param construct the construct which this construct constributes to
    void SetConstruct(const Construct* construct) { construct_ = construct; }

    /// @return the construct to which this construct constributes
    const Construct* GetConstruct() const { return construct_; }

    /// @return the ID of the block at which the completion action should be
    /// triggered and this statement block discarded. This is often the `end_id`
    /// of `construct` itself.
    uint32_t GetEndId() const { return end_id_; }

    /// @return the list of statements being built, if this construct is not a
    /// switch.
    const ast::StatementList& GetStatements() const { return statements_; }

   private:
    /// The construct to which this construct constributes.
    const Construct* construct_;
    /// The ID of the block at which the completion action should be triggered
    /// and this statement block discarded. This is often the `end_id` of
    /// `construct` itself.
    uint32_t const end_id_;
    /// The completion action finishes processing this statement block.
    FunctionEmitter::CompletionAction const completion_action_;
    /// The list of statements being built, if this construct is not a switch.
    ast::StatementList statements_;

    /// Owned statement builders
    std::vector<std::unique_ptr<StatementBuilder>> builders_;
    /// True if Finalize() has been called.
    bool finalized_ = false;
  };

  /// Pushes an empty statement block onto the statements stack.
  /// @param action the completion action for this block
  void PushNewStatementBlock(const Construct* construct,
                             uint32_t end_id,
                             CompletionAction action);

  /// Emits an if-statement whose condition is the given flow guard
  /// variable, and pushes onto the statement stack the corresponding
  /// statement block ending (and not including) the given block.
  /// @param flow_guard name of the flow guard variable
  /// @param end_id first block after the if construct.
  void PushGuard(const std::string& flow_guard, uint32_t end_id);

  /// Emits an if-statement with 'true' condition, and pushes onto the
  /// statement stack the corresponding statement block ending (and not
  /// including) the given block.
  /// @param end_id first block after the if construct.
  void PushTrueGuard(uint32_t end_id);

  /// @returns a boolean true expression.
  ast::Expression* MakeTrue(const Source&) const;

  /// @returns a boolean false expression.
  ast::Expression* MakeFalse(const Source&) const;

  /// Creates a new `ast::Node` owned by the ProgramBuilder.
  /// @param args the arguments to pass to the type constructor
  /// @returns the node pointer
  template <typename T, typename... ARGS>
  T* create(ARGS&&... args) const {
    return builder_.create<T>(std::forward<ARGS>(args)...);
  }

  using StatementsStack = std::vector<StatementBlock>;

  ParserImpl& parser_impl_;
  ProgramBuilder& builder_;
  spvtools::opt::IRContext& ir_context_;
  spvtools::opt::analysis::DefUseManager* def_use_mgr_;
  spvtools::opt::analysis::ConstantManager* constant_mgr_;
  spvtools::opt::analysis::TypeManager* type_mgr_;
  FailStream& fail_stream_;
  Namer& namer_;
  const spvtools::opt::Function& function_;
  type::I32* const i32_;  // The unique I32 type object.
  type::U32* const u32_;  // The unique U32 type object.

  // The SPIR-V ID for the SampleMask input variable.
  uint32_t sample_mask_in_id;
  // The SPIR-V ID for the SampleMask output variable.
  uint32_t sample_mask_out_id;

  // A stack of statement lists. Each list is contained in a construct in
  // the next deeper element of stack. The 0th entry represents the statements
  // for the entire function.  This stack is never empty.
  // The `construct` member for the 0th element is only valid during the
  // lifetime of the EmitFunctionBodyStatements method.
  StatementsStack statements_stack_;

  // The set of IDs that have already had an identifier name generated for it.
  std::unordered_set<uint32_t> identifier_values_;
  // Mapping from SPIR-V ID that is used at most once, to its AST expression.
  std::unordered_map<uint32_t, TypedExpression> singly_used_values_;

  // The IDs of basic blocks, in reverse structured post-order (RSPO).
  // This is the output order for the basic blocks.
  std::vector<uint32_t> block_order_;

  // Mapping from block ID to its bookkeeping info.
  std::unordered_map<uint32_t, std::unique_ptr<BlockInfo>> block_info_;

  // Mapping from a locally-defined result ID to its bookkeeping info.
  std::unordered_map<uint32_t, std::unique_ptr<DefInfo>> def_info_;

  // Structured constructs, where enclosing constructs precede their children.
  ConstructList constructs_;

  // Information about entry point, if this function is referenced by one
  const EntryPointInfo* ep_info_ = nullptr;
};

}  // namespace spirv
}  // namespace reader
}  // namespace tint

#endif  // SRC_READER_SPIRV_FUNCTION_H_
