//===-- TraceHTR.h --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache
// License v2.0 with LLVM Exceptions.// See https://llvm.org/LICENSE.txt for
// license information.// SPDX-License-Identifier: Apache-2.0 WITH
// LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_TARGET_TRACE_HTR_H
#define LLDB_TARGET_TRACE_HTR_H

#include "lldb/Target/Thread.h"
#include "lldb/Target/Trace.h"

#include <unordered_map>
#include <unordered_set>

namespace lldb_private {

/// Metadata associated with an HTR block
/// See lldb/docs/htr.rst for comprehensive HTR documentation
class HTRBlockMetadata {
public:
  /// Constructor for a block's metadata.
  ///
  /// \param[in] first_instruction_load_address
  ///     The load address of the block's first instruction.
  ///
  /// \param[in] num_instructions
  ///     The total number of instructions in the block.
  ///
  /// \param[in] func_calls
  ///     The map of a function name to the number of times it is called from
  ///     the block.
  HTRBlockMetadata(lldb::addr_t first_instruction_load_address,
                   size_t num_instructions,
                   llvm::DenseMap<ConstString, size_t> &&func_calls)
      : m_first_instruction_load_address(first_instruction_load_address),
        m_num_instructions(num_instructions), m_func_calls(func_calls) {}

  /// Merge two \a HTRBlockMetadata in place.
  ///
  /// \param[in][out] merged_metadata
  ///     Metadata that metadata_to_merge will be merged into.
  ///
  /// \param[in] metadata_to_merge
  ///     Metadata to merge into merged_metadata.
  static void MergeMetadata(HTRBlockMetadata &merged_metadata,
                            HTRBlockMetadata const &metadata_to_merge);
  /// Get the number of instructions in the block.
  ///
  /// \return
  ///     The number of instructions in the block.
  size_t GetNumInstructions() const;

  /// Get the name of the most frequently called function from the block.
  ///
  /// \return
  ///     The name of the function that is called the most from this block or
  ///     None if no function is called from this block.
  llvm::Optional<llvm::StringRef> GetMostFrequentlyCalledFunction() const;

  /// Get the load address of the first instruction in the block.
  ///
  /// \return
  ///     The load address of the first instruction in the block.
  lldb::addr_t GetFirstInstructionLoadAddress() const;

  /// Get the function calls map for the block.
  /// Function calls are identified in the instruction layer by finding 'call'
  /// instructions and determining the function they are calling. As these
  /// instructions are merged into blocks, we merge these different function
  /// calls into a single map containing the function names to the number of
  /// times it is called from this block.
  ///
  /// \return
  ///     The mapping of function name to the number of times it is called from
  ///     this block.
  llvm::DenseMap<ConstString, size_t> const &GetFunctionCalls() const;

private:
  lldb::addr_t m_first_instruction_load_address;
  size_t m_num_instructions;
  llvm::DenseMap<ConstString, size_t> m_func_calls;
};

/// Block structure representing a sequence of trace "units" (ie instructions).
/// Sequences of blocks are merged to create a new, single block
/// See lldb/docs/htr.rst for comprehensive HTR documentation
class HTRBlock {
public:
  /// Constructor for a block of an HTR layer.
  ///
  /// \param[in] offset
  ///     The offset of the start of this block in the previous layer.
  ///
  /// \param[in] size
  ///     Number of blocks/instructions that make up this block in the previous
  ///     layer.
  ///
  /// \param[in] metadata
  ///     General metadata for this block.
  HTRBlock(size_t offset, size_t size, HTRBlockMetadata metadata)
      : m_offset(offset), m_size(size), m_metadata(metadata) {}

  /// Get the offset of the start of this block in the previous layer.
  ///
  /// \return
  ///     The offset of the block.
  size_t GetOffset() const;

  /// Get the number of blocks/instructions that make up this block in the
  /// previous layer.
  ///
  /// \return
  ///     The size of the block.
  size_t GetSize() const;

  /// Get the metadata for this block.
  ///
  /// \return
  ///     The metadata of the block.
  HTRBlockMetadata const &GetMetadata() const;

private:
  /// Offset in the previous layer
  size_t m_offset;
  /// Number of blocks/instructions that make up this block in the previous
  /// layer
  size_t m_size;
  /// General metadata for this block
  HTRBlockMetadata m_metadata;
};

/// HTR layer interface
/// See lldb/docs/htr.rst for comprehensive HTR documentation
class IHTRLayer {
public:
  /// Construct new HTR layer.
  //
  /// \param[in] id
  ///     The layer's id.
  IHTRLayer(size_t id) : m_layer_id(id) {}

