Jlm
Statistics.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Nico Reißmann <nico.reissmann@gmail.com>
3  * Copyright 2024 Håvard Krogstie <krogstie.havard@gmail.com>
4  * See COPYING for terms of redistribution.
5  */
6 
8 
10 #include <jlm/util/strfmt.hpp>
11 
12 #include <string_view>
13 
14 namespace jlm::util
15 {
16 // Mapping between each statistics id and identifier used when serializing the statistic
17 static const util::BijectiveMap<Statistics::Id, std::string_view> &
19 {
21  { Statistics::Id::Aggregation, "Aggregation" },
22  { Statistics::Id::AgnosticModRefSummarizer, "AgnosticModRefSummarizer" },
23  { Statistics::Id::AliasAnalysisPrecisionEvaluation, "AliasAnalysisPrecisionEvaluation" },
24  { Statistics::Id::AndersenAnalysis, "AndersenAnalysis" },
25  { Statistics::Id::Annotation, "Annotation" },
27  { Statistics::Id::ControlFlowRecovery, "ControlFlowRestructuring" },
28  { Statistics::Id::DataNodeToDelta, "DataNodeToDeltaStatistics" },
29  { Statistics::Id::DeadNodeElimination, "DeadNodeElimination" },
31  { Statistics::Id::IfConversion, "IfConversion" },
32  { Statistics::Id::JlmToRvsdgConversion, "ControlFlowGraphToLambda" },
33  { Statistics::Id::LoopUnrolling, "UNROLL" },
34  { Statistics::Id::LoopUnswitching, "LoopUnswitching" },
35  { Statistics::Id::InvariantValueRedirection, "InvariantValueRedirection" },
36  { Statistics::Id::MemoryStateEncoder, "MemoryStateEncoder" },
37  { Statistics::Id::PullNodes, "PULL" },
38  { Statistics::Id::PushNodes, "PUSH" },
39  { Statistics::Id::ReduceNodes, "RED" },
40  { Statistics::Id::RegionAwareModRefSummarizer, "RegionAwareModRefSummarizer" },
41  { Statistics::Id::RvsdgConstruction, "InterProceduralGraphToRvsdg" },
42  { Statistics::Id::RvsdgDestruction, "RVSDGDESTRUCTION" },
43  { Statistics::Id::RvsdgOptimization, "RVSDGOPTIMIZATION" },
44  { Statistics::Id::RvsdgTreePrinter, "RvsdgTreePrinter" },
45  { Statistics::Id::ScalarEvolution, "ScalarEvolution" },
46  };
47  // Make sure every Statistic is mentioned in the mapping
48  auto lastIdx = static_cast<size_t>(Statistics::Id::LastEnumValue);
49  auto firstIdx = static_cast<size_t>(Statistics::Id::FirstEnumValue);
50  JLM_ASSERT(mapping.Size() == lastIdx - firstIdx - 1);
51  return mapping;
52 }
53 
54 Statistics::~Statistics() = default;
55 
56 std::string_view
58 {
59  return GetStatisticsIdNames().LookupKey(StatisticsId_);
60 }
61 
62 const util::FilePath &
64 {
65  return SourceFile_;
66 }
67 
68 std::string
69 Statistics::Serialize(char fieldSeparator, char nameValueSeparator) const
70 {
71  std::ostringstream ss;
72 
73  ss << GetName() << fieldSeparator;
74  ss << GetSourceFile().to_str();
75 
76  for (const auto & [mName, measurement] : Measurements_)
77  {
78  if (ss.tellp() != 0)
79  ss << fieldSeparator;
80 
81  ss << mName << nameValueSeparator;
82  std::visit(
83  [&](const auto & value)
84  {
85  ss << value;
86  },
87  measurement);
88  }
89  for (const auto & [mName, timer] : Timers_)
90  {
91  if (ss.tellp() != 0)
92  ss << fieldSeparator;
93 
94  ss << mName << "[ns]" << nameValueSeparator << timer.ns();
95  }
96 
97  return ss.str();
98 }
99 
100 bool
101 Statistics::HasMeasurement(const std::string & name) const noexcept
102 {
103  for (const auto & [mName, _] : Measurements_)
104  if (mName == name)
105  return true;
106  return false;
107 }
108 
110 Statistics::GetMeasurement(const std::string & name) const
111 {
112  for (const auto & [mName, measurement] : Measurements_)
113  if (mName == name)
114  return measurement;
115  JLM_UNREACHABLE("Unknown measurement");
116 }
117 
120 {
121  return { Measurements_.begin(), Measurements_.end() };
122 }
123 
124 bool
125 Statistics::HasTimer(const std::string & name) const noexcept
126 {
127  for (const auto & [mName, _] : Timers_)
128  if (mName == name)
129  return true;
130  return false;
131 }
132 
133 util::Timer &
134 Statistics::GetTimer(const std::string & name)
135 {
136  for (auto & [mName, timer] : Timers_)
137  if (mName == name)
138  return timer;
139  JLM_UNREACHABLE("Unknown Timer");
140 }
141 
142 const util::Timer &
143 Statistics::GetTimer(const std::string & name) const
144 {
145  return const_cast<Statistics *>(this)->GetTimer(name);
146 }
147 
150 {
151  return { Timers_.begin(), Timers_.end() };
152 }
153 
154 util::Timer &
155 Statistics::AddTimer(std::string name)
156 {
157  JLM_ASSERT(!HasTimer(name));
158  Timers_.emplace_back(std::make_pair(std::move(name), util::Timer()));
159  auto & timer = Timers_.back().second;
160  return timer;
161 }
162 
163 void
165 {
166  if (NumCollectedStatistics() == 0)
167  return;
168 
169  auto file = createOutputFile("statistics.log");
170  file.open("w");
171 
172  for (auto & statistics : CollectedStatistics())
173  {
174  fprintf(file.fd(), "%s\n", statistics.Serialize(' ', ':').c_str());
175  }
176 }
177 
178 File
179 StatisticsCollector::createOutputFile(std::string fileNameSuffix, bool includeCount)
180 {
182 
183  auto directory = Settings_.GetOrCreateOutputDirectory();
184 
185  // If the fileNameSuffix should have a count included, place it before the '.' (or at the end)
186  if (includeCount)
187  {
188  size_t count = OutputFileCounter_[fileNameSuffix]++;
189  auto firstDot = fileNameSuffix.find('.');
190  if (firstDot == std::string::npos)
191  firstDot = fileNameSuffix.size();
192 
193  fileNameSuffix =
194  strfmt(fileNameSuffix.substr(0, firstDot), "-", count, fileNameSuffix.substr(firstDot));
195  }
196 
197  std::string fileName;
198  if (!Settings_.GetModuleName().empty())
199  fileName += Settings_.GetModuleName() + "-";
200  if (!Settings_.GetUniqueString().empty())
201  fileName += Settings_.GetUniqueString() + "-";
202  fileName += fileNameSuffix;
203 
204  auto fullPath = directory.Join(fileName);
205  if (fullPath.Exists())
206  throw Error("The generated output file name already exists: " + fullPath.to_str());
207 
208  return File(fullPath);
209 }
210 
211 }
std::size_t Size() const noexcept
const std::string & to_str() const noexcept
Definition: file.hpp:275
bool HasOutputDirectory() const noexcept
Definition: Statistics.hpp:344
const std::string & GetUniqueString() const noexcept
Definition: Statistics.hpp:406
const FilePath & GetOrCreateOutputDirectory() const noexcept
Definition: Statistics.hpp:366
const std::string & GetModuleName() const noexcept
Definition: Statistics.hpp:388
void PrintStatistics()
Print collected statistics to file. If no statistics have been collected, this is a no-op.
Definition: Statistics.cpp:164
StatisticsCollectorSettings Settings_
Definition: Statistics.hpp:622
std::unordered_map< std::string, size_t > OutputFileCounter_
Definition: Statistics.hpp:626
StatisticsRange CollectedStatistics() const noexcept
Definition: Statistics.hpp:517
File createOutputFile(std::string fileNameSuffix, bool includeCount=false)
Definition: Statistics.cpp:179
size_t NumCollectedStatistics() const noexcept
Definition: Statistics.hpp:524
Statistics Interface.
Definition: Statistics.hpp:31
util::Timer & GetTimer(const std::string &name)
Definition: Statistics.cpp:134
util::FilePath SourceFile_
Definition: Statistics.hpp:245
std::string_view GetName() const
Definition: Statistics.cpp:57
const util::FilePath & GetSourceFile() const
Definition: Statistics.cpp:63
Statistics::Id StatisticsId_
Definition: Statistics.hpp:244
MeasurementList Measurements_
Definition: Statistics.hpp:247
bool HasTimer(const std::string &name) const noexcept
Definition: Statistics.cpp:125
std::string Serialize(char fieldSeparator, char nameValueSeparator) const
Definition: Statistics.cpp:69
const Measurement & GetMeasurement(const std::string &name) const
Definition: Statistics.cpp:110
util::Timer & AddTimer(std::string name)
Definition: Statistics.cpp:155
IteratorRange< MeasurementList::const_iterator > GetMeasurements() const
Definition: Statistics.cpp:119
IteratorRange< TimerList::const_iterator > GetTimers() const
Definition: Statistics.cpp:149
bool HasMeasurement(const std::string &name) const noexcept
Definition: Statistics.cpp:101
std::variant< std::string, int64_t, uint64_t, double > Measurement
Definition: Statistics.hpp:66
#define JLM_ASSERT(x)
Definition: common.hpp:16
#define JLM_UNREACHABLE(msg)
Definition: common.hpp:43
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35
static const util::BijectiveMap< Statistics::Id, std::string_view > & GetStatisticsIdNames()
Definition: Statistics.cpp:18