// Copyright (c) 2017 Pierre Moreau
//
// 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_OPT_DECORATION_MANAGER_H_
#define SOURCE_OPT_DECORATION_MANAGER_H_

#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "source/opt/instruction.h"
#include "source/opt/module.h"

namespace spvtools {
namespace opt {
namespace analysis {

// A class for analyzing and managing decorations in an Module.
class DecorationManager {
 public:
  // Constructs a decoration manager from the given |module|
  explicit DecorationManager(Module* module) : module_(module) {
    AnalyzeDecorations();
  }
  DecorationManager() = delete;

  // Removes all decorations (direct and through groups) where |pred| is
  // true and that apply to |id| so that they no longer apply to |id|.  Returns
  // true if something changed.
  //
  // If |id| is part of a group, it will be removed from the group if it
  // does not use all of the group's decorations, or, if there are no
  // decorations that apply to the group.
  //
  // If decoration groups become empty, the |OpGroupDecorate| and
  // |OpGroupMemberDecorate| instructions will be killed.
  //
  // Decoration instructions that apply directly to |id| will be killed.
  //
  // If |id| is a decoration group and all of the group's decorations are
  // removed, then the |OpGroupDecorate| and
  // |OpGroupMemberDecorate| for the group will be killed, but not the defining
  // |OpDecorationGroup| instruction.
  bool RemoveDecorationsFrom(
      uint32_t id, std::function<bool(const Instruction&)> pred =
                       [](const Instruction&) { return true; });

  // Removes all decorations from the result id of |inst|.
  //
  // NOTE: This is only meant to be called from ir_context, as only metadata
  // will be removed, and no actual instruction.
  void RemoveDecoration(Instruction* inst);

  // Returns a vector of all decorations affecting |id|. If a group is applied
  // to |id|, the decorations of that group are returned rather than the group
  // decoration instruction. If |include_linkage| is not set, linkage
  // decorations won't be returned.
  std::vector<Instruction*> GetDecorationsFor(uint32_t id,
                                              bool include_linkage);
  std::vector<const Instruction*> GetDecorationsFor(uint32_t id,
                                                    bool include_linkage) const;
  // Returns whether two IDs have the same decorations. Two SpvOpGroupDecorate
  // instructions that apply the same decorations but to different IDs, still
  // count as being the same.
  bool HaveTheSameDecorations(uint32_t id1, uint32_t id2) const;

  // Returns whether two IDs have the same decorations. Two SpvOpGroupDecorate
  // instructions that apply the same decorations but to different IDs, still
  // count as being the same.
  bool HaveSubsetOfDecorations(uint32_t id1, uint32_t id2) const;

  // Returns whether the two decorations instructions are the same and are
  // applying the same decorations; unless |ignore_target| is false, the targets
  // to which they are applied to does not matter, except for the member part.
  //
  // This is only valid for OpDecorate, OpMemberDecorate and OpDecorateId; it
  // will return false for other opcodes.
  bool AreDecorationsTheSame(const Instruction* inst1, const Instruction* inst2,
                             bool ignore_target) const;

  // Returns whether a decoration instruction for |id| with decoration
  // |decoration| exists or not.
  bool HasDecoration(uint32_t id, uint32_t decoration);

  // |f| is run on each decoration instruction for |id| with decoration
  // |decoration|. Processed are all decorations which target |id| either
  // directly or indirectly by Decoration Groups.
  void ForEachDecoration(uint32_t id, uint32_t decoration,
                         std::function<void(const Instruction&)> f);

  // |f| is run on each decoration instruction for |id| with decoration
  // |decoration|. Processes all decoration which target |id| either directly or
  // indirectly through decoration groups. If |f| returns false, iteration is
  // terminated and this function returns false.
  bool WhileEachDecoration(uint32_t id, uint32_t decoration,
                           std::function<bool(const Instruction&)> f);

