xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Remarks/Remark.h (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
10b57cec5SDimitry Andric //===-- llvm/Remarks/Remark.h - The remark type -----------------*- C++/-*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines an abstraction for handling remarks.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_REMARKS_REMARK_H
140b57cec5SDimitry Andric #define LLVM_REMARKS_REMARK_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm-c/Remarks.h"
170b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
18*5ffd83dbSDimitry Andric #include "llvm/ADT/SmallVector.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
200b57cec5SDimitry Andric #include "llvm/Support/CBindingWrapping.h"
210b57cec5SDimitry Andric #include <string>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace llvm {
240b57cec5SDimitry Andric namespace remarks {
250b57cec5SDimitry Andric 
268bcb0991SDimitry Andric /// The current version of the remark entry.
278bcb0991SDimitry Andric constexpr uint64_t CurrentRemarkVersion = 0;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric /// The debug location used to track a remark back to the source file.
300b57cec5SDimitry Andric struct RemarkLocation {
310b57cec5SDimitry Andric   /// Absolute path of the source file corresponding to this remark.
320b57cec5SDimitry Andric   StringRef SourceFilePath;
33480093f4SDimitry Andric   unsigned SourceLine = 0;
34480093f4SDimitry Andric   unsigned SourceColumn = 0;
350b57cec5SDimitry Andric };
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric // Create wrappers for C Binding types (see CBindingWrapping.h).
380b57cec5SDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RemarkLocation, LLVMRemarkDebugLocRef)
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric /// A key-value pair with a debug location that is used to display the remarks
410b57cec5SDimitry Andric /// at the right place in the source.
420b57cec5SDimitry Andric struct Argument {
430b57cec5SDimitry Andric   StringRef Key;
440b57cec5SDimitry Andric   // FIXME: We might want to be able to store other types than strings here.
450b57cec5SDimitry Andric   StringRef Val;
460b57cec5SDimitry Andric   // If set, the debug location corresponding to the value.
470b57cec5SDimitry Andric   Optional<RemarkLocation> Loc;
480b57cec5SDimitry Andric };
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric // Create wrappers for C Binding types (see CBindingWrapping.h).
510b57cec5SDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Argument, LLVMRemarkArgRef)
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric /// The type of the remark.
540b57cec5SDimitry Andric enum class Type {
550b57cec5SDimitry Andric   Unknown,
560b57cec5SDimitry Andric   Passed,
570b57cec5SDimitry Andric   Missed,
580b57cec5SDimitry Andric   Analysis,
590b57cec5SDimitry Andric   AnalysisFPCommute,
600b57cec5SDimitry Andric   AnalysisAliasing,
610b57cec5SDimitry Andric   Failure,
628bcb0991SDimitry Andric   First = Unknown,
638bcb0991SDimitry Andric   Last = Failure
640b57cec5SDimitry Andric };
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric /// A remark type used for both emission and parsing.
670b57cec5SDimitry Andric struct Remark {
680b57cec5SDimitry Andric   /// The type of the remark.
690b57cec5SDimitry Andric   Type RemarkType = Type::Unknown;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   /// Name of the pass that triggers the emission of this remark.
720b57cec5SDimitry Andric   StringRef PassName;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   /// Textual identifier for the remark (single-word, camel-case). Can be used
750b57cec5SDimitry Andric   /// by external tools reading the output file for remarks to identify the
760b57cec5SDimitry Andric   /// remark.
770b57cec5SDimitry Andric   StringRef RemarkName;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   /// Mangled name of the function that triggers the emssion of this remark.
800b57cec5SDimitry Andric   StringRef FunctionName;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   /// The location in the source file of the remark.
830b57cec5SDimitry Andric   Optional<RemarkLocation> Loc;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// If profile information is available, this is the number of times the
860b57cec5SDimitry Andric   /// corresponding code was executed in a profile instrumentation run.
870b57cec5SDimitry Andric   Optional<uint64_t> Hotness;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   /// Arguments collected via the streaming interface.
900b57cec5SDimitry Andric   SmallVector<Argument, 5> Args;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   Remark() = default;
930b57cec5SDimitry Andric   Remark(Remark &&) = default;
940b57cec5SDimitry Andric   Remark &operator=(Remark &&) = default;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   /// Return a message composed from the arguments as a string.
970b57cec5SDimitry Andric   std::string getArgsAsMsg() const;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   /// Clone this remark to explicitly ask for a copy.
1000b57cec5SDimitry Andric   Remark clone() const { return *this; }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric private:
1030b57cec5SDimitry Andric   /// In order to avoid unwanted copies, "delete" the copy constructor.
1040b57cec5SDimitry Andric   /// If a copy is needed, it should be done through `Remark::clone()`.
1050b57cec5SDimitry Andric   Remark(const Remark &) = default;
1060b57cec5SDimitry Andric   Remark& operator=(const Remark &) = default;
1070b57cec5SDimitry Andric };
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric // Create wrappers for C Binding types (see CBindingWrapping.h).
1100b57cec5SDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Remark, LLVMRemarkEntryRef)
1110b57cec5SDimitry Andric 
1128bcb0991SDimitry Andric /// Comparison operators for Remark objects and dependent objects.
113480093f4SDimitry Andric 
114480093f4SDimitry Andric template <typename T>
115480093f4SDimitry Andric bool operator<(const Optional<T> &LHS, const Optional<T> &RHS) {
116480093f4SDimitry Andric   // Sorting based on optionals should result in all `None` entries to appear
117480093f4SDimitry Andric   // before the valid entries. For example, remarks with no debug location will
118480093f4SDimitry Andric   // appear first.
119480093f4SDimitry Andric   if (!LHS && !RHS)
120480093f4SDimitry Andric     return false;
121480093f4SDimitry Andric   if (!LHS && RHS)
122480093f4SDimitry Andric     return true;
123480093f4SDimitry Andric   if (LHS && !RHS)
124480093f4SDimitry Andric     return false;
125480093f4SDimitry Andric   return *LHS < *RHS;
126480093f4SDimitry Andric }
127480093f4SDimitry Andric 
1288bcb0991SDimitry Andric inline bool operator==(const RemarkLocation &LHS, const RemarkLocation &RHS) {
1298bcb0991SDimitry Andric   return LHS.SourceFilePath == RHS.SourceFilePath &&
1308bcb0991SDimitry Andric          LHS.SourceLine == RHS.SourceLine &&
1318bcb0991SDimitry Andric          LHS.SourceColumn == RHS.SourceColumn;
1328bcb0991SDimitry Andric }
1338bcb0991SDimitry Andric 
1348bcb0991SDimitry Andric inline bool operator!=(const RemarkLocation &LHS, const RemarkLocation &RHS) {
1358bcb0991SDimitry Andric   return !(LHS == RHS);
1368bcb0991SDimitry Andric }
1378bcb0991SDimitry Andric 
138480093f4SDimitry Andric inline bool operator<(const RemarkLocation &LHS, const RemarkLocation &RHS) {
139480093f4SDimitry Andric   return std::make_tuple(LHS.SourceFilePath, LHS.SourceLine, LHS.SourceColumn) <
140480093f4SDimitry Andric          std::make_tuple(RHS.SourceFilePath, RHS.SourceLine, RHS.SourceColumn);
141480093f4SDimitry Andric }
142480093f4SDimitry Andric 
1438bcb0991SDimitry Andric inline bool operator==(const Argument &LHS, const Argument &RHS) {
1448bcb0991SDimitry Andric   return LHS.Key == RHS.Key && LHS.Val == RHS.Val && LHS.Loc == RHS.Loc;
1458bcb0991SDimitry Andric }
1468bcb0991SDimitry Andric 
1478bcb0991SDimitry Andric inline bool operator!=(const Argument &LHS, const Argument &RHS) {
1488bcb0991SDimitry Andric   return !(LHS == RHS);
1498bcb0991SDimitry Andric }
1508bcb0991SDimitry Andric 
151480093f4SDimitry Andric inline bool operator<(const Argument &LHS, const Argument &RHS) {
152480093f4SDimitry Andric   return std::make_tuple(LHS.Key, LHS.Val, LHS.Loc) <
153480093f4SDimitry Andric          std::make_tuple(RHS.Key, RHS.Val, RHS.Loc);
154480093f4SDimitry Andric }
155480093f4SDimitry Andric 
1568bcb0991SDimitry Andric inline bool operator==(const Remark &LHS, const Remark &RHS) {
1578bcb0991SDimitry Andric   return LHS.RemarkType == RHS.RemarkType && LHS.PassName == RHS.PassName &&
1588bcb0991SDimitry Andric          LHS.RemarkName == RHS.RemarkName &&
1598bcb0991SDimitry Andric          LHS.FunctionName == RHS.FunctionName && LHS.Loc == RHS.Loc &&
1608bcb0991SDimitry Andric          LHS.Hotness == RHS.Hotness && LHS.Args == RHS.Args;
1618bcb0991SDimitry Andric }
1628bcb0991SDimitry Andric 
1638bcb0991SDimitry Andric inline bool operator!=(const Remark &LHS, const Remark &RHS) {
1648bcb0991SDimitry Andric   return !(LHS == RHS);
1658bcb0991SDimitry Andric }
1668bcb0991SDimitry Andric 
167480093f4SDimitry Andric inline bool operator<(const Remark &LHS, const Remark &RHS) {
168480093f4SDimitry Andric   return std::make_tuple(LHS.RemarkType, LHS.PassName, LHS.RemarkName,
169480093f4SDimitry Andric                          LHS.FunctionName, LHS.Loc, LHS.Hotness, LHS.Args) <
170480093f4SDimitry Andric          std::make_tuple(RHS.RemarkType, RHS.PassName, RHS.RemarkName,
171480093f4SDimitry Andric                          RHS.FunctionName, RHS.Loc, RHS.Hotness, RHS.Args);
172480093f4SDimitry Andric }
173480093f4SDimitry Andric 
1740b57cec5SDimitry Andric } // end namespace remarks
1750b57cec5SDimitry Andric } // end namespace llvm
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric #endif /* LLVM_REMARKS_REMARK_H */
178