Jlm
Loading...
Searching...
No Matches
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
14namespace jlm::util
15{
16// Mapping between each statistics id and identifier used when serializing the statistic
17static const util::BijectiveMap<Statistics::Id, std::string_view> &
19{
21 { Statistics::Id::AggregateAllocaSplitting, "AggregateAllocaSplitting" },
22 { Statistics::Id::Aggregation, "Aggregation" },
23 { Statistics::Id::AgnosticModRefSummarizer, "AgnosticModRefSummarizer" },
24 { Statistics::Id::AliasAnalysisPrecisionEvaluation, "AliasAnalysisPrecisionEvaluation" },
25 { Statistics::Id::AndersenAnalysis, "AndersenAnalysis" },
26 { Statistics::Id::Annotation, "Annotation" },
28 { Statistics::Id::ControlFlowRecovery, "ControlFlowRestructuring" },
29 { Statistics::Id::DataNodeToDelta, "DataNodeToDeltaStatistics" },
30 { Statistics::Id::DeadNodeElimination, "DeadNodeElimination" },
32 { Statistics::Id::IfConversion, "IfConversion" },
33 { Statistics::Id::IOBarrierElimination, "IOBarrierElimination" },
34 { Statistics::Id::JlmToRvsdgConversion, "ControlFlowGraphToLambda" },
35 { Statistics::Id::LoopStrengthReduction, "LoopStrengthReduction" },
37 { Statistics::Id::LoopUnswitching, "LoopUnswitching" },
38 { Statistics::Id::InvariantValueRedirection, "InvariantValueRedirection" },
39 { Statistics::Id::MemoryStateEncoder, "MemoryStateEncoder" },
40 { Statistics::Id::PullNodes, "PULL" },
41 { Statistics::Id::PushNodes, "PUSH" },
43 { Statistics::Id::RegionAwareModRefSummarizer, "RegionAwareModRefSummarizer" },
44 { Statistics::Id::RvsdgConstruction, "InterProceduralGraphToRvsdg" },
45 { Statistics::Id::RvsdgDestruction, "RVSDGDESTRUCTION" },
46 { Statistics::Id::RvsdgOptimization, "RVSDGOPTIMIZATION" },
47 { Statistics::Id::RvsdgTreePrinter, "RvsdgTreePrinter" },
48 { Statistics::Id::ScalarEvolution, "ScalarEvolution" },
49 { Statistics::Id::StoreValueForwarding, "StoreValueForwarding" },
50 };
51 // Make sure every Statistic is mentioned in the mapping
52 auto lastIdx = static_cast<size_t>(Statistics::Id::LastEnumValue);
53 auto firstIdx = static_cast<size_t>(Statistics::Id::FirstEnumValue);
54 JLM_ASSERT(mapping.Size() == lastIdx - firstIdx - 1);
55 return mapping;
56}
57
58Statistics::~Statistics() = default;
59
60std::string_view
65
66const util::FilePath &
68{
69 return SourceFile_;
70}
71
72std::string
73Statistics::Serialize(char fieldSeparator, char nameValueSeparator) const
74{
75 std::ostringstream ss;
76
77 ss << GetName() << fieldSeparator;
78 ss << GetSourceFile().to_str();
79
80 for (const auto & [mName, measurement] : Measurements_)
81 {
82 if (ss.tellp() != 0)
83 ss << fieldSeparator;
84
85 ss << mName << nameValueSeparator;
86 std::visit(
87 [&](const auto & value)
88 {
89 ss << value;
90 },
91 measurement);
92 }
93 for (const auto & [mName, timer] : Timers_)
94 {
95 if (ss.tellp() != 0)
96 ss << fieldSeparator;
97
98 ss << mName << "[ns]" << nameValueSeparator << timer.ns();
99 }
100
101 return ss.str();
102}
103
104bool
105Statistics::HasMeasurement(const std::string & name) const noexcept
106{
107 for (const auto & [mName, _] : Measurements_)
108 if (mName == name)
109 return true;
110 return false;
111}
112
114Statistics::GetMeasurement(const std::string & name) const
115{
116 for (const auto & [mName, measurement] : Measurements_)
117 if (mName == name)
118 return measurement;
119 JLM_UNREACHABLE("Unknown measurement");
120}
121
124{
125 return { Measurements_.begin(), Measurements_.end() };
126}
127
128bool
129Statistics::HasTimer(const std::string & name) const noexcept
130{
131 for (const auto & [mName, _] : Timers_)
132 if (mName == name)
133 return true;
134 return false;
135}
136
138Statistics::GetTimer(const std::string & name)
139{
140 for (auto & [mName, timer] : Timers_)
141 if (mName == name)
142 return timer;
143 JLM_UNREACHABLE("Unknown Timer");
144}
145
146const util::Timer &
147Statistics::GetTimer(const std::string & name) const
148{
149 return const_cast<Statistics *>(this)->GetTimer(name);
150}
151
154{
155 return { Timers_.begin(), Timers_.end() };
156}
157
159Statistics::AddTimer(std::string name)
160{
161 JLM_ASSERT(!HasTimer(name));
162 Timers_.emplace_back(std::make_pair(std::move(name), util::Timer()));
163 auto & timer = Timers_.back().second;
164 return timer;
165}
166
167void
169{
170 if (NumCollectedStatistics() == 0)
171 return;
172
173 auto file = createOutputFile("statistics.log");
174 file.open("w");
175
176 for (auto & statistics : CollectedStatistics())
177 {
178 fprintf(file.fd(), "%s\n", statistics.Serialize(' ', ':').c_str());
179 }
180}
181
182File
183StatisticsCollector::createOutputFile(std::string fileNameSuffix, bool includeCount)
184{
186
187 auto directory = Settings_.GetOrCreateOutputDirectory();
188
189 // If the fileNameSuffix should have a count included, place it before the '.' (or at the end)
190 if (includeCount)
191 {
192 size_t count = OutputFileCounter_[fileNameSuffix]++;
193 auto firstDot = fileNameSuffix.find('.');
194 if (firstDot == std::string::npos)
195 firstDot = fileNameSuffix.size();
196
197 fileNameSuffix =
198 strfmt(fileNameSuffix.substr(0, firstDot), "-", count, fileNameSuffix.substr(firstDot));
199 }
200
201 std::string fileName;
202 if (!Settings_.GetModuleName().empty())
203 fileName += Settings_.GetModuleName() + "-";
204 if (!Settings_.GetUniqueString().empty())
205 fileName += Settings_.GetUniqueString() + "-";
206 fileName += fileNameSuffix;
207
208 auto fullPath = directory.Join(fileName);
209 if (fullPath.Exists())
210 throw Error("The generated output file name already exists: " + fullPath.to_str());
211
212 return File(fullPath);
213}
214
215}
std::size_t Size() const noexcept
const V & LookupKey(const K &key) const
const std::string & to_str() const noexcept
Definition file.hpp:275
const std::string & GetModuleName() const noexcept
bool HasOutputDirectory() const noexcept
const FilePath & GetOrCreateOutputDirectory() const noexcept
const std::string & GetUniqueString() const noexcept
void PrintStatistics()
Print collected statistics to file. If no statistics have been collected, this is a no-op.
StatisticsCollectorSettings Settings_
std::unordered_map< std::string, size_t > OutputFileCounter_
StatisticsRange CollectedStatistics() const noexcept
File createOutputFile(std::string fileNameSuffix, bool includeCount=false)
size_t NumCollectedStatistics() const noexcept
Statistics Interface.
util::Timer & GetTimer(const std::string &name)
util::FilePath SourceFile_
std::string_view GetName() const
const util::FilePath & GetSourceFile() const
Statistics::Id StatisticsId_
MeasurementList Measurements_
bool HasTimer(const std::string &name) const noexcept
std::string Serialize(char fieldSeparator, char nameValueSeparator) const
const Measurement & GetMeasurement(const std::string &name) const
util::Timer & AddTimer(std::string name)
IteratorRange< MeasurementList::const_iterator > GetMeasurements() const
IteratorRange< TimerList::const_iterator > GetTimers() const
bool HasMeasurement(const std::string &name) const noexcept
std::variant< std::string, int64_t, uint64_t, double > Measurement
#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()