  // |f| is run on each decoration instruction for |id| with decoration
  // |decoration|. Processes all decoration which target |id| either directly or
  // indirectly through decoration groups. If |f| returns true, iteration is
  // terminated and this function returns true. Otherwise returns false.
  bool FindDecoration(uint32_t id, uint32_t decoration,
                      std::function<bool(const Instruction&)> f);

  // Clone all decorations from one id |from|.
  // The cloned decorations are assigned to the given id |to| and are
  // added to the module. The purpose is to decorate cloned instructions.
  // This function does not check if the id |to| is already decorated.
  void CloneDecorations(uint32_t from, uint32_t to);

  // Same as above, but only clone the decoration if the decoration operand is
  // in |decorations_to_copy|.  This function has the extra restriction that
  // |from| and |to| must not be an object, not a type.
  void CloneDecorations(uint32_t from, uint32_t to,
                        const std::vector<SpvDecoration>& decorations_to_copy);

  // Informs the decoration manager of a new decoration that it needs to track.
  void AddDecoration(Instruction* inst);

  // Add decoration with |opcode| and operands |opnds|.
  void AddDecoration(SpvOp opcode, const std::vector<Operand> opnds);

  // Add |decoration| of |inst_id| to module.
  void AddDecoration(uint32_t inst_id, uint32_t decoration);

  // Add |decoration, decoration_value| of |inst_id| to module.
  void AddDecorationVal(uint32_t inst_id, uint32_t decoration,
                        uint32_t decoration_value);

  // Add |decoration, decoration_value| of |inst_id, member| to module.
  void AddMemberDecoration(uint32_t member, uint32_t inst_id,
                           uint32_t decoration, uint32_t decoration_value);

  friend bool operator==(const DecorationManager&, const DecorationManager&);
  friend bool operator!=(const DecorationManager& lhs,
                         const DecorationManager& rhs) {
    return !(lhs == rhs);
  }

 private:
  // Analyzes the defs and uses in the given |module| and populates data
  // structures in this class. Does nothing if |module| is nullptr.
  void AnalyzeDecorations();

  template <typename T>
  std::vector<T> InternalGetDecorationsFor(uint32_t id, bool include_linkage);

  // Tracks decoration information of an ID.
  struct TargetData {
    std::vector<Instruction*> direct_decorations;    // All decorate
                                                     // instructions applied
                                                     // to the tracked ID.
    std::vector<Instruction*> indirect_decorations;  // All instructions
                                                     // applying a group to
                                                     // the tracked ID.
    std::vector<Instruction*> decorate_insts;  // All decorate instructions
                                               // applying the decorations
                                               // of the tracked ID to
                                               // targets.
                                               // It is empty if the
                                               // tracked ID is not a
                                               // group.
  };

  friend bool operator==(const TargetData& lhs, const TargetData& rhs) {
    if (!std::is_permutation(lhs.direct_decorations.begin(),
                             lhs.direct_decorations.end(),
                             rhs.direct_decorations.begin())) {
      return false;
    }
    if (!std::is_permutation(lhs.indirect_decorations.begin(),
                             lhs.indirect_decorations.end(),
                             rhs.indirect_decorations.begin())) {
      return false;
    }
    if (!std::is_permutation(lhs.decorate_insts.begin(),
                             lhs.decorate_insts.end(),
                             rhs.decorate_insts.begin())) {
      return false;
    }
    return true;
  }

  // Mapping from ids to the instructions applying a decoration to those ids.
  // In other words, for each id you get all decoration instructions
  // referencing that id, be it directly (SpvOpDecorate, SpvOpMemberDecorate
  // and SpvOpDecorateId), or indirectly (SpvOpGroupDecorate,
  // SpvOpMemberGroupDecorate).
  std::unordered_map<uint32_t, TargetData> id_to_decoration_insts_;
  // The enclosing module.
  Module* module_;
};

}  // namespace analysis
}  // namespace opt
}  // namespace spvtools

#endif  // SOURCE_OPT_DECORATION_MANAGER_H_
