2
0

Statistic.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //===-- Statistic.cpp - Easy way to expose stats information --------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the 'Statistic' class, which is designed to be an easy
  11. // way to expose various success metrics from passes. These statistics are
  12. // printed at the end of a run, when the -stats command line option is enabled
  13. // on the command line.
  14. //
  15. // This is useful for reporting information like the number of instructions
  16. // simplified, optimized or removed by various transformations, like this:
  17. //
  18. // static Statistic NumInstEliminated("GCSE", "Number of instructions killed");
  19. //
  20. // Later, in the code: ++NumInstEliminated;
  21. //
  22. //===----------------------------------------------------------------------===//
  23. #include "llvm/ADT/Statistic.h"
  24. #include "llvm/ADT/StringExtras.h"
  25. #include "llvm/Support/CommandLine.h"
  26. #include "llvm/Support/Debug.h"
  27. #include "llvm/Support/Format.h"
  28. #include "llvm/Support/ManagedStatic.h"
  29. #include "llvm/Support/Mutex.h"
  30. #include "llvm/Support/raw_ostream.h"
  31. #include <algorithm>
  32. #include <cstring>
  33. using namespace llvm;
  34. // CreateInfoOutputFile - Return a file stream to print our output on.
  35. namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
  36. /// -stats - Command line option to cause transformations to emit stats about
  37. /// what they did.
  38. ///
  39. #if 0 // HLSL Change Starts - option pending
  40. static cl::opt<bool>
  41. Enabled(
  42. "stats",
  43. cl::desc("Enable statistics output from program (available with Asserts)"));
  44. #else
  45. static const bool Enabled = false;
  46. #endif // HLSL Change Ends
  47. namespace {
  48. /// StatisticInfo - This class is used in a ManagedStatic so that it is created
  49. /// on demand (when the first statistic is bumped) and destroyed only when
  50. /// llvm_shutdown is called. We print statistics from the destructor.
  51. class StatisticInfo {
  52. std::vector<const Statistic*> Stats;
  53. friend void llvm::PrintStatistics();
  54. friend void llvm::PrintStatistics(raw_ostream &OS);
  55. public:
  56. ~StatisticInfo();
  57. void addStatistic(const Statistic *S) {
  58. Stats.push_back(S);
  59. }
  60. };
  61. }
  62. static ManagedStatic<StatisticInfo> StatInfo;
  63. static ManagedStatic<sys::SmartMutex<true> > StatLock;
  64. /// RegisterStatistic - The first time a statistic is bumped, this method is
  65. /// called.
  66. void Statistic::RegisterStatistic() {
  67. // If stats are enabled, inform StatInfo that this statistic should be
  68. // printed.
  69. sys::SmartScopedLock<true> Writer(*StatLock);
  70. if (!Initialized) {
  71. if (Enabled)
  72. StatInfo->addStatistic(this);
  73. TsanHappensBefore(this);
  74. sys::MemoryFence();
  75. // Remember we have been registered.
  76. TsanIgnoreWritesBegin();
  77. Initialized = true;
  78. TsanIgnoreWritesEnd();
  79. }
  80. }
  81. // Print information when destroyed, iff command line option is specified.
  82. StatisticInfo::~StatisticInfo() {
  83. llvm::PrintStatistics();
  84. }
  85. void llvm::EnableStatistics() {
  86. //Enabled.setValue(true); // HLSL Change
  87. }
  88. bool llvm::AreStatisticsEnabled() {
  89. return Enabled;
  90. }
  91. void llvm::PrintStatistics(raw_ostream &OS) {
  92. StatisticInfo &Stats = *StatInfo;
  93. // Figure out how long the biggest Value and Name fields are.
  94. unsigned MaxNameLen = 0, MaxValLen = 0;
  95. for (size_t i = 0, e = Stats.Stats.size(); i != e; ++i) {
  96. MaxValLen = std::max(MaxValLen,
  97. (unsigned)utostr(Stats.Stats[i]->getValue()).size());
  98. MaxNameLen = std::max(MaxNameLen,
  99. (unsigned)std::strlen(Stats.Stats[i]->getName()));
  100. }
  101. // Sort the fields by name.
  102. std::stable_sort(Stats.Stats.begin(), Stats.Stats.end(),
  103. [](const Statistic *LHS, const Statistic *RHS) {
  104. if (int Cmp = std::strcmp(LHS->getName(), RHS->getName()))
  105. return Cmp < 0;
  106. // Secondary key is the description.
  107. return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0;
  108. });
  109. // Print out the statistics header...
  110. OS << "===" << std::string(73, '-') << "===\n"
  111. << " ... Statistics Collected ...\n"
  112. << "===" << std::string(73, '-') << "===\n\n";
  113. // Print all of the statistics.
  114. for (size_t i = 0, e = Stats.Stats.size(); i != e; ++i)
  115. OS << format("%*u %-*s - %s\n",
  116. MaxValLen, Stats.Stats[i]->getValue(),
  117. MaxNameLen, Stats.Stats[i]->getName(),
  118. Stats.Stats[i]->getDesc());
  119. OS << '\n'; // Flush the output stream.
  120. OS.flush();
  121. }
  122. void llvm::PrintStatistics() {
  123. #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
  124. StatisticInfo &Stats = *StatInfo;
  125. // Statistics not enabled?
  126. if (Stats.Stats.empty()) return;
  127. // Get the stream to write to.
  128. raw_ostream &OutStream = *CreateInfoOutputFile();
  129. PrintStatistics(OutStream);
  130. delete &OutStream; // Close the file.
  131. #else
  132. // Check if the -stats option is set instead of checking
  133. // !Stats.Stats.empty(). In release builds, Statistics operators
  134. // do nothing, so stats are never Registered.
  135. if (Enabled) {
  136. // Get the stream to write to.
  137. raw_ostream &OutStream = *CreateInfoOutputFile();
  138. OutStream << "Statistics are disabled. "
  139. << "Build with asserts or with -DLLVM_ENABLE_STATS\n";
  140. OutStream.flush();
  141. delete &OutStream; // Close the file.
  142. }
  143. #endif
  144. }