  /// Get the ID of the layer.
  ///
  /// \return
  ///     The layer ID of this layer.
  size_t GetLayerId() const;

  /// Get the metadata of a unit (instruction or block) in the layer.
  ///
  /// \param[in] index
  ///     The position of the unit in the layer.
  ///
  /// \return
  ///     The metadata of the unit in the layer.
  virtual HTRBlockMetadata GetMetadataByIndex(size_t index) const = 0;

  /// Get the total number of units (instruction or block) in this layer.
  ///
  /// \return
  ///     The total number of units in the layer.
  virtual size_t GetNumUnits() const = 0;

  /// Creates a new block from the result of merging a contiguous sequence of
  /// "units" (instructions or blocks depending on layer type) in this layer
  /// This allows the implementation class to decide how to store/generate this
  /// metadata. For example, in the case of the instruction layer we want to
  /// lazily generate this metadata instead of storing it for each instruction.
  ///
  /// \param[in] start_unit_index
  ///     The index of the first unit to be merged.
  ///
  /// \param[in] num_units
  ///     The number of units to be merged. Must be >= 1, since merging 0 blocks
  ///     does not make sense.
  ///
  /// \return
  ///     A new block instance representing the merge of the specified units.
  HTRBlock MergeUnits(size_t start_unit_index, size_t num_units);

  virtual ~IHTRLayer() = default;

protected:
  /// ID of the layer.
  size_t m_layer_id;
};

/// "Base" layer of HTR representing the dynamic instructions of the trace.
/// See lldb/docs/htr.rst for comprehensive HTR documentation
class HTRInstructionLayer : public IHTRLayer {
public:
  /// Construct new instruction layer.
  //
  /// \param[in] id
  ///     The layer's id.
  HTRInstructionLayer(size_t id) : IHTRLayer(id) {}

  size_t GetNumUnits() const override;

  HTRBlockMetadata GetMetadataByIndex(size_t index) const override;

  /// Get the dynamic instruction trace.
  ///
  /// \return
  ///     The dynamic instruction trace.
  llvm::ArrayRef<lldb::addr_t> GetInstructionTrace() const;

  /// Add metadata for a 'call' instruction of the trace.
  ///
  /// \param[in] load_addr
  ///     The load address of the 'call' instruction.
  ///
  /// \param[in] func_name
  ///     The name of the function the 'call' instruction is calling if it can
  ///     be determined, None otherwise.
  void AddCallInstructionMetadata(lldb::addr_t load_addr,
                                  llvm::Optional<ConstString> func_name);

  /// Append the load address of an instruction to the dynamic instruction
  /// trace.
  ///
  /// \param[in] load_addr
  ///     The load address of the instruction.
  void AppendInstruction(lldb::addr_t load_addr);

private:
  // Dynamic instructions of trace are stored in chronological order.
  std::vector<lldb::addr_t> m_instruction_trace;
  // Only store metadata for instructions of interest (call instructions)
  // If we stored metadata for each instruction this would be wasteful since
  // most instructions don't contain useful metadata

  // This map contains the load address of all the call instructions.
  // load address maps to the name of the function it calls (None if function
  // name can't be determined)
  std::unordered_map<lldb::addr_t, llvm::Optional<ConstString>> m_call_isns;
};

/// HTR layer composed of blocks of the trace.
/// See lldb/docs/htr.rst for comprehensive HTR documentation
class HTRBlockLayer : public IHTRLayer {
public:
  /// Construct new block layer.
  //
  /// \param[in] id
  ///     The layer's id.
  HTRBlockLayer(size_t id) : IHTRLayer(id) {}

  size_t GetNumUnits() const override;

  HTRBlockMetadata GetMetadataByIndex(size_t index) const override;

  /// Get an \a HTRBlock from its block id.
  ///
  /// \param[in] block_id
  ///     The id of the block to retrieve.
  ///
  /// \return
  ///     The \a HTRBlock with the specified id, nullptr if no there is no block
  ///     in the layer with the specified block id.
  HTRBlock const *GetBlockById(size_t block_id) const;

  /// Get the block ID trace for this layer.
  /// This block ID trace stores the block ID of each block that occured in the
  /// trace and the block defs map maps block ID to the corresponding \a
  /// HTRBlock.
  ///
  /// \return
  ///     The block ID trace for this layer.
  llvm::ArrayRef<size_t> GetBlockIdTrace() const;

