// Copyright (c) 2018 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 LIBSPIRV_OPT_UPGRADE_MEMORY_MODEL_H_
#define LIBSPIRV_OPT_UPGRADE_MEMORY_MODEL_H_

#include <functional>
#include <tuple>

#include "pass.h"

namespace spvtools {
namespace opt {

// Hashing functor for the memoized result store.
struct CacheHash {
  size_t operator()(
      const std::pair<uint32_t, std::vector<uint32_t>>& item) const {
    std::u32string to_hash;
    to_hash.push_back(item.first);
    for (auto i : item.second) to_hash.push_back(i);
    return std::hash<std::u32string>()(to_hash);
  }
};

// Upgrades the memory model from Logical GLSL450 to Logical VulkanKHR.
//
// This pass remove deprecated decorations (Volatile and Coherent) and replaces
// them with new flags on individual instructions. It adds the Output storage
// class semantic to control barriers in tessellation control shaders that have
// an access to Output memory.
class UpgradeMemoryModel : public Pass {
 public:
  const char* name() const override { return "upgrade-memory-model"; }
  Status Process() override;

 private:
  // Used to indicate whether the operation performs an availability or
  // visibility operation.
  enum OperationType { kVisibility, kAvailability };

  // Used to indicate whether the instruction is a memory or image instruction.
  enum InstructionType { kMemory, kImage };

  // Modifies the OpMemoryModel to use VulkanKHR. Adds the Vulkan memory model
  // capability and extension.
  void UpgradeMemoryModelInstruction();

  // Upgrades memory, image and atomic instructions.
  // Memory and image instructions convert coherent and volatile decorations
  // into flags on the instruction.
  // Atomic memory semantics convert volatile decoration into flags on the
  // instruction.
  void UpgradeInstructions();

  // Upgrades memory and image operands for instructions that have them.
  void UpgradeMemoryAndImages();

  // Adds the volatile memory semantic if necessary.
  void UpgradeAtomics();

  // Returns whether |id| is coherent and/or volatile.
  std::tuple<bool, bool, SpvScope> GetInstructionAttributes(uint32_t id);

  // Traces |inst| to determine if it is coherent and/or volatile.
  // |indices| tracks the access chain indices seen so far.
  std::pair<bool, bool> TraceInstruction(Instruction* inst,
                                         std::vector<uint32_t> indices,
                                         std::unordered_set<uint32_t>* visited);

  // Return true if |inst| is decorated with |decoration|.
  // If |inst| is decorated by member decorations then either |value| must
  // match the index or |value| must be a maximum allowable value. The max
  // value allows any element to match.
  bool HasDecoration(const Instruction* inst, uint32_t value,
                     SpvDecoration decoration);

  // Returns whether |type_id| indexed via |indices| is coherent and/or
  // volatile.
  std::pair<bool, bool> CheckType(uint32_t type_id,
                                  const std::vector<uint32_t>& indices);

  // Returns whether any type/element under |inst| is coherent and/or volatile.
  std::pair<bool, bool> CheckAllTypes(const Instruction* inst);

  // Modifies the flags of |inst| to include the new flags for the Vulkan
  // memory model. |operation_type| indicates whether flags should use
  // MakeVisible or MakeAvailable variants. |inst_type| indicates whether the
  // Pointer or Texel variants of flags should be used.
  void UpgradeFlags(Instruction* inst, uint32_t in_operand, bool is_coherent,
                    bool is_volatile, OperationType operation_type,
                    InstructionType inst_type);

  // Modifies the semantics at |in_operand| of |inst| to include the volatile
  // bit if |is_volatile| is true.
  void UpgradeSemantics(Instruction* inst, uint32_t in_operand,
                        bool is_volatile);

  // Returns the result id for a constant for |scope|.
  uint32_t GetScopeConstant(SpvScope scope);

  // Returns the value of |index_inst|. |index_inst| must be an OpConstant of
  // integer type.g
  uint64_t GetIndexValue(Instruction* index_inst);

  // Removes coherent and volatile decorations.
  void CleanupDecorations();

  // For all tessellation control entry points, if there is an operation on
  // Output storage class, then all barriers are modified to include the
  // OutputMemoryKHR semantic.
  void UpgradeBarriers();

  // If the Vulkan memory model is specified, device scope actually means
  // device scope. The memory scope must be modified to be QueueFamilyKHR
  // scope.
  void UpgradeMemoryScope();

  // Returns true if |scope_id| is SpvScopeDevice.
  bool IsDeviceScope(uint32_t scope_id);

  // Upgrades GLSL.std.450 modf and frexp. Both instructions are replaced with
  // their struct versions. New extracts and a store are added in order to
  // facilitate adding memory model flags.
  void UpgradeExtInst(Instruction* modf);

  // Returns the number of words taken up by a memory access argument and its
  // implied operands.
  uint32_t MemoryAccessNumWords(uint32_t mask);

  // Caches the result of TraceInstruction. For a given result id and set of
  // indices, stores whether that combination is coherent and/or volatile.
  std::unordered_map<std::pair<uint32_t, std::vector<uint32_t>>,
                     std::pair<bool, bool>, CacheHash>
      cache_;
};
}  // namespace opt
}  // namespace spvtools
#endif  // LIBSPIRV_OPT_UPGRADE_MEMORY_MODEL_H_
