// Copyright (c) 2020 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_OPT_DEBUG_INFO_MANAGER_H_
#define SOURCE_OPT_DEBUG_INFO_MANAGER_H_

#include <unordered_map>
#include <unordered_set>

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

namespace spvtools {
namespace opt {
namespace analysis {

// When an instruction of a callee function is inlined to its caller function,
// we need the line and the scope information of the function call instruction
// to generate DebugInlinedAt. This class keeps the data. For multiple inlining
// of a single instruction, we have to create multiple DebugInlinedAt
// instructions as a chain. This class keeps the information of the generated
// DebugInlinedAt chains to reduce the number of chains.
class DebugInlinedAtContext {
 public:
  explicit DebugInlinedAtContext(Instruction* call_inst)
      : call_inst_line_(call_inst->dbg_line_inst()),
        call_inst_scope_(call_inst->GetDebugScope()) {}

  const Instruction* GetLineOfCallInstruction() { return call_inst_line_; }
  const DebugScope& GetScopeOfCallInstruction() { return call_inst_scope_; }
  // Puts the DebugInlinedAt chain that is generated for the callee instruction
  // whose DebugInlinedAt of DebugScope is |callee_instr_inlined_at| into
  // |callee_inlined_at2chain_|.
  void SetDebugInlinedAtChain(uint32_t callee_instr_inlined_at,
                              uint32_t chain_head_id) {
    callee_inlined_at2chain_[callee_instr_inlined_at] = chain_head_id;
  }
  // Gets the DebugInlinedAt chain from |callee_inlined_at2chain_|.
  uint32_t GetDebugInlinedAtChain(uint32_t callee_instr_inlined_at) {
    auto chain_itr = callee_inlined_at2chain_.find(callee_instr_inlined_at);
    if (chain_itr != callee_inlined_at2chain_.end()) return chain_itr->second;
    return kNoInlinedAt;
  }

 private:
  // The line information of the function call instruction that will be
  // replaced by the callee function.
  const Instruction* call_inst_line_;

  // The scope information of the function call instruction that will be
  // replaced by the callee function.
  const DebugScope call_inst_scope_;

  // Map from DebugInlinedAt ids of callee to head ids of new generated
  // DebugInlinedAt chain.
  std::unordered_map<uint32_t, uint32_t> callee_inlined_at2chain_;
};

// A class for analyzing, managing, and creating OpenCL.DebugInfo.100 extension
// instructions.
class DebugInfoManager {
 public:
  // Constructs a debug information manager from the given |context|.
  DebugInfoManager(IRContext* context);

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

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

  // Analyzes OpenCL.DebugInfo.100 instruction |dbg_inst|.
  void AnalyzeDebugInst(Instruction* dbg_inst);

  // Creates new DebugInlinedAt and returns its id. Its line operand is the
  // line number of |line| if |line| is not nullptr. Otherwise, its line operand
  // is the line number of lexical scope of |scope|. Its Scope and Inlined
  // operands are Scope and Inlined of |scope|.
  uint32_t CreateDebugInlinedAt(const Instruction* line,
                                const DebugScope& scope);

  // Clones DebugExpress instruction |dbg_expr| and add Deref Operation
  // in the front of the Operation list of |dbg_expr|.
  Instruction* DerefDebugExpression(Instruction* dbg_expr);

  // Returns a DebugInfoNone instruction.
  Instruction* GetDebugInfoNone();

  // Returns DebugInlinedAt whose id is |dbg_inlined_at_id|. If it does not
  // exist or it is not a DebugInlinedAt instruction, return nullptr.
  Instruction* GetDebugInlinedAt(uint32_t dbg_inlined_at_id);

  // Returns DebugFunction whose Function operand is |fn_id|. If it does not
  // exist, return nullptr.
  Instruction* GetDebugFunction(uint32_t fn_id) {
    auto dbg_fn_it = fn_id_to_dbg_fn_.find(fn_id);
    return dbg_fn_it == fn_id_to_dbg_fn_.end() ? nullptr : dbg_fn_it->second;
  }

  // Clones DebugInlinedAt whose id is |clone_inlined_at_id|. If
  // |clone_inlined_at_id| is not an id of DebugInlinedAt, returns nullptr.
  // If |insert_before| is given, inserts the new DebugInlinedAt before it.
  // Otherwise, inserts the new DebugInlinedAt into the debug instruction
  // section of the module.
  Instruction* CloneDebugInlinedAt(uint32_t clone_inlined_at_id,
                                   Instruction* insert_before = nullptr);

  // Returns the debug scope corresponding to an inlining instruction in the
  // scope |callee_instr_scope| into |inlined_at_ctx|. Generates all new
  // debug instructions needed to represent the scope.
  DebugScope BuildDebugScope(const DebugScope& callee_instr_scope,
                             DebugInlinedAtContext* inlined_at_ctx);

  // Returns DebugInlinedAt corresponding to inlining an instruction, which
  // was inlined at |callee_inlined_at|, into |inlined_at_ctx|. Generates all
  // new debug instructions needed to represent the DebugInlinedAt.
  uint32_t BuildDebugInlinedAtChain(uint32_t callee_inlined_at,
                                    DebugInlinedAtContext* inlined_at_ctx);

  // Returns true if there is a debug declaration instruction whose
  // 'Local Variable' operand is |variable_id|.
  bool IsVariableDebugDeclared(uint32_t variable_id);

  // Kills all debug declaration instructions with Deref whose 'Local Variable'
  // operand is |variable_id|.
  void KillDebugDeclares(uint32_t variable_id);