  /// Appends a new block to the layer.
  ///
  /// \param[in] block_id
  ///     The block id of the new block.
  ///
  /// \param[in] block
  ///     The new \a HTRBlock to be appended to the layer. This block is moved
  ///     into the layer.
  void AppendNewBlock(size_t block_id, HTRBlock &&block);

  /// Appends a repeated block to the layer.
  ///
  /// \param[in] block_id
  ///     The block id of the repeated block.
  void AppendRepeatedBlock(size_t block_id);

private:
  /// Maps a unique Block ID to the corresponding HTRBlock
  std::unordered_map<size_t, HTRBlock> m_block_defs;
  /// Reduce memory footprint by just storing a trace of block IDs and use
  /// m_block_defs to map a block_id to its corresponding HTRBlock
  std::vector<size_t> m_block_id_trace;
};

typedef std::unique_ptr<lldb_private::HTRBlockLayer> HTRBlockLayerUP;
typedef std::unique_ptr<lldb_private::HTRInstructionLayer>
    HTRInstructionLayerUP;

/// Top-level HTR class
/// See lldb/docs/htr.rst for comprehensive HTR documentation
class TraceHTR {

public:
  /// Constructor for a trace's HTR.
  ///
  /// \param[in] thread
  ///     The thread the trace belongs to.
  ///
  /// \param[in] cursor
  ///     The trace cursor that gives access to the trace's contents.
  TraceHTR(Thread &thread, TraceCursor &cursor);

  /// Executes passes on the HTR layers until no further
  /// summarization/compression is achieved
  void ExecutePasses();

  /// Export HTR layers to the specified format and outfile.
  ///
  /// \param[in] outfile
  ///     The file that the exported HTR data will be written to.
  ///
  /// \return
  ///     Success if the export is successful, Error otherwise.
  llvm::Error Export(std::string outfile);

  /// Get the block layers of this HTR.
  ///
  /// \return
  ///     The block layers of this HTR.
  llvm::ArrayRef<HTRBlockLayerUP> GetBlockLayers() const;

  /// Get the instruction layer of this HTR.
  ///
  /// \return
  ///     The instruction layer of this HTR.
  HTRInstructionLayer const &GetInstructionLayer() const;

  /// Add a new block layer to this HTR.
  ///
  /// \param[in]
  ///     The new block layer to be added.
  void AddNewBlockLayer(HTRBlockLayerUP &&block_layer);

private:
  // There is a single instruction layer per HTR
  HTRInstructionLayerUP m_instruction_layer_up;
  // There are one or more block layers per HTR
  std::vector<HTRBlockLayerUP> m_block_layer_ups;
};

// Serialization functions for exporting HTR to Chrome Trace Format
llvm::json::Value toJSON(const TraceHTR &htr);
llvm::json::Value toJSON(const HTRBlock &block);
llvm::json::Value toJSON(const HTRBlockMetadata &metadata);

/// The HTR passes are defined below:

/// Creates a new layer by merging the "basic super blocks" in the current layer
///
/// A "basic super block" is the longest sequence of blocks that always occur in
/// the same order. (The concept is akin to “Basic Block" in compiler theory,
/// but refers to dynamic occurrences rather than CFG nodes)
///
/// Procedure to find all basic super blocks:
//
///   - For each block, compute the number of distinct predecessor and
///   successor blocks.
///       Predecessor - the block that occurs directly before (to the left of)
///       the current block Successor  - the block that occurs directly after
///       (to the right of) the current block
///   - A block with more than one distinct successor is always the start of a
///   super block, the super block will continue until the next block with
///   more than one distinct predecessor or successor.
///
/// The implementation makes use of two terms - 'heads' and 'tails' known as
/// the 'endpoints' of a basic super block:
///   A 'head' is defined to be a block in the trace that doesn't have a
///   unique predecessor
///   A 'tail' is defined to be a block in the trace that doesn't have a
///   unique successor
///
/// A basic super block is defined to be a sequence of blocks between two
/// endpoints
///
/// A head represents the start of the next group, so the current group
/// ends at the block preceding the head and the next group begins with
/// this head block
///
/// A tail represents the end of the current group, so the current group
/// ends with the tail block and the next group begins with the
/// following block.
///
/// See lldb/docs/htr.rst for comprehensive HTR documentation
///
/// \param[in] layer
///     The layer to execute the pass on.
///
/// \return
///     A new layer instance representing the merge of blocks in the
///     previous layer
HTRBlockLayerUP BasicSuperBlockMerge(IHTRLayer &layer);

} // namespace lldb_private

#endif // LLDB_TARGET_TRACE_HTR_H
