Jlm
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 
24 namespace jlm::util
25 {
26 
31 {
32 public:
33  enum class Id
34  {
35  FirstEnumValue, // must always be the first enum value, used for iteration
36 
42  Annotation,
55  PullNodes,
56  PushNodes,
65 
66  LastEnumValue // must always be the last enum value, used for iteration
67  };
68 
69  using Measurement = std::variant<std::string, int64_t, uint64_t, double>;
70  // Lists are used instead of vectors to give stable references to members
71  using MeasurementList = std::list<std::pair<std::string, Measurement>>;
72  using TimerList = std::list<std::pair<std::string, util::Timer>>;
73 
74  virtual ~Statistics();
75 
76  Statistics(const Statistics::Id & statisticsId, util::FilePath sourceFile)
77  : StatisticsId_(statisticsId),
78  SourceFile_(std::move(sourceFile))
79  {}
80 
81  [[nodiscard]] Statistics::Id
82  GetId() const noexcept
83  {
84  return StatisticsId_;
85  }
86 
90  [[nodiscard]] std::string_view
91  GetName() const;
92 
96  [[nodiscard]] const util::FilePath &
97  GetSourceFile() const;
98 
109  [[nodiscard]] std::string
110  Serialize(char fieldSeparator, char nameValueSeparator) const;
111 
116  [[nodiscard]] bool
117  HasMeasurement(const std::string & name) const noexcept;
118 
123  [[nodiscard]] const Measurement &
124  GetMeasurement(const std::string & name) const;
125 
131  template<typename T>
132  [[nodiscard]] const T &
133  GetMeasurementValue(const std::string & name) const
134  {
135  const auto & measurement = GetMeasurement(name);
136  return std::get<T>(measurement);
137  }
138 
143  GetMeasurements() const;
144 
149  [[nodiscard]] bool
150  HasTimer(const std::string & name) const noexcept;
151 
157  [[nodiscard]] size_t
158  GetTimerElapsedNanoseconds(const std::string & name) const
159  {
160  return GetTimer(name).ns();
161  }
162 
167  GetTimers() const;
168 
169 protected:
175  template<typename T>
176  void
177  AddMeasurement(std::string name, T value)
178  {
179  JLM_ASSERT(!HasMeasurement(name));
180  Measurements_.emplace_back(std::make_pair(std::move(name), std::move(value)));
181  }
182 
188  util::Timer &
189  AddTimer(std::string name);
190 
196  [[nodiscard]] util::Timer &
197  GetTimer(const std::string & name);
198 
199  [[nodiscard]] const util::Timer &
200  GetTimer(const std::string & name) const;
201 
205  struct Label
206  {
207  static inline const char * FunctionNameLabel_ = "Function";
208 
209  static inline const char * NumCfgNodes = "#CfgNodes";
210 
211  static inline const char * NumThreeAddressCodes = "#ThreeAddressCodes";
212 
213  static inline const char * NumRvsdgNodes = "#RvsdgNodes";
214  static inline const char * NumRvsdgNodesBefore = "#RvsdgNodesBefore";
215  static inline const char * NumRvsdgNodesAfter = "#RvsdgNodesAfter";
216 
217  static inline const char * NumRvsdgInputsBefore = "#RvsdgInputsBefore";
218  static inline const char * NumRvsdgInputsAfter = "#RvsdgInputsAfter";
219 
220  inline static const char * NumPointsToGraphNodes = "#PointsToGraphNodes";
221  inline static const char * NumPointsToGraphAllocaNodes = "#PointsToGraphAllocaNodes";
222  inline static const char * NumPointsToGraphDeltaNodes = "#PointsToGraphDeltaNodes";
223  inline static const char * NumPointsToGraphImportNodes = "#PointsToGraphImportNodes";
224  inline static const char * NumPointsToGraphLambdaNodes = "#PointsToGraphLambdaNodes";
225  inline static const char * NumPointsToGraphMallocNodes = "#PointsToGraphMallocNodes";
226  inline static const char * NumPointsToGraphMemoryNodes = "#PointsToGraphMemoryNodes";
227  inline static const char * NumPointsToGraphRegisterNodes = "#PointsToGraphRegisterNodes";
228  inline static const char * NumPointsToGraphExternallyAvailableNodes =
229  "#PointsToGraphExternallyAvailableNodes";
231  "#PointsToGraphNodesTargetsAllExternallyAvailable";
232 
233  inline static const char * NumPointsToGraphExplicitEdges = "#PointsToGraphExplicitEdges";
234  inline static const char * NumPointsToGraphEdges = "#PointsToGraphEdges";
235 
236  inline static const char * NumLoopVariablesTotal = "#LoopVariablesTotal";
237  inline static const char * NumTotalInductionVariables = "#TotalInductionVariables";
238  inline static const char * NumConstantInductionVariables = "#ConstantInductionVariables";
239  inline static const char * NumFirstOrderInductionVariables = "#FirstOrderInductionVariables";
240  inline static const char * NumSecondOrderInductionVariables = "#SecondOrderInductionVariables";
241  inline static const char * NumLoops = "#NumLoops";
242  inline static const char * TripCounts = "#TripCounts";
243 
244  inline static const char * NumLSRCandidates = "#Candidates";
245  inline static const char * NumArithmeticLSRCandidates = "#ArithmeticCandidates";
246  inline static const char * NumGepLSRCandidates = "#GepCandidates";
247  inline static const char * NumOperationsReduced = "#OperationsReduced";
248  inline static const char * NumArithmeticOperationsReduced = "#ArithmeticOperationsReduced";
249  inline static const char * NumGepOperationsReduced = "#GepOperationsReduced";
250 
251  static inline const char * Timer = "Time";
252  };
253 
254 private:
257 
260 };
261 
266 {
267 public:
273  : Directory_("."),
274  ModuleName_("")
275  {}
276 
283  : DemandedStatistics_(std::move(demandedStatistics)),
284  Directory_("."),
285  ModuleName_("")
286  {}
287 
303  HashSet<Statistics::Id> demandedStatistics,
304  std::optional<FilePath> directory,
305  std::string moduleName)
306  : DemandedStatistics_(std::move(demandedStatistics)),
307  Directory_(std::move(directory)),
308  ModuleName_(std::move(moduleName))
309  {}
310 
315  void
317  {
318  DemandedStatistics_ = std::move(demandedStatistics);
319  }
320 
324  [[nodiscard]] size_t
325  NumDemandedStatistics() const noexcept
326  {
327  return DemandedStatistics_.Size();
328  }
329 
333  [[nodiscard]] const HashSet<Statistics::Id> &
334  GetDemandedStatistics() const noexcept
335  {
336  return DemandedStatistics_;
337  }
338 
344  [[nodiscard]] bool
345  isDemanded(Statistics::Id id) const noexcept
346  {
347  return DemandedStatistics_.Contains(id);
348  }
349 
354  [[nodiscard]] bool
355  HasOutputDirectory() const noexcept
356  {
357  return Directory_.has_value();
358  }
359 
363  [[nodiscard]] const FilePath &
364  GetOutputDirectory() const noexcept
365  {
366  JLM_ASSERT(Directory_.has_value());
367  return Directory_.value();
368  }
369 
376  [[nodiscard]] const FilePath &
377  GetOrCreateOutputDirectory() const noexcept
378  {
379  JLM_ASSERT(Directory_.has_value());
380  Directory_->CreateDirectory();
381  return Directory_.value();
382  }
383 
389  void
391  {
392  Directory_ = std::move(directory);
393  }
394 
398  [[nodiscard]] const std::string &
399  GetModuleName() const noexcept
400  {
401  return ModuleName_;
402  }
403 
407  void
408  SetModuleName(std::string moduleName)
409  {
410  ModuleName_ = std::move(moduleName);
411  }
412 
416  [[nodiscard]] const std::string &
417  GetUniqueString() const noexcept
418  {
419  return UniqueString_;
420  }
421 
426  void
427  SetUniqueString(std::string uniqueString)
428  {
429  UniqueString_ = std::move(uniqueString);
430  }
431 
432 private:
434  std::optional<FilePath> Directory_;
435  std::string ModuleName_;
437 };
438 
443 {
444  class StatisticsIterator final
445  {
446  public:
447  using iterator_category = std::forward_iterator_tag;
448  using value_type = const Statistics *;
449  using difference_type = std::ptrdiff_t;
450  using pointer = const Statistics **;
451  using reference = const Statistics *&;
452 
453  private:
455 
456  explicit StatisticsIterator(const std::vector<std::unique_ptr<Statistics>>::const_iterator & it)
457  : it_(it)
458  {}
459 
460  public:
461  [[nodiscard]] const Statistics *
462  GetStatistics() const noexcept
463  {
464  return it_->get();
465  }
466 
467  const Statistics &
468  operator*() const
469  {
470  JLM_ASSERT(GetStatistics() != nullptr);
471  return *GetStatistics();
472  }
473 
474  const Statistics *
475  operator->() const
476  {
477  return GetStatistics();
478  }
479 
482  {
483  ++it_;
484  return *this;
485  }
486 
489  {
490  StatisticsIterator tmp = *this;
491  ++*this;
492  return tmp;
493  }
494 
495  bool
496  operator==(const StatisticsIterator & other) const
497  {
498  return it_ == other.it_;
499  }
500 
501  bool
502  operator!=(const StatisticsIterator & other) const
503  {
504  return !operator==(other);
505  }
506 
507  private:
508  std::vector<std::unique_ptr<Statistics>>::const_iterator it_;
509  };
510 
511 public:
513 
515  {}
516 
518  : Settings_(std::move(settings))
519  {}
520 
522  GetSettings() const noexcept
523  {
524  return Settings_;
525  }
526 
528  CollectedStatistics() const noexcept
529  {
530  return { StatisticsIterator(CollectedStatistics_.begin()),
532  }
533 
534  [[nodiscard]] size_t
535  NumCollectedStatistics() const noexcept
536  {
537  return CollectedStatistics_.size();
538  }
539 
547  [[nodiscard]] bool
548  IsDemanded(Statistics::Id id) const noexcept
549  {
550  return GetSettings().isDemanded(id);
551  }
552 
560  [[nodiscard]] bool
561  IsDemanded(const Statistics & statistics) const noexcept
562  {
563  return IsDemanded(statistics.GetId());
564  }
565 
573  void
574  CollectDemandedStatistics(std::unique_ptr<Statistics> statistics)
575  {
576  if (IsDemanded(*statistics))
577  CollectedStatistics_.emplace_back(std::move(statistics));
578  }
579 
587  [[nodiscard]] std::unique_ptr<Statistics>
589  {
590  auto it = CollectedStatistics_.end();
591  while (it != CollectedStatistics_.begin())
592  {
593  it--;
594  if (it->get()->GetId() == id)
595  {
596  auto result = std::move(*it);
597  CollectedStatistics_.erase(it);
598  return result;
599  }
600  }
601  throw std::out_of_range("No Statistics with the given id has been collected");
602  }
603 
609  void
610  PrintStatistics();
611 
629  [[nodiscard]] File
630  createOutputFile(std::string fileNameSuffix, bool includeCount = false);
631 
632 private:
634  std::vector<std::unique_ptr<Statistics>> CollectedStatistics_;
635 
636  // Counter used to give unique file names to output files that share suffix
637  std::unordered_map<std::string, size_t> OutputFileCounter_;
638 };
639 
640 }
641 
642 #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)
Definition: Statistics.hpp:390
size_t NumDemandedStatistics() const noexcept
Definition: Statistics.hpp:325
bool HasOutputDirectory() const noexcept
Definition: Statistics.hpp:355
std::optional< FilePath > Directory_
Definition: Statistics.hpp:434
void SetUniqueString(std::string uniqueString)
Definition: Statistics.hpp:427
void SetDemandedStatistics(HashSet< Statistics::Id > demandedStatistics)
Definition: Statistics.hpp:316
const std::string & GetUniqueString() const noexcept
Definition: Statistics.hpp:417
const HashSet< Statistics::Id > & GetDemandedStatistics() const noexcept
Definition: Statistics.hpp:334
HashSet< Statistics::Id > DemandedStatistics_
Definition: Statistics.hpp:433
StatisticsCollectorSettings(HashSet< Statistics::Id > demandedStatistics, std::optional< FilePath > directory, std::string moduleName)
Definition: Statistics.hpp:302
const FilePath & GetOutputDirectory() const noexcept
Definition: Statistics.hpp:364
void SetModuleName(std::string moduleName)
Definition: Statistics.hpp:408
const FilePath & GetOrCreateOutputDirectory() const noexcept
Definition: Statistics.hpp:377
bool isDemanded(Statistics::Id id) const noexcept
Checks if a statistics is demanded.
Definition: Statistics.hpp:345
const std::string & GetModuleName() const noexcept
Definition: Statistics.hpp:399
StatisticsCollectorSettings(HashSet< Statistics::Id > demandedStatistics)
Definition: Statistics.hpp:282
const Statistics * GetStatistics() const noexcept
Definition: Statistics.hpp:462
StatisticsIterator(const std::vector< std::unique_ptr< Statistics >>::const_iterator &it)
Definition: Statistics.hpp:456
bool operator!=(const StatisticsIterator &other) const
Definition: Statistics.hpp:502
bool operator==(const StatisticsIterator &other) const
Definition: Statistics.hpp:496
std::vector< std::unique_ptr< Statistics > >::const_iterator it_
Definition: Statistics.hpp:508
std::unique_ptr< Statistics > releaseStatistic(Statistics::Id id)
Definition: Statistics.hpp:588
IteratorRange< StatisticsIterator > StatisticsRange
Definition: Statistics.hpp:512
bool IsDemanded(const Statistics &statistics) const noexcept
Definition: Statistics.hpp:561
void PrintStatistics()
Print collected statistics to file. If no statistics have been collected, this is a no-op.
Definition: Statistics.cpp:167
bool IsDemanded(Statistics::Id id) const noexcept
Definition: Statistics.hpp:548
const StatisticsCollectorSettings & GetSettings() const noexcept
Definition: Statistics.hpp:522
StatisticsCollectorSettings Settings_
Definition: Statistics.hpp:633
std::vector< std::unique_ptr< Statistics > > CollectedStatistics_
Definition: Statistics.hpp:634
std::unordered_map< std::string, size_t > OutputFileCounter_
Definition: Statistics.hpp:637
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
Definition: Statistics.hpp:574
StatisticsRange CollectedStatistics() const noexcept
Definition: Statistics.hpp:528
File createOutputFile(std::string fileNameSuffix, bool includeCount=false)
Definition: Statistics.cpp:182
StatisticsCollector(StatisticsCollectorSettings settings)
Definition: Statistics.hpp:517
size_t NumCollectedStatistics() const noexcept
Definition: Statistics.hpp:535
Statistics Interface.
Definition: Statistics.hpp:31
util::Timer & GetTimer(const std::string &name)
Definition: Statistics.cpp:137
util::FilePath SourceFile_
Definition: Statistics.hpp:256
std::string_view GetName() const
Definition: Statistics.cpp:60
const util::FilePath & GetSourceFile() const
Definition: Statistics.cpp:66
std::list< std::pair< std::string, util::Timer > > TimerList
Definition: Statistics.hpp:72
Statistics::Id StatisticsId_
Definition: Statistics.hpp:255
Statistics(const Statistics::Id &statisticsId, util::FilePath sourceFile)
Definition: Statistics.hpp:76
MeasurementList Measurements_
Definition: Statistics.hpp:258
bool HasTimer(const std::string &name) const noexcept
Definition: Statistics.cpp:128
std::string Serialize(char fieldSeparator, char nameValueSeparator) const
Definition: Statistics.cpp:72
const Measurement & GetMeasurement(const std::string &name) const
Definition: Statistics.cpp:113
const T & GetMeasurementValue(const std::string &name) const
Definition: Statistics.hpp:133
util::Timer & AddTimer(std::string name)
Definition: Statistics.cpp:158
IteratorRange< MeasurementList::const_iterator > GetMeasurements() const
Definition: Statistics.cpp:122
IteratorRange< TimerList::const_iterator > GetTimers() const
Definition: Statistics.cpp:152
size_t GetTimerElapsedNanoseconds(const std::string &name) const
Definition: Statistics.hpp:158
bool HasMeasurement(const std::string &name) const noexcept
Definition: Statistics.cpp:104
Statistics::Id GetId() const noexcept
Definition: Statistics.hpp:82
std::variant< std::string, int64_t, uint64_t, double > Measurement
Definition: Statistics.hpp:69
std::list< std::pair< std::string, Measurement > > MeasurementList
Definition: Statistics.hpp:71
void AddMeasurement(std::string name, T value)
Definition: Statistics.hpp:177
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
Definition: Statistics.hpp:249
static const char * FunctionNameLabel_
Definition: Statistics.hpp:207
static const char * TripCounts
Definition: Statistics.hpp:242
static const char * NumFirstOrderInductionVariables
Definition: Statistics.hpp:239
static const char * NumPointsToGraphAllocaNodes
Definition: Statistics.hpp:221
static const char * NumPointsToGraphMemoryNodes
Definition: Statistics.hpp:226
static const char * NumRvsdgNodes
Definition: Statistics.hpp:213
static const char * NumPointsToGraphDeltaNodes
Definition: Statistics.hpp:222
static const char * NumThreeAddressCodes
Definition: Statistics.hpp:211
static const char * NumRvsdgNodesBefore
Definition: Statistics.hpp:214
static const char * NumPointsToGraphRegisterNodes
Definition: Statistics.hpp:227
static const char * NumConstantInductionVariables
Definition: Statistics.hpp:238
static const char * NumPointsToGraphNodes
Definition: Statistics.hpp:220
static const char * NumGepLSRCandidates
Definition: Statistics.hpp:246
static const char * NumOperationsReduced
Definition: Statistics.hpp:247
static const char * NumPointsToGraphMallocNodes
Definition: Statistics.hpp:225
static const char * NumPointsToGraphImportNodes
Definition: Statistics.hpp:223
static const char * NumRvsdgNodesAfter
Definition: Statistics.hpp:215
static const char * NumTotalInductionVariables
Definition: Statistics.hpp:237
static const char * NumPointsToGraphExternallyAvailableNodes
Definition: Statistics.hpp:228
static const char * NumPointsToGraphExplicitEdges
Definition: Statistics.hpp:233
static const char * NumPointsToGraphLambdaNodes
Definition: Statistics.hpp:224
static const char * NumSecondOrderInductionVariables
Definition: Statistics.hpp:240
static const char * NumPointsToGraphEdges
Definition: Statistics.hpp:234
static const char * NumPointsToGraphNodesTargetsAllExternallyAvailable
Definition: Statistics.hpp:230
static const char * NumArithmeticOperationsReduced
Definition: Statistics.hpp:248
static const char * NumLoopVariablesTotal
Definition: Statistics.hpp:236
static const char * NumLSRCandidates
Definition: Statistics.hpp:244
static const char * NumArithmeticLSRCandidates
Definition: Statistics.hpp:245
static const char * NumCfgNodes
Definition: Statistics.hpp:209
static const char * NumRvsdgInputsAfter
Definition: Statistics.hpp:218
static const char * NumLoops
Definition: Statistics.hpp:241
static const char * NumRvsdgInputsBefore
Definition: Statistics.hpp:217