// 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 "pass.h"

#include <functional>
#include <tuple>

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 barrier instructions.
  // Memory and image instructions convert coherent and volatile decorations
  // into flags on the instruction. Barriers in tessellation shaders get the
  // output storage semantic if appropriate.
  void UpgradeInstructions();

  // 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);

  // 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);

  // 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_
