Trace.h revision 355940
167760Smsmith//===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- C++ -*-===//
267760Smsmith//
367760Smsmith// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
467760Smsmith// See https://llvm.org/LICENSE.txt for license information.
567760Smsmith// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
667760Smsmith//
767760Smsmith//===----------------------------------------------------------------------===//
867760Smsmith//
967760Smsmith// This class represents a single trace of LLVM basic blocks.  A trace is a
1067760Smsmith// single entry, multiple exit, region of code that is often hot.  Trace-based
1167760Smsmith// optimizations treat traces almost like they are a large, strange, basic
1267760Smsmith// block: because the trace path is assumed to be hot, optimizations for the
1367760Smsmith// fall-through path are made at the expense of the non-fall-through paths.
1467760Smsmith//
1567760Smsmith//===----------------------------------------------------------------------===//
1667760Smsmith
1767760Smsmith#ifndef LLVM_ANALYSIS_TRACE_H
1867760Smsmith#define LLVM_ANALYSIS_TRACE_H
1967760Smsmith
2067760Smsmith#include <cassert>
2167760Smsmith#include <vector>
2267760Smsmith
2367760Smsmithnamespace llvm {
2467760Smsmith
2567760Smsmithclass BasicBlock;
2667760Smsmithclass Function;
2767760Smsmithclass Module;
2867760Smsmithclass raw_ostream;
2967760Smsmith
3067760Smsmithclass Trace {
3167760Smsmith  using BasicBlockListType = std::vector<BasicBlock *>;
3267760Smsmith
3367760Smsmith  BasicBlockListType BasicBlocks;
3467760Smsmith
3567760Smsmithpublic:
3667760Smsmith  /// Trace ctor - Make a new trace from a vector of basic blocks,
3767760Smsmith  /// residing in the function which is the parent of the first
3867760Smsmith  /// basic block in the vector.
3967760Smsmith  Trace(const std::vector<BasicBlock *> &vBB) : BasicBlocks (vBB) {}
4067760Smsmith
4167760Smsmith  /// getEntryBasicBlock - Return the entry basic block (first block)
4267760Smsmith  /// of the trace.
4377432Smsmith  BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; }
4491128Smsmith
4571875Smsmith  /// operator[]/getBlock - Return basic block N in the trace.
4679000Smsmith  BasicBlock *operator[](unsigned i) const { return BasicBlocks[i]; }
4779000Smsmith  BasicBlock *getBlock(unsigned i)   const { return BasicBlocks[i]; }
4879000Smsmith
49122500Sjhb  /// getFunction - Return this trace's parent function.
50122500Sjhb  Function *getFunction () const;
5167760Smsmith
5267760Smsmith  /// getModule - Return this Module that contains this trace's parent
5367760Smsmith  /// function.
5467760Smsmith  Module *getModule () const;
5567760Smsmith
5667760Smsmith  /// getBlockIndex - Return the index of the specified basic block in the
5767760Smsmith  /// trace, or -1 if it is not in the trace.
5867760Smsmith  int getBlockIndex(const BasicBlock *X) const {
5967760Smsmith    for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
6096926Speter      if (BasicBlocks[i] == X)
6171875Smsmith        return i;
6289054Smsmith    return -1;
6379386Smsmith  }
6479386Smsmith
6579386Smsmith  /// contains - Returns true if this trace contains the given basic
6679386Smsmith  /// block.
6767760Smsmith  bool contains(const BasicBlock *X) const {
6871875Smsmith    return getBlockIndex(X) != -1;
6967760Smsmith  }
7071875Smsmith
7180335Siwasaki  /// Returns true if B1 occurs before B2 in the trace, or if it is the same
7279000Smsmith  /// block as B2..  Both blocks must be in the trace.
7379000Smsmith  bool dominates(const BasicBlock *B1, const BasicBlock *B2) const {
7479000Smsmith    int B1Idx = getBlockIndex(B1), B2Idx = getBlockIndex(B2);
7579000Smsmith    assert(B1Idx != -1 && B2Idx != -1 && "Block is not in the trace!");
7667760Smsmith    return B1Idx <= B2Idx;
7767760Smsmith  }
7867760Smsmith
7967760Smsmith  // BasicBlock iterators...
8067760Smsmith  using iterator = BasicBlockListType::iterator;
8167760Smsmith  using const_iterator = BasicBlockListType::const_iterator;
8267760Smsmith  using reverse_iterator = std::reverse_iterator<iterator>;
8387036Smsmith  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
8467760Smsmith
8567760Smsmith  iterator                begin()       { return BasicBlocks.begin(); }
86122500Sjhb  const_iterator          begin() const { return BasicBlocks.begin(); }
87122500Sjhb  iterator                end  ()       { return BasicBlocks.end();   }
88122500Sjhb  const_iterator          end  () const { return BasicBlocks.end();   }
89122500Sjhb
90122500Sjhb  reverse_iterator       rbegin()       { return BasicBlocks.rbegin(); }
91122500Sjhb  const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
9267760Smsmith  reverse_iterator       rend  ()       { return BasicBlocks.rend();   }
9367760Smsmith  const_reverse_iterator rend  () const { return BasicBlocks.rend();   }
9467760Smsmith
9567760Smsmith  unsigned                 size() const { return BasicBlocks.size(); }
9687036Smsmith  bool                    empty() const { return BasicBlocks.empty(); }
9767760Smsmith
9879000Smsmith  iterator erase(iterator q)               { return BasicBlocks.erase (q); }
9979000Smsmith  iterator erase(iterator q1, iterator q2) { return BasicBlocks.erase (q1, q2); }
10067760Smsmith
10187036Smsmith  /// print - Write trace to output stream.
10267760Smsmith  void print(raw_ostream &O) const;
10367760Smsmith
10471875Smsmith  /// dump - Debugger convenience method; writes trace to standard error
10567760Smsmith  /// output stream.
10667760Smsmith  void dump() const;
10767760Smsmith};
10867760Smsmith
10967760Smsmith} // end namespace llvm
11067760Smsmith
11167760Smsmith#endif // LLVM_ANALYSIS_TRACE_H
11296926Speter