1//===- subzero/src/IceTimerTree.h - Pass timer defs -------------*- C++ -*-===//
2//
3//                        The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Declares the TimerTree class, which allows flat and cumulative
12/// execution time collection of call chains.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICETIMERTREE_H
17#define SUBZERO_SRC_ICETIMERTREE_H
18
19// TODO(jpp): Refactor IceDefs.
20#include "IceDefs.h"
21#include "IceTimerTree.def"
22
23namespace Ice {
24
25class TimerStack {
26  TimerStack() = delete;
27  TimerStack &operator=(const TimerStack &) = delete;
28
29  /// Timer tree index type. A variable of this type is used to access an
30  /// interior, not-necessarily-leaf node of the tree.
31  using TTindex = std::vector<class TimerTreeNode>::size_type;
32  /// Representation of a path of leaf values leading to a particular node. The
33  /// representation happens to be in "reverse" order, i.e. from leaf/interior
34  /// to root, for implementation efficiency.
35  using PathType = llvm::SmallVector<TTindex, 8>;
36  /// Representation of a mapping of leaf node indexes from one timer stack to
37  /// another.
38  using TranslationType = std::vector<TimerIdT>;
39
40  /// TimerTreeNode represents an interior or leaf node in the call tree. It
41  /// contains a list of children, a pointer to its parent, and the timer ID for
42  /// the node. It also holds the cumulative time spent at this node and below.
43  /// The children are always at a higher index in the TimerTreeNode::Nodes
44  /// array, and the parent is always at a lower index.
45  class TimerTreeNode {
46    TimerTreeNode &operator=(const TimerTreeNode &) = delete;
47
48  public:
49    TimerTreeNode() = default;
50    TimerTreeNode(const TimerTreeNode &) = default;
51    std::vector<TTindex> Children; // indexed by TimerIdT
52    TTindex Parent = 0;
53    TimerIdT Interior = 0;
54    double Time = 0;
55    size_t UpdateCount = 0;
56  };
57
58public:
59  enum TimerTag {
60#define X(tag) TT_##tag,
61    TIMERTREE_TABLE
62#undef X
63        TT__num
64  };
65  explicit TimerStack(const std::string &Name);
66  TimerStack(const TimerStack &) = default;
67  TimerIdT getTimerID(const std::string &Name);
68  void mergeFrom(const TimerStack &Src);
69  void setName(const std::string &NewName) { Name = NewName; }
70  const std::string &getName() const { return Name; }
71  void push(TimerIdT ID);
72  void pop(TimerIdT ID);
73  void reset();
74  void dump(Ostream &Str, bool DumpCumulative);
75
76private:
77  void update(bool UpdateCounts);
78  static double timestamp();
79  TranslationType translateIDsFrom(const TimerStack &Src);
80  PathType getPath(TTindex Index, const TranslationType &Mapping) const;
81  TTindex getChildIndex(TTindex Parent, TimerIdT ID);
82  TTindex findPath(const PathType &Path);
83  std::string Name;
84  double FirstTimestamp;
85  double LastTimestamp;
86  uint64_t StateChangeCount = 0;
87  /// IDsIndex maps a symbolic timer name to its integer ID.
88  std::map<std::string, TimerIdT> IDsIndex;
89  std::vector<std::string> IDs;     /// indexed by TimerIdT
90  std::vector<TimerTreeNode> Nodes; /// indexed by TTindex
91  std::vector<double> LeafTimes;    /// indexed by TimerIdT
92  std::vector<size_t> LeafCounts;   /// indexed by TimerIdT
93  TTindex StackTop = 0;
94};
95
96} // end of namespace Ice
97
98#endif // SUBZERO_SRC_ICETIMERTREE_H
99