Remark.h 5.7 KB

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