Remark.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- llvm/Remarks/Remark.h - The remark type -----------------*- C++/-*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines an abstraction for handling remarks.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_REMARKS_REMARK_H
  18. #define LLVM_REMARKS_REMARK_H
  19. #include "llvm-c/Remarks.h"
  20. #include "llvm/ADT/SmallVector.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include "llvm/Support/CBindingWrapping.h"
  23. #include <optional>
  24. #include <string>
  25. namespace llvm {
  26. namespace remarks {
  27. /// The current version of the remark entry.
  28. constexpr uint64_t CurrentRemarkVersion = 0;
  29. /// The debug location used to track a remark back to the source file.
  30. struct RemarkLocation {
  31. /// Absolute path of the source file corresponding to this remark.
  32. StringRef SourceFilePath;
  33. unsigned SourceLine = 0;
  34. unsigned SourceColumn = 0;
  35. };
  36. // Create wrappers for C Binding types (see CBindingWrapping.h).
  37. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RemarkLocation, LLVMRemarkDebugLocRef)
  38. /// A key-value pair with a debug location that is used to display the remarks
  39. /// at the right place in the source.
  40. struct Argument {
  41. StringRef Key;
  42. // FIXME: We might want to be able to store other types than strings here.
  43. StringRef Val;
  44. // If set, the debug location corresponding to the value.
  45. std::optional<RemarkLocation> Loc;
  46. };
  47. // Create wrappers for C Binding types (see CBindingWrapping.h).
  48. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Argument, LLVMRemarkArgRef)
  49. /// The type of the remark.
  50. enum class Type {
  51. Unknown,
  52. Passed,
  53. Missed,
  54. Analysis,
  55. AnalysisFPCommute,
  56. AnalysisAliasing,
  57. Failure,
  58. First = Unknown,
  59. Last = Failure
  60. };
  61. /// A remark type used for both emission and parsing.
  62. struct Remark {
  63. /// The type of the remark.
  64. Type RemarkType = Type::Unknown;
  65. /// Name of the pass that triggers the emission of this remark.
  66. StringRef PassName;
  67. /// Textual identifier for the remark (single-word, camel-case). Can be used
  68. /// by external tools reading the output file for remarks to identify the
  69. /// remark.
  70. StringRef RemarkName;
  71. /// Mangled name of the function that triggers the emssion of this remark.
  72. StringRef FunctionName;
  73. /// The location in the source file of the remark.
  74. std::optional<RemarkLocation> Loc;
  75. /// If profile information is available, this is the number of times the
  76. /// corresponding code was executed in a profile instrumentation run.
  77. std::optional<uint64_t> Hotness;
  78. /// Arguments collected via the streaming interface.
  79. SmallVector<Argument, 5> Args;
  80. Remark() = default;
  81. Remark(Remark &&) = default;
  82. Remark &operator=(Remark &&) = default;
  83. /// Return a message composed from the arguments as a string.
  84. std::string getArgsAsMsg() const;
  85. /// Clone this remark to explicitly ask for a copy.
  86. Remark clone() const { return *this; }
  87. private:
  88. /// In order to avoid unwanted copies, "delete" the copy constructor.
  89. /// If a copy is needed, it should be done through `Remark::clone()`.
  90. Remark(const Remark &) = default;
  91. Remark& operator=(const Remark &) = default;
  92. };
  93. // Create wrappers for C Binding types (see CBindingWrapping.h).
  94. DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Remark, LLVMRemarkEntryRef)
  95. /// Comparison operators for Remark objects and dependent objects.
  96. template <typename T>
  97. bool operator<(const std::optional<T> &LHS, const std::optional<T> &RHS) {
  98. // Sorting based on optionals should result in all `None` entries to appear
  99. // before the valid entries. For example, remarks with no debug location will
  100. // appear first.
  101. if (!LHS && !RHS)
  102. return false;
  103. if (!LHS && RHS)
  104. return true;
  105. if (LHS && !RHS)
  106. return false;
  107. return *LHS < *RHS;
  108. }
  109. inline bool operator==(const RemarkLocation &LHS, const RemarkLocation &RHS) {
  110. return LHS.SourceFilePath == RHS.SourceFilePath &&
  111. LHS.SourceLine == RHS.SourceLine &&
  112. LHS.SourceColumn == RHS.SourceColumn;
  113. }
  114. inline bool operator!=(const RemarkLocation &LHS, const RemarkLocation &RHS) {
  115. return !(LHS == RHS);
  116. }
  117. inline bool operator<(const RemarkLocation &LHS, const RemarkLocation &RHS) {
  118. return std::make_tuple(LHS.SourceFilePath, LHS.SourceLine, LHS.SourceColumn) <
  119. std::make_tuple(RHS.SourceFilePath, RHS.SourceLine, RHS.SourceColumn);
  120. }
  121. inline bool operator==(const Argument &LHS, const Argument &RHS) {
  122. return LHS.Key == RHS.Key && LHS.Val == RHS.Val && LHS.Loc == RHS.Loc;
  123. }
  124. inline bool operator!=(const Argument &LHS, const Argument &RHS) {
  125. return !(LHS == RHS);
  126. }
  127. inline bool operator<(const Argument &LHS, const Argument &RHS) {
  128. return std::make_tuple(LHS.Key, LHS.Val, LHS.Loc) <
  129. std::make_tuple(RHS.Key, RHS.Val, RHS.Loc);
  130. }
  131. inline bool operator==(const Remark &LHS, const Remark &RHS) {
  132. return LHS.RemarkType == RHS.RemarkType && LHS.PassName == RHS.PassName &&
  133. LHS.RemarkName == RHS.RemarkName &&
  134. LHS.FunctionName == RHS.FunctionName && LHS.Loc == RHS.Loc &&
  135. LHS.Hotness == RHS.Hotness && LHS.Args == RHS.Args;
  136. }
  137. inline bool operator!=(const Remark &LHS, const Remark &RHS) {
  138. return !(LHS == RHS);
  139. }
  140. inline bool operator<(const Remark &LHS, const Remark &RHS) {
  141. return std::make_tuple(LHS.RemarkType, LHS.PassName, LHS.RemarkName,
  142. LHS.FunctionName, LHS.Loc, LHS.Hotness, LHS.Args) <
  143. std::make_tuple(RHS.RemarkType, RHS.PassName, RHS.RemarkName,
  144. RHS.FunctionName, RHS.Loc, RHS.Hotness, RHS.Args);
  145. }
  146. } // end namespace remarks
  147. } // end namespace llvm
  148. #endif /* LLVM_REMARKS_REMARK_H */
  149. #ifdef __GNUC__
  150. #pragma GCC diagnostic pop
  151. #endif