1349cc55cSDimitry Andric //===-- TraceHTR.h --------------------------------------------------------===// 2349cc55cSDimitry Andric // 3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6349cc55cSDimitry Andric // 7349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8349cc55cSDimitry Andric 9349cc55cSDimitry Andric #ifndef LLDB_TARGET_TRACE_HTR_H 10349cc55cSDimitry Andric #define LLDB_TARGET_TRACE_HTR_H 11349cc55cSDimitry Andric 12349cc55cSDimitry Andric #include "lldb/Target/Thread.h" 13349cc55cSDimitry Andric #include "lldb/Target/Trace.h" 14349cc55cSDimitry Andric 15bdd1243dSDimitry Andric #include <optional> 16349cc55cSDimitry Andric #include <unordered_map> 17349cc55cSDimitry Andric #include <unordered_set> 18349cc55cSDimitry Andric 19349cc55cSDimitry Andric namespace lldb_private { 20349cc55cSDimitry Andric 21349cc55cSDimitry Andric /// Metadata associated with an HTR block 22349cc55cSDimitry Andric /// See lldb/docs/htr.rst for comprehensive HTR documentation 23349cc55cSDimitry Andric class HTRBlockMetadata { 24349cc55cSDimitry Andric public: 25349cc55cSDimitry Andric /// Constructor for a block's metadata. 26349cc55cSDimitry Andric /// 27349cc55cSDimitry Andric /// \param[in] first_instruction_load_address 28349cc55cSDimitry Andric /// The load address of the block's first instruction. 29349cc55cSDimitry Andric /// 30349cc55cSDimitry Andric /// \param[in] num_instructions 31349cc55cSDimitry Andric /// The total number of instructions in the block. 32349cc55cSDimitry Andric /// 33349cc55cSDimitry Andric /// \param[in] func_calls 34349cc55cSDimitry Andric /// The map of a function name to the number of times it is called from 35349cc55cSDimitry Andric /// the block. HTRBlockMetadata(lldb::addr_t first_instruction_load_address,size_t num_instructions,llvm::DenseMap<ConstString,size_t> && func_calls)36349cc55cSDimitry Andric HTRBlockMetadata(lldb::addr_t first_instruction_load_address, 37349cc55cSDimitry Andric size_t num_instructions, 38349cc55cSDimitry Andric llvm::DenseMap<ConstString, size_t> &&func_calls) 39349cc55cSDimitry Andric : m_first_instruction_load_address(first_instruction_load_address), 40349cc55cSDimitry Andric m_num_instructions(num_instructions), m_func_calls(func_calls) {} 41349cc55cSDimitry Andric 42349cc55cSDimitry Andric /// Merge two \a HTRBlockMetadata in place. 43349cc55cSDimitry Andric /// 44349cc55cSDimitry Andric /// \param[in][out] merged_metadata 45349cc55cSDimitry Andric /// Metadata that metadata_to_merge will be merged into. 46349cc55cSDimitry Andric /// 47349cc55cSDimitry Andric /// \param[in] metadata_to_merge 48349cc55cSDimitry Andric /// Metadata to merge into merged_metadata. 49349cc55cSDimitry Andric static void MergeMetadata(HTRBlockMetadata &merged_metadata, 50349cc55cSDimitry Andric HTRBlockMetadata const &metadata_to_merge); 51349cc55cSDimitry Andric /// Get the number of instructions in the block. 52349cc55cSDimitry Andric /// 53349cc55cSDimitry Andric /// \return 54349cc55cSDimitry Andric /// The number of instructions in the block. 55349cc55cSDimitry Andric size_t GetNumInstructions() const; 56349cc55cSDimitry Andric 57349cc55cSDimitry Andric /// Get the name of the most frequently called function from the block. 58349cc55cSDimitry Andric /// 59349cc55cSDimitry Andric /// \return 60349cc55cSDimitry Andric /// The name of the function that is called the most from this block or 61bdd1243dSDimitry Andric /// std::nullopt if no function is called from this block. 62bdd1243dSDimitry Andric std::optional<llvm::StringRef> GetMostFrequentlyCalledFunction() const; 63349cc55cSDimitry Andric 64349cc55cSDimitry Andric /// Get the load address of the first instruction in the block. 65349cc55cSDimitry Andric /// 66349cc55cSDimitry Andric /// \return 67349cc55cSDimitry Andric /// The load address of the first instruction in the block. 68349cc55cSDimitry Andric lldb::addr_t GetFirstInstructionLoadAddress() const; 69349cc55cSDimitry Andric 70349cc55cSDimitry Andric /// Get the function calls map for the block. 71349cc55cSDimitry Andric /// Function calls are identified in the instruction layer by finding 'call' 72349cc55cSDimitry Andric /// instructions and determining the function they are calling. As these 73349cc55cSDimitry Andric /// instructions are merged into blocks, we merge these different function 74349cc55cSDimitry Andric /// calls into a single map containing the function names to the number of 75349cc55cSDimitry Andric /// times it is called from this block. 76349cc55cSDimitry Andric /// 77349cc55cSDimitry Andric /// \return 78349cc55cSDimitry Andric /// The mapping of function name to the number of times it is called from 79349cc55cSDimitry Andric /// this block. 80349cc55cSDimitry Andric llvm::DenseMap<ConstString, size_t> const &GetFunctionCalls() const; 81349cc55cSDimitry Andric 82349cc55cSDimitry Andric private: 83349cc55cSDimitry Andric lldb::addr_t m_first_instruction_load_address; 84349cc55cSDimitry Andric size_t m_num_instructions; 85349cc55cSDimitry Andric llvm::DenseMap<ConstString, size_t> m_func_calls; 86349cc55cSDimitry Andric }; 87349cc55cSDimitry Andric 88349cc55cSDimitry Andric /// Block structure representing a sequence of trace "units" (ie instructions). 89349cc55cSDimitry Andric /// Sequences of blocks are merged to create a new, single block 90349cc55cSDimitry Andric /// See lldb/docs/htr.rst for comprehensive HTR documentation 91349cc55cSDimitry Andric class HTRBlock { 92349cc55cSDimitry Andric public: 93349cc55cSDimitry Andric /// Constructor for a block of an HTR layer. 94349cc55cSDimitry Andric /// 95349cc55cSDimitry Andric /// \param[in] offset 96349cc55cSDimitry Andric /// The offset of the start of this block in the previous layer. 97349cc55cSDimitry Andric /// 98349cc55cSDimitry Andric /// \param[in] size 99349cc55cSDimitry Andric /// Number of blocks/instructions that make up this block in the previous 100349cc55cSDimitry Andric /// layer. 101349cc55cSDimitry Andric /// 102349cc55cSDimitry Andric /// \param[in] metadata 103349cc55cSDimitry Andric /// General metadata for this block. HTRBlock(size_t offset,size_t size,HTRBlockMetadata metadata)104349cc55cSDimitry Andric HTRBlock(size_t offset, size_t size, HTRBlockMetadata metadata) 105349cc55cSDimitry Andric : m_offset(offset), m_size(size), m_metadata(metadata) {} 106349cc55cSDimitry Andric 107349cc55cSDimitry Andric /// Get the offset of the start of this block in the previous layer. 108349cc55cSDimitry Andric /// 109349cc55cSDimitry Andric /// \return 110349cc55cSDimitry Andric /// The offset of the block. 111349cc55cSDimitry Andric size_t GetOffset() const; 112349cc55cSDimitry Andric 113349cc55cSDimitry Andric /// Get the number of blocks/instructions that make up this block in the 114349cc55cSDimitry Andric /// previous layer. 115349cc55cSDimitry Andric /// 116349cc55cSDimitry Andric /// \return 117349cc55cSDimitry Andric /// The size of the block. 118349cc55cSDimitry Andric size_t GetSize() const; 119349cc55cSDimitry Andric 120349cc55cSDimitry Andric /// Get the metadata for this block. 121349cc55cSDimitry Andric /// 122349cc55cSDimitry Andric /// \return 123349cc55cSDimitry Andric /// The metadata of the block. 124349cc55cSDimitry Andric HTRBlockMetadata const &GetMetadata() const; 125349cc55cSDimitry Andric 126349cc55cSDimitry Andric private: 127349cc55cSDimitry Andric /// Offset in the previous layer 128349cc55cSDimitry Andric size_t m_offset; 129349cc55cSDimitry Andric /// Number of blocks/instructions that make up this block in the previous 130349cc55cSDimitry Andric /// layer 131349cc55cSDimitry Andric size_t m_size; 132349cc55cSDimitry Andric /// General metadata for this block 133349cc55cSDimitry Andric HTRBlockMetadata m_metadata; 134349cc55cSDimitry Andric }; 135349cc55cSDimitry Andric 136349cc55cSDimitry Andric /// HTR layer interface 137349cc55cSDimitry Andric /// See lldb/docs/htr.rst for comprehensive HTR documentation 138349cc55cSDimitry Andric class IHTRLayer { 139349cc55cSDimitry Andric public: 140349cc55cSDimitry Andric /// Construct new HTR layer. 141349cc55cSDimitry Andric // 142349cc55cSDimitry Andric /// \param[in] id 143349cc55cSDimitry Andric /// The layer's id. IHTRLayer(size_t id)144349cc55cSDimitry Andric IHTRLayer(size_t id) : m_layer_id(id) {} 145349cc55cSDimitry Andric 146349cc55cSDimitry Andric /// Get the ID of the layer. 147349cc55cSDimitry Andric /// 148349cc55cSDimitry Andric /// \return 149349cc55cSDimitry Andric /// The layer ID of this layer. 150349cc55cSDimitry Andric size_t GetLayerId() const; 151349cc55cSDimitry Andric 152349cc55cSDimitry Andric /// Get the metadata of a unit (instruction or block) in the layer. 153349cc55cSDimitry Andric /// 154349cc55cSDimitry Andric /// \param[in] index 155349cc55cSDimitry Andric /// The position of the unit in the layer. 156349cc55cSDimitry Andric /// 157349cc55cSDimitry Andric /// \return 158349cc55cSDimitry Andric /// The metadata of the unit in the layer. 159349cc55cSDimitry Andric virtual HTRBlockMetadata GetMetadataByIndex(size_t index) const = 0; 160349cc55cSDimitry Andric 161349cc55cSDimitry Andric /// Get the total number of units (instruction or block) in this layer. 162349cc55cSDimitry Andric /// 163349cc55cSDimitry Andric /// \return 164349cc55cSDimitry Andric /// The total number of units in the layer. 165349cc55cSDimitry Andric virtual size_t GetNumUnits() const = 0; 166349cc55cSDimitry Andric 167349cc55cSDimitry Andric /// Creates a new block from the result of merging a contiguous sequence of 168349cc55cSDimitry Andric /// "units" (instructions or blocks depending on layer type) in this layer 169349cc55cSDimitry Andric /// This allows the implementation class to decide how to store/generate this 170349cc55cSDimitry Andric /// metadata. For example, in the case of the instruction layer we want to 171349cc55cSDimitry Andric /// lazily generate this metadata instead of storing it for each instruction. 172349cc55cSDimitry Andric /// 173349cc55cSDimitry Andric /// \param[in] start_unit_index 174349cc55cSDimitry Andric /// The index of the first unit to be merged. 175349cc55cSDimitry Andric /// 176349cc55cSDimitry Andric /// \param[in] num_units 177349cc55cSDimitry Andric /// The number of units to be merged. Must be >= 1, since merging 0 blocks 178349cc55cSDimitry Andric /// does not make sense. 179349cc55cSDimitry Andric /// 180349cc55cSDimitry Andric /// \return 181349cc55cSDimitry Andric /// A new block instance representing the merge of the specified units. 182349cc55cSDimitry Andric HTRBlock MergeUnits(size_t start_unit_index, size_t num_units); 183349cc55cSDimitry Andric 184349cc55cSDimitry Andric virtual ~IHTRLayer() = default; 185349cc55cSDimitry Andric 186349cc55cSDimitry Andric protected: 187349cc55cSDimitry Andric /// ID of the layer. 188349cc55cSDimitry Andric size_t m_layer_id; 189349cc55cSDimitry Andric }; 190349cc55cSDimitry Andric 191349cc55cSDimitry Andric /// "Base" layer of HTR representing the dynamic instructions of the trace. 192349cc55cSDimitry Andric /// See lldb/docs/htr.rst for comprehensive HTR documentation 193349cc55cSDimitry Andric class HTRInstructionLayer : public IHTRLayer { 194349cc55cSDimitry Andric public: 195349cc55cSDimitry Andric /// Construct new instruction layer. 196349cc55cSDimitry Andric // 197349cc55cSDimitry Andric /// \param[in] id 198349cc55cSDimitry Andric /// The layer's id. HTRInstructionLayer(size_t id)199349cc55cSDimitry Andric HTRInstructionLayer(size_t id) : IHTRLayer(id) {} 200349cc55cSDimitry Andric 201349cc55cSDimitry Andric size_t GetNumUnits() const override; 202349cc55cSDimitry Andric 203349cc55cSDimitry Andric HTRBlockMetadata GetMetadataByIndex(size_t index) const override; 204349cc55cSDimitry Andric 205349cc55cSDimitry Andric /// Get the dynamic instruction trace. 206349cc55cSDimitry Andric /// 207349cc55cSDimitry Andric /// \return 208349cc55cSDimitry Andric /// The dynamic instruction trace. 209349cc55cSDimitry Andric llvm::ArrayRef<lldb::addr_t> GetInstructionTrace() const; 210349cc55cSDimitry Andric 211349cc55cSDimitry Andric /// Add metadata for a 'call' instruction of the trace. 212349cc55cSDimitry Andric /// 213349cc55cSDimitry Andric /// \param[in] load_addr 214349cc55cSDimitry Andric /// The load address of the 'call' instruction. 215349cc55cSDimitry Andric /// 216349cc55cSDimitry Andric /// \param[in] func_name 217349cc55cSDimitry Andric /// The name of the function the 'call' instruction is calling if it can 218*06c3fb27SDimitry Andric /// be determined, std::nullopt otherwise. 219349cc55cSDimitry Andric void AddCallInstructionMetadata(lldb::addr_t load_addr, 220bdd1243dSDimitry Andric std::optional<ConstString> func_name); 221349cc55cSDimitry Andric 222349cc55cSDimitry Andric /// Append the load address of an instruction to the dynamic instruction 223349cc55cSDimitry Andric /// trace. 224349cc55cSDimitry Andric /// 225349cc55cSDimitry Andric /// \param[in] load_addr 226349cc55cSDimitry Andric /// The load address of the instruction. 227349cc55cSDimitry Andric void AppendInstruction(lldb::addr_t load_addr); 228349cc55cSDimitry Andric 229349cc55cSDimitry Andric private: 230349cc55cSDimitry Andric // Dynamic instructions of trace are stored in chronological order. 231349cc55cSDimitry Andric std::vector<lldb::addr_t> m_instruction_trace; 232349cc55cSDimitry Andric // Only store metadata for instructions of interest (call instructions) 233349cc55cSDimitry Andric // If we stored metadata for each instruction this would be wasteful since 234349cc55cSDimitry Andric // most instructions don't contain useful metadata 235349cc55cSDimitry Andric 236349cc55cSDimitry Andric // This map contains the load address of all the call instructions. 237bdd1243dSDimitry Andric // load address maps to the name of the function it calls (std::nullopt if 238bdd1243dSDimitry Andric // function name can't be determined) 239bdd1243dSDimitry Andric std::unordered_map<lldb::addr_t, std::optional<ConstString>> m_call_isns; 240349cc55cSDimitry Andric }; 241349cc55cSDimitry Andric 242349cc55cSDimitry Andric /// HTR layer composed of blocks of the trace. 243349cc55cSDimitry Andric /// See lldb/docs/htr.rst for comprehensive HTR documentation 244349cc55cSDimitry Andric class HTRBlockLayer : public IHTRLayer { 245349cc55cSDimitry Andric public: 246349cc55cSDimitry Andric /// Construct new block layer. 247349cc55cSDimitry Andric // 248349cc55cSDimitry Andric /// \param[in] id 249349cc55cSDimitry Andric /// The layer's id. HTRBlockLayer(size_t id)250349cc55cSDimitry Andric HTRBlockLayer(size_t id) : IHTRLayer(id) {} 251349cc55cSDimitry Andric 252349cc55cSDimitry Andric size_t GetNumUnits() const override; 253349cc55cSDimitry Andric 254349cc55cSDimitry Andric HTRBlockMetadata GetMetadataByIndex(size_t index) const override; 255349cc55cSDimitry Andric 256349cc55cSDimitry Andric /// Get an \a HTRBlock from its block id. 257349cc55cSDimitry Andric /// 258349cc55cSDimitry Andric /// \param[in] block_id 259349cc55cSDimitry Andric /// The id of the block to retrieve. 260349cc55cSDimitry Andric /// 261349cc55cSDimitry Andric /// \return 262349cc55cSDimitry Andric /// The \a HTRBlock with the specified id, nullptr if no there is no block 263349cc55cSDimitry Andric /// in the layer with the specified block id. 264349cc55cSDimitry Andric HTRBlock const *GetBlockById(size_t block_id) const; 265349cc55cSDimitry Andric 266349cc55cSDimitry Andric /// Get the block ID trace for this layer. 267349cc55cSDimitry Andric /// This block ID trace stores the block ID of each block that occured in the 268349cc55cSDimitry Andric /// trace and the block defs map maps block ID to the corresponding \a 269349cc55cSDimitry Andric /// HTRBlock. 270349cc55cSDimitry Andric /// 271349cc55cSDimitry Andric /// \return 272349cc55cSDimitry Andric /// The block ID trace for this layer. 273349cc55cSDimitry Andric llvm::ArrayRef<size_t> GetBlockIdTrace() const; 274349cc55cSDimitry Andric 275349cc55cSDimitry Andric /// Appends a new block to the layer. 276349cc55cSDimitry Andric /// 277349cc55cSDimitry Andric /// \param[in] block_id 278349cc55cSDimitry Andric /// The block id of the new block. 279349cc55cSDimitry Andric /// 280349cc55cSDimitry Andric /// \param[in] block 281349cc55cSDimitry Andric /// The new \a HTRBlock to be appended to the layer. This block is moved 282349cc55cSDimitry Andric /// into the layer. 283349cc55cSDimitry Andric void AppendNewBlock(size_t block_id, HTRBlock &&block); 284349cc55cSDimitry Andric 285349cc55cSDimitry Andric /// Appends a repeated block to the layer. 286349cc55cSDimitry Andric /// 287349cc55cSDimitry Andric /// \param[in] block_id 288349cc55cSDimitry Andric /// The block id of the repeated block. 289349cc55cSDimitry Andric void AppendRepeatedBlock(size_t block_id); 290349cc55cSDimitry Andric 291349cc55cSDimitry Andric private: 292349cc55cSDimitry Andric /// Maps a unique Block ID to the corresponding HTRBlock 293349cc55cSDimitry Andric std::unordered_map<size_t, HTRBlock> m_block_defs; 294349cc55cSDimitry Andric /// Reduce memory footprint by just storing a trace of block IDs and use 295349cc55cSDimitry Andric /// m_block_defs to map a block_id to its corresponding HTRBlock 296349cc55cSDimitry Andric std::vector<size_t> m_block_id_trace; 297349cc55cSDimitry Andric }; 298349cc55cSDimitry Andric 299349cc55cSDimitry Andric typedef std::unique_ptr<lldb_private::HTRBlockLayer> HTRBlockLayerUP; 300349cc55cSDimitry Andric typedef std::unique_ptr<lldb_private::HTRInstructionLayer> 301349cc55cSDimitry Andric HTRInstructionLayerUP; 302349cc55cSDimitry Andric 303349cc55cSDimitry Andric /// Top-level HTR class 304349cc55cSDimitry Andric /// See lldb/docs/htr.rst for comprehensive HTR documentation 305349cc55cSDimitry Andric class TraceHTR { 306349cc55cSDimitry Andric 307349cc55cSDimitry Andric public: 308349cc55cSDimitry Andric /// Constructor for a trace's HTR. 309349cc55cSDimitry Andric /// 310349cc55cSDimitry Andric /// \param[in] thread 311349cc55cSDimitry Andric /// The thread the trace belongs to. 312349cc55cSDimitry Andric /// 313349cc55cSDimitry Andric /// \param[in] cursor 314349cc55cSDimitry Andric /// The trace cursor that gives access to the trace's contents. 315349cc55cSDimitry Andric TraceHTR(Thread &thread, TraceCursor &cursor); 316349cc55cSDimitry Andric 317349cc55cSDimitry Andric /// Executes passes on the HTR layers until no further 318349cc55cSDimitry Andric /// summarization/compression is achieved 319349cc55cSDimitry Andric void ExecutePasses(); 320349cc55cSDimitry Andric 321349cc55cSDimitry Andric /// Export HTR layers to the specified format and outfile. 322349cc55cSDimitry Andric /// 323349cc55cSDimitry Andric /// \param[in] outfile 324349cc55cSDimitry Andric /// The file that the exported HTR data will be written to. 325349cc55cSDimitry Andric /// 326349cc55cSDimitry Andric /// \return 327349cc55cSDimitry Andric /// Success if the export is successful, Error otherwise. 328349cc55cSDimitry Andric llvm::Error Export(std::string outfile); 329349cc55cSDimitry Andric 330349cc55cSDimitry Andric /// Get the block layers of this HTR. 331349cc55cSDimitry Andric /// 332349cc55cSDimitry Andric /// \return 333349cc55cSDimitry Andric /// The block layers of this HTR. 334349cc55cSDimitry Andric llvm::ArrayRef<HTRBlockLayerUP> GetBlockLayers() const; 335349cc55cSDimitry Andric 336349cc55cSDimitry Andric /// Get the instruction layer of this HTR. 337349cc55cSDimitry Andric /// 338349cc55cSDimitry Andric /// \return 339349cc55cSDimitry Andric /// The instruction layer of this HTR. 340349cc55cSDimitry Andric HTRInstructionLayer const &GetInstructionLayer() const; 341349cc55cSDimitry Andric 342349cc55cSDimitry Andric /// Add a new block layer to this HTR. 343349cc55cSDimitry Andric /// 344349cc55cSDimitry Andric /// \param[in] 345349cc55cSDimitry Andric /// The new block layer to be added. 346349cc55cSDimitry Andric void AddNewBlockLayer(HTRBlockLayerUP &&block_layer); 347349cc55cSDimitry Andric 348349cc55cSDimitry Andric private: 349349cc55cSDimitry Andric // There is a single instruction layer per HTR 350349cc55cSDimitry Andric HTRInstructionLayerUP m_instruction_layer_up; 351349cc55cSDimitry Andric // There are one or more block layers per HTR 352349cc55cSDimitry Andric std::vector<HTRBlockLayerUP> m_block_layer_ups; 353349cc55cSDimitry Andric }; 354349cc55cSDimitry Andric 355349cc55cSDimitry Andric // Serialization functions for exporting HTR to Chrome Trace Format 356349cc55cSDimitry Andric llvm::json::Value toJSON(const TraceHTR &htr); 357349cc55cSDimitry Andric llvm::json::Value toJSON(const HTRBlock &block); 358349cc55cSDimitry Andric llvm::json::Value toJSON(const HTRBlockMetadata &metadata); 359349cc55cSDimitry Andric 360349cc55cSDimitry Andric /// The HTR passes are defined below: 361349cc55cSDimitry Andric 362349cc55cSDimitry Andric /// Creates a new layer by merging the "basic super blocks" in the current layer 363349cc55cSDimitry Andric /// 364349cc55cSDimitry Andric /// A "basic super block" is the longest sequence of blocks that always occur in 365349cc55cSDimitry Andric /// the same order. (The concept is akin to “Basic Block" in compiler theory, 366349cc55cSDimitry Andric /// but refers to dynamic occurrences rather than CFG nodes) 367349cc55cSDimitry Andric /// 368349cc55cSDimitry Andric /// Procedure to find all basic super blocks: 369349cc55cSDimitry Andric // 370349cc55cSDimitry Andric /// - For each block, compute the number of distinct predecessor and 371349cc55cSDimitry Andric /// successor blocks. 372349cc55cSDimitry Andric /// Predecessor - the block that occurs directly before (to the left of) 373349cc55cSDimitry Andric /// the current block Successor - the block that occurs directly after 374349cc55cSDimitry Andric /// (to the right of) the current block 375349cc55cSDimitry Andric /// - A block with more than one distinct successor is always the start of a 376349cc55cSDimitry Andric /// super block, the super block will continue until the next block with 377349cc55cSDimitry Andric /// more than one distinct predecessor or successor. 378349cc55cSDimitry Andric /// 379349cc55cSDimitry Andric /// The implementation makes use of two terms - 'heads' and 'tails' known as 380349cc55cSDimitry Andric /// the 'endpoints' of a basic super block: 381349cc55cSDimitry Andric /// A 'head' is defined to be a block in the trace that doesn't have a 382349cc55cSDimitry Andric /// unique predecessor 383349cc55cSDimitry Andric /// A 'tail' is defined to be a block in the trace that doesn't have a 384349cc55cSDimitry Andric /// unique successor 385349cc55cSDimitry Andric /// 386349cc55cSDimitry Andric /// A basic super block is defined to be a sequence of blocks between two 387349cc55cSDimitry Andric /// endpoints 388349cc55cSDimitry Andric /// 389349cc55cSDimitry Andric /// A head represents the start of the next group, so the current group 390349cc55cSDimitry Andric /// ends at the block preceding the head and the next group begins with 391349cc55cSDimitry Andric /// this head block 392349cc55cSDimitry Andric /// 393349cc55cSDimitry Andric /// A tail represents the end of the current group, so the current group 394349cc55cSDimitry Andric /// ends with the tail block and the next group begins with the 395349cc55cSDimitry Andric /// following block. 396349cc55cSDimitry Andric /// 397349cc55cSDimitry Andric /// See lldb/docs/htr.rst for comprehensive HTR documentation 398349cc55cSDimitry Andric /// 399349cc55cSDimitry Andric /// \param[in] layer 400349cc55cSDimitry Andric /// The layer to execute the pass on. 401349cc55cSDimitry Andric /// 402349cc55cSDimitry Andric /// \return 403349cc55cSDimitry Andric /// A new layer instance representing the merge of blocks in the 404349cc55cSDimitry Andric /// previous layer 405349cc55cSDimitry Andric HTRBlockLayerUP BasicSuperBlockMerge(IHTRLayer &layer); 406349cc55cSDimitry Andric 407349cc55cSDimitry Andric } // namespace lldb_private 408349cc55cSDimitry Andric 409349cc55cSDimitry Andric #endif // LLDB_TARGET_TRACE_HTR_H 410