Jlm
Loading...
Searching...
No Matches
Statistics.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 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
7#ifndef JLM_UTIL_STATISTICS_HPP
8#define JLM_UTIL_STATISTICS_HPP
9
10#include <jlm/util/file.hpp>
11#include <jlm/util/HashSet.hpp>
12#include <jlm/util/strfmt.hpp>
13#include <jlm/util/time.hpp>
14
15#include <cstdint>
16#include <list>
17#include <memory>
18#include <optional>
19#include <string>
20#include <unordered_map>
21#include <variant>
22#include <vector>
23
24namespace jlm::util
25{
26
31{
32public:
69
70 using Measurement = std::variant<std::string, int64_t, uint64_t, double>;
71 // Lists are used instead of vectors to give stable references to members
72 using MeasurementList = std::list<std::pair<std::string, Measurement>>;
73 using TimerList = std::list<std::pair<std::string, util::Timer>>;
74
75 virtual ~Statistics();
76
77 Statistics(const Statistics::Id & statisticsId, util::FilePath sourceFile)
78 : StatisticsId_(statisticsId),
79 SourceFile_(std::move(sourceFile))
80 {}
81
82 [[nodiscard]] Statistics::Id
83 GetId() const noexcept
84 {
85 return StatisticsId_;
86 }
87
91 [[nodiscard]] std::string_view
92 GetName() const;
93
97 [[nodiscard]] const util::FilePath &
98 GetSourceFile() const;
99
110 [[nodiscard]] std::string
111 Serialize(char fieldSeparator, char nameValueSeparator) const;
112
117 [[nodiscard]] bool
118 HasMeasurement(const std::string & name) const noexcept;
119
124 [[nodiscard]] const Measurement &
125 GetMeasurement(const std::string & name) const;
126
132 template<typename T>
133 [[nodiscard]] const T &
134 GetMeasurementValue(const std::string & name) const
135 {
136 const auto & measurement = GetMeasurement(name);
137 return std::get<T>(measurement);
138 }
139
144 GetMeasurements() const;
145
150 [[nodiscard]] bool
151 HasTimer(const std::string & name) const noexcept;
152
158 [[nodiscard]] size_t
159 GetTimerElapsedNanoseconds(const std::string & name) const
160 {
161 return GetTimer(name).ns();
162 }
163
168 GetTimers() const;
169
170protected:
176 template<typename T>
177 void
178 AddMeasurement(std::string name, T value)
179 {
181 Measurements_.emplace_back(std::make_pair(std::move(name), std::move(value)));
182 }
183
190 AddTimer(std::string name);
191
197 [[nodiscard]] util::Timer &
198 GetTimer(const std::string & name);
199
200 [[nodiscard]] const util::Timer &
201 GetTimer(const std::string & name) const;
202
206 struct Label
207 {
208 static inline const char * FunctionNameLabel_ = "Function";
209
210 static inline const char * NumCfgNodes = "#CfgNodes";
211
212 static inline const char * NumThreeAddressCodes = "#ThreeAddressCodes";
213
214 static inline const char * NumRvsdgNodes = "#RvsdgNodes";
215 static inline const char * NumRvsdgNodesBefore = "#RvsdgNodesBefore";
216 static inline const char * NumRvsdgNodesAfter = "#RvsdgNodesAfter";
217
218 static inline const char * NumRvsdgInputsBefore = "#RvsdgInputsBefore";
219 static inline const char * NumRvsdgInputsAfter = "#RvsdgInputsAfter";
220
221 inline static const char * NumPointsToGraphNodes = "#PointsToGraphNodes";
222 inline static const char * NumPointsToGraphAllocaNodes = "#PointsToGraphAllocaNodes";
223 inline static const char * NumPointsToGraphDeltaNodes = "#PointsToGraphDeltaNodes";
224 inline static const char * NumPointsToGraphImportNodes = "#PointsToGraphImportNodes";
225 inline static const char * NumPointsToGraphLambdaNodes = "#PointsToGraphLambdaNodes";
226 inline static const char * NumPointsToGraphMallocNodes = "#PointsToGraphMallocNodes";
227 inline static const char * NumPointsToGraphMemoryNodes = "#PointsToGraphMemoryNodes";
228 inline static const char * NumPointsToGraphRegisterNodes = "#PointsToGraphRegisterNodes";
229 inline static const char * NumPointsToGraphExternallyAvailableNodes =
230 "#PointsToGraphExternallyAvailableNodes";
232 "#PointsToGraphNodesTargetsAllExternallyAvailable";
233
234 inline static const char * NumPointsToGraphExplicitEdges = "#PointsToGraphExplicitEdges";
235 inline static const char * NumPointsToGraphEdges = "#PointsToGraphEdges";
236
237 inline static const char * NumLoopVariablesTotal = "#LoopVariablesTotal";
238 inline static const char * NumTotalInductionVariables = "#TotalInductionVariables";
239 inline static const char * NumConstantInductionVariables = "#ConstantInductionVariables";
240 inline static const char * NumFirstOrderInductionVariables = "#FirstOrderInductionVariables";
241 inline static const char * NumSecondOrderInductionVariables = "#SecondOrderInductionVariables";
242 inline static const char * NumLoops = "#NumLoops";
243 inline static const char * TripCounts = "#TripCounts";
244
245 inline static const char * NumLSRCandidates = "#Candidates";
246 inline static const char * NumArithmeticLSRCandidates = "#ArithmeticCandidates";
247 inline static const char * NumGepLSRCandidates = "#GepCandidates";
248 inline static const char * NumOperationsReduced = "#OperationsReduced";
249 inline static const char * NumArithmeticOperationsReduced = "#ArithmeticOperationsReduced";
250 inline static const char * NumGepOperationsReduced = "#GepOperationsReduced";
251
252 static inline const char * Timer = "Time";
253 };
254
255private:
258
261};
262
267{
268public:
277
284 : DemandedStatistics_(std::move(demandedStatistics)),
285 Directory_("."),
286 ModuleName_("")
287 {}
288
304 HashSet<Statistics::Id> demandedStatistics,
305 std::optional<FilePath> directory,
306 std::string moduleName)
307 : DemandedStatistics_(std::move(demandedStatistics)),
308 Directory_(std::move(directory)),
309 ModuleName_(std::move(moduleName))
310 {}
311
316 void
318 {
319 DemandedStatistics_ = std::move(demandedStatistics);
320 }
321
325 [[nodiscard]] size_t
326 NumDemandedStatistics() const noexcept
327 {
328 return DemandedStatistics_.Size();
329 }
330
334 [[nodiscard]] const HashSet<Statistics::Id> &
335 GetDemandedStatistics() const noexcept
336 {
337 return DemandedStatistics_;
338 }
339
345 [[nodiscard]] bool
346 isDemanded(Statistics::Id id) const noexcept
347 {
348 return DemandedStatistics_.Contains(id);
349 }
350
355 [[nodiscard]] bool
356 HasOutputDirectory() const noexcept
357 {
358 return Directory_.has_value();
359 }
360
364 [[nodiscard]] const FilePath &
365 GetOutputDirectory() const noexcept
366 {
367 JLM_ASSERT(Directory_.has_value());
368 return Directory_.value();
369 }
370
377 [[nodiscard]] const FilePath &
379 {
380 JLM_ASSERT(Directory_.has_value());
381 Directory_->CreateDirectory();
382 return Directory_.value();
383 }
384
390 void
392 {
393 Directory_ = std::move(directory);
394 }
395
399 [[nodiscard]] const std::string &
400 GetModuleName() const noexcept
401 {
402 return ModuleName_;
403 }
404
408 void
409 SetModuleName(std::string moduleName)
410 {
411 ModuleName_ = std::move(moduleName);
412 }
413
417 [[nodiscard]] const std::string &
418 GetUniqueString() const noexcept
419 {
420 return UniqueString_;
421 }
422
427 void
428 SetUniqueString(std::string uniqueString)
429 {
430 UniqueString_ = std::move(uniqueString);
431 }
432
433private:
435 std::optional<FilePath> Directory_;
436 std::string ModuleName_;
438};
439
444{
446 {
447 public:
448 using iterator_category = std::forward_iterator_tag;
449 using value_type = const Statistics *;
450 using difference_type = std::ptrdiff_t;
451 using pointer = const Statistics **;
452 using reference = const Statistics *&;
453
454 private:
456
457 explicit StatisticsIterator(const std::vector<std::unique_ptr<Statistics>>::const_iterator & it)
458 : it_(it)
459 {}
460
461 public:
462 [[nodiscard]] const Statistics *
463 GetStatistics() const noexcept
464 {
465 return it_->get();
466 }
467
468 const Statistics &
469 operator*() const
470 {
471 JLM_ASSERT(GetStatistics() != nullptr);
472 return *GetStatistics();
473 }
474
475 const Statistics *
477 {
478 return GetStatistics();
479 }
480
483 {
484 ++it_;
485 return *this;
486 }
487
490 {
491 StatisticsIterator tmp = *this;
492 ++*this;
493 return tmp;
494 }
495
496 bool
497 operator==(const StatisticsIterator & other) const
498 {
499 return it_ == other.it_;
500 }
501
502 bool
503 operator!=(const StatisticsIterator & other) const
504 {
505 return !operator==(other);
506 }
507
508 private:
509 std::vector<std::unique_ptr<Statistics>>::const_iterator it_;
510 };
511
512public:
514
517
519 : Settings_(std::move(settings))
520 {}
521
523 GetSettings() const noexcept
524 {
525 return Settings_;
526 }
527
529 CollectedStatistics() const noexcept
530 {
533 }
534
535 [[nodiscard]] size_t
536 NumCollectedStatistics() const noexcept
537 {
538 return CollectedStatistics_.size();
539 }
540
548 [[nodiscard]] bool
549 IsDemanded(Statistics::Id id) const noexcept
550 {
551 return GetSettings().isDemanded(id);
552 }
553
561 [[nodiscard]] bool
562 IsDemanded(const Statistics & statistics) const noexcept
563 {
564 return IsDemanded(statistics.GetId());
565 }
566
574 void
575 CollectDemandedStatistics(std::unique_ptr<Statistics> statistics)
576 {
577 if (IsDemanded(*statistics))
578 CollectedStatistics_.emplace_back(std::move(statistics));
579 }
580
588 [[nodiscard]] std::unique_ptr<Statistics>
590 {
591 auto it = CollectedStatistics_.end();
592 while (it != CollectedStatistics_.begin())
593 {
594 it--;
595 if (it->get()->GetId() == id)
596 {
597 auto result = std::move(*it);
598 CollectedStatistics_.erase(it);
599 return result;
600 }
601 }
602 throw std::out_of_range("No Statistics with the given id has been collected");
603 }
604
610 void
612
630 [[nodiscard]] File
631 createOutputFile(std::string fileNameSuffix, bool includeCount = false);
632
633private:
635 std::vector<std::unique_ptr<Statistics>> CollectedStatistics_;
636
637 // Counter used to give unique file names to output files that share suffix
638 std::unordered_map<std::string, size_t> OutputFileCounter_;
639};
640
641}
642
643#endif
std::size_t Size() const noexcept
Definition HashSet.hpp:187
bool Contains(const ItemType &item) const noexcept
Definition HashSet.hpp:150
void SetOutputDirectory(FilePath directory)
size_t NumDemandedStatistics() const noexcept
const std::string & GetModuleName() const noexcept
const HashSet< Statistics::Id > & GetDemandedStatistics() const noexcept
bool HasOutputDirectory() const noexcept
std::optional< FilePath > Directory_
void SetUniqueString(std::string uniqueString)
const FilePath & GetOutputDirectory() const noexcept
void SetDemandedStatistics(HashSet< Statistics::Id > demandedStatistics)
HashSet< Statistics::Id > DemandedStatistics_
StatisticsCollectorSettings(HashSet< Statistics::Id > demandedStatistics, std::optional< FilePath > directory, std::string moduleName)
void SetModuleName(std::string moduleName)
const FilePath & GetOrCreateOutputDirectory() const noexcept
bool isDemanded(Statistics::Id id) const noexcept
Checks if a statistics is demanded.
StatisticsCollectorSettings(HashSet< Statistics::Id > demandedStatistics)
const std::string & GetUniqueString() const noexcept
std::vector< std::unique_ptr< Statistics > >::const_iterator it_
const Statistics * GetStatistics() const noexcept
bool operator!=(const StatisticsIterator &other) const
bool operator==(const StatisticsIterator &other) const
StatisticsIterator(const std::vector< std::unique_ptr< Statistics > >::const_iterator &it)
IteratorRange< StatisticsIterator > StatisticsRange
bool IsDemanded(const Statistics &statistics) const noexcept
std::unique_ptr< Statistics > releaseStatistic(Statistics::Id id)
void PrintStatistics()
Print collected statistics to file. If no statistics have been collected, this is a no-op.
const StatisticsCollectorSettings & GetSettings() const noexcept
bool IsDemanded(Statistics::Id id) const noexcept
StatisticsCollectorSettings Settings_
std::vector< std::unique_ptr< Statistics > > CollectedStatistics_
std::unordered_map< std::string, size_t > OutputFileCounter_
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
StatisticsRange CollectedStatistics() const noexcept
File createOutputFile(std::string fileNameSuffix, bool includeCount=false)
StatisticsCollector(StatisticsCollectorSettings settings)
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
std::list< std::pair< std::string, util::Timer > > TimerList
Statistics::Id StatisticsId_
Statistics(const Statistics::Id &statisticsId, util::FilePath sourceFile)
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)
const T & GetMeasurementValue(const std::string &name) const
IteratorRange< MeasurementList::const_iterator > GetMeasurements() const
IteratorRange< TimerList::const_iterator > GetTimers() const
size_t GetTimerElapsedNanoseconds(const std::string &name) const
bool HasMeasurement(const std::string &name) const noexcept
Statistics::Id GetId() const noexcept
std::variant< std::string, int64_t, uint64_t, double > Measurement
std::list< std::pair< std::string, Measurement > > MeasurementList
void AddMeasurement(std::string name, T value)
size_t ns() const
Definition time.hpp:83
#define JLM_ASSERT(x)
Definition common.hpp:16
std::string CreateRandomAlphanumericString(std::size_t length)
Definition strfmt.cpp:15
static const char * NumGepOperationsReduced
static const char * FunctionNameLabel_
static const char * TripCounts
static const char * NumFirstOrderInductionVariables
static const char * NumPointsToGraphAllocaNodes
static const char * NumPointsToGraphMemoryNodes
static const char * NumRvsdgNodes
static const char * NumPointsToGraphDeltaNodes
static const char * NumThreeAddressCodes
static const char * NumRvsdgNodesBefore
static const char * NumPointsToGraphRegisterNodes
static const char * NumConstantInductionVariables
static const char * NumPointsToGraphNodes
static const char * NumGepLSRCandidates
static const char * NumOperationsReduced
static const char * NumPointsToGraphMallocNodes
static const char * NumPointsToGraphImportNodes
static const char * NumRvsdgNodesAfter
static const char * NumTotalInductionVariables
static const char * NumPointsToGraphExternallyAvailableNodes
static const char * NumPointsToGraphExplicitEdges
static const char * NumPointsToGraphLambdaNodes
static const char * NumSecondOrderInductionVariables
static const char * NumPointsToGraphEdges
static const char * NumPointsToGraphNodesTargetsAllExternallyAvailable
static const char * NumArithmeticOperationsReduced
static const char * NumLoopVariablesTotal
static const char * NumLSRCandidates
static const char * NumArithmeticLSRCandidates
static const char * NumCfgNodes
static const char * NumRvsdgInputsAfter
static const char * NumLoops
static const char * NumRvsdgInputsBefore