  // Generates a DebugValue instruction with value |value_id| for every local
  // variable that is in the scope of |scope_and_line| and whose memory is
  // |variable_id| and inserts it after the instruction |insert_pos|.
  void AddDebugValueIfVarDeclIsVisible(Instruction* scope_and_line,
                                       uint32_t variable_id, uint32_t value_id,
                                       Instruction* insert_pos);

  // Generates a DebugValue instruction with |dbg_local_var_id|, |value_id|,
  // |expr_id|, |index_id| operands and inserts it before |insert_before|.
  Instruction* AddDebugValueWithIndex(uint32_t dbg_local_var_id,
                                      uint32_t value_id, uint32_t expr_id,
                                      uint32_t index_id,
                                      Instruction* insert_before);

  // Erases |instr| from data structures of this class.
  void ClearDebugInfo(Instruction* instr);

  // Returns the id of Value operand if |inst| is DebugValue who has Deref
  // operation and its Value operand is a result id of OpVariable with
  // Function storage class. Otherwise, returns 0.
  uint32_t GetVariableIdOfDebugValueUsedForDeclare(Instruction* inst);

  // Converts DebugGlobalVariable |dbg_global_var| to a DebugLocalVariable and
  // creates a DebugDeclare mapping the new DebugLocalVariable to |local_var|.
  void ConvertDebugGlobalToLocalVariable(Instruction* dbg_global_var,
                                         Instruction* local_var);

  // Returns true if |instr| is a debug declaration instruction.
  bool IsDebugDeclare(Instruction* instr);

  // Replace all uses of |before| id that is an operand of a DebugScope with
  // |after| id if those uses (instruction) return true for |predicate|.
  void ReplaceAllUsesInDebugScopeWithPredicate(
      uint32_t before, uint32_t after,
      const std::function<bool(Instruction*)>& predicate);

  // Removes uses of DebugScope |inst| from |scope_id_to_users_| or uses of
  // DebugInlinedAt |inst| from |inlinedat_id_to_users_|.
  void ClearDebugScopeAndInlinedAtUses(Instruction* inst);

 private:
  IRContext* context() { return context_; }

  // Analyzes OpenCL.DebugInfo.100 instructions in the given |module| and
  // populates data structures in this class.
  void AnalyzeDebugInsts(Module& module);

  // Returns the debug instruction whose id is |id|. Returns |nullptr| if one
  // does not exists.
  Instruction* GetDbgInst(uint32_t id);

  // Returns a DebugOperation instruction with OpCode Deref.
  Instruction* GetDebugOperationWithDeref();

  // Registers the debug instruction |inst| into |id_to_dbg_inst_| using id of
  // |inst| as a key.
  void RegisterDbgInst(Instruction* inst);

  // Register the DebugFunction instruction |inst|. The function referenced
  // in |inst| must not already be registered.
  void RegisterDbgFunction(Instruction* inst);

  // Register the DebugDeclare or DebugValue with Deref operation
  // |dbg_declare| into |var_id_to_dbg_decl_| using OpVariable id
  // |var_id| as a key.
  void RegisterDbgDeclare(uint32_t var_id, Instruction* dbg_declare);

  // Returns a DebugExpression instruction without Operation operands.
  Instruction* GetEmptyDebugExpression();

  // Returns true if a scope |ancestor| is |scope| or an ancestor scope
  // of |scope|.
  bool IsAncestorOfScope(uint32_t scope, uint32_t ancestor);

  // Returns the DebugLocalVariable declared by |dbg_declare|.
  Instruction* GetDebugLocalVariableFromDeclare(Instruction* dbg_declare);

  // Returns true if the DebugLocalVariable |dbg_local_var| is a function
  // parameter.
  bool IsFunctionParameter(Instruction* dbg_local_var) const;

  // Returns true if the DebugLocalVariable |dbg_local_var| is visible
  // in the scope of an instruction |instr_scope_id|.
  bool IsLocalVariableVisibleToInstr(Instruction* dbg_local_var,
                                     uint32_t instr_scope_id);

  // Returns the parent scope of the scope |child_scope|.
  uint32_t GetParentScope(uint32_t child_scope);

  IRContext* context_;

  // Mapping from ids of OpenCL.DebugInfo.100 extension instructions
  // to their Instruction instances.
  std::unordered_map<uint32_t, Instruction*> id_to_dbg_inst_;

  // Mapping from function's ids to DebugFunction instructions whose
  // operand is the function.
  std::unordered_map<uint32_t, Instruction*> fn_id_to_dbg_fn_;

  // Mapping from variable or value ids to DebugDeclare or DebugValue
  // instructions whose operand is the variable or value.
  std::unordered_map<uint32_t, std::unordered_set<Instruction*>>
      var_id_to_dbg_decl_;

  // Mapping from DebugScope ids to users.
  std::unordered_map<uint32_t, std::unordered_set<Instruction*>>
      scope_id_to_users_;

  // Mapping from DebugInlinedAt ids to users.
  std::unordered_map<uint32_t, std::unordered_set<Instruction*>>
      inlinedat_id_to_users_;

  // DebugOperation whose OpCode is OpenCLDebugInfo100Deref.
  Instruction* deref_operation_;

  // DebugInfoNone instruction. We need only a single DebugInfoNone.
  // To reuse the existing one, we keep it using this member variable.
  Instruction* debug_info_none_inst_;

  // DebugExpression instruction without Operation operands. We need only
  // a single DebugExpression without Operation operands. To reuse the
  // existing one, we keep it using this member variable.
  Instruction* empty_debug_expr_inst_;
};

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

#endif  // SOURCE_OPT_DEBUG_INFO_MANAGER_H_
