Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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 | |||
13 | #ifndef LLVM_REMARKS_REMARK_H |
||
14 | #define LLVM_REMARKS_REMARK_H |
||
15 | |||
16 | #include "llvm-c/Remarks.h" |
||
17 | #include "llvm/ADT/SmallVector.h" |
||
18 | #include "llvm/ADT/StringRef.h" |
||
19 | #include "llvm/Support/CBindingWrapping.h" |
||
20 | #include <optional> |
||
21 | #include <string> |
||
22 | |||
23 | namespace llvm { |
||
24 | namespace remarks { |
||
25 | |||
26 | /// The current version of the remark entry. |
||
27 | constexpr uint64_t CurrentRemarkVersion = 0; |
||
28 | |||
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 | |||
37 | // Create wrappers for C Binding types (see CBindingWrapping.h). |
||
38 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RemarkLocation, LLVMRemarkDebugLocRef) |
||
39 | |||
40 | /// A key-value pair with a debug location that is used to display the remarks |
||
41 | /// at the right place in the source. |
||
42 | struct Argument { |
||
43 | StringRef Key; |
||
44 | // FIXME: We might want to be able to store other types than strings here. |
||
45 | StringRef Val; |
||
46 | // If set, the debug location corresponding to the value. |
||
47 | std::optional<RemarkLocation> Loc; |
||
48 | }; |
||
49 | |||
50 | // Create wrappers for C Binding types (see CBindingWrapping.h). |
||
51 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Argument, LLVMRemarkArgRef) |
||
52 | |||
53 | /// The type of the remark. |
||
54 | enum class Type { |
||
55 | Unknown, |
||
56 | Passed, |
||
57 | Missed, |
||
58 | Analysis, |
||
59 | AnalysisFPCommute, |
||
60 | AnalysisAliasing, |
||
61 | Failure, |
||
62 | First = Unknown, |
||
63 | Last = Failure |
||
64 | }; |
||
65 | |||
66 | /// A remark type used for both emission and parsing. |
||
67 | struct Remark { |
||
68 | /// The type of the remark. |
||
69 | Type RemarkType = Type::Unknown; |
||
70 | |||
71 | /// Name of the pass that triggers the emission of this remark. |
||
72 | StringRef PassName; |
||
73 | |||
74 | /// Textual identifier for the remark (single-word, camel-case). Can be used |
||
75 | /// by external tools reading the output file for remarks to identify the |
||
76 | /// remark. |
||
77 | StringRef RemarkName; |
||
78 | |||
79 | /// Mangled name of the function that triggers the emssion of this remark. |
||
80 | StringRef FunctionName; |
||
81 | |||
82 | /// The location in the source file of the remark. |
||
83 | std::optional<RemarkLocation> Loc; |
||
84 | |||
85 | /// If profile information is available, this is the number of times the |
||
86 | /// corresponding code was executed in a profile instrumentation run. |
||
87 | std::optional<uint64_t> Hotness; |
||
88 | |||
89 | /// Arguments collected via the streaming interface. |
||
90 | SmallVector<Argument, 5> Args; |
||
91 | |||
92 | Remark() = default; |
||
93 | Remark(Remark &&) = default; |
||
94 | Remark &operator=(Remark &&) = default; |
||
95 | |||
96 | /// Return a message composed from the arguments as a string. |
||
97 | std::string getArgsAsMsg() const; |
||
98 | |||
99 | /// Clone this remark to explicitly ask for a copy. |
||
100 | Remark clone() const { return *this; } |
||
101 | |||
102 | private: |
||
103 | /// In order to avoid unwanted copies, "delete" the copy constructor. |
||
104 | /// If a copy is needed, it should be done through `Remark::clone()`. |
||
105 | Remark(const Remark &) = default; |
||
106 | Remark& operator=(const Remark &) = default; |
||
107 | }; |
||
108 | |||
109 | // Create wrappers for C Binding types (see CBindingWrapping.h). |
||
110 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Remark, LLVMRemarkEntryRef) |
||
111 | |||
112 | /// Comparison operators for Remark objects and dependent objects. |
||
113 | |||
114 | template <typename T> |
||
115 | bool operator<(const std::optional<T> &LHS, const std::optional<T> &RHS) { |
||
116 | // Sorting based on optionals should result in all `None` entries to appear |
||
117 | // before the valid entries. For example, remarks with no debug location will |
||
118 | // appear first. |
||
119 | if (!LHS && !RHS) |
||
120 | return false; |
||
121 | if (!LHS && RHS) |
||
122 | return true; |
||
123 | if (LHS && !RHS) |
||
124 | return false; |
||
125 | return *LHS < *RHS; |
||
126 | } |
||
127 | |||
128 | inline bool operator==(const RemarkLocation &LHS, const RemarkLocation &RHS) { |
||
129 | return LHS.SourceFilePath == RHS.SourceFilePath && |
||
130 | LHS.SourceLine == RHS.SourceLine && |
||
131 | LHS.SourceColumn == RHS.SourceColumn; |
||
132 | } |
||
133 | |||
134 | inline bool operator!=(const RemarkLocation &LHS, const RemarkLocation &RHS) { |
||
135 | return !(LHS == RHS); |
||
136 | } |
||
137 | |||
138 | inline bool operator<(const RemarkLocation &LHS, const RemarkLocation &RHS) { |
||
139 | return std::make_tuple(LHS.SourceFilePath, LHS.SourceLine, LHS.SourceColumn) < |
||
140 | std::make_tuple(RHS.SourceFilePath, RHS.SourceLine, RHS.SourceColumn); |
||
141 | } |
||
142 | |||
143 | inline bool operator==(const Argument &LHS, const Argument &RHS) { |
||
144 | return LHS.Key == RHS.Key && LHS.Val == RHS.Val && LHS.Loc == RHS.Loc; |
||
145 | } |
||
146 | |||
147 | inline bool operator!=(const Argument &LHS, const Argument &RHS) { |
||
148 | return !(LHS == RHS); |
||
149 | } |
||
150 | |||
151 | inline bool operator<(const Argument &LHS, const Argument &RHS) { |
||
152 | return std::make_tuple(LHS.Key, LHS.Val, LHS.Loc) < |
||
153 | std::make_tuple(RHS.Key, RHS.Val, RHS.Loc); |
||
154 | } |
||
155 | |||
156 | inline bool operator==(const Remark &LHS, const Remark &RHS) { |
||
157 | return LHS.RemarkType == RHS.RemarkType && LHS.PassName == RHS.PassName && |
||
158 | LHS.RemarkName == RHS.RemarkName && |
||
159 | LHS.FunctionName == RHS.FunctionName && LHS.Loc == RHS.Loc && |
||
160 | LHS.Hotness == RHS.Hotness && LHS.Args == RHS.Args; |
||
161 | } |
||
162 | |||
163 | inline bool operator!=(const Remark &LHS, const Remark &RHS) { |
||
164 | return !(LHS == RHS); |
||
165 | } |
||
166 | |||
167 | inline bool operator<(const Remark &LHS, const Remark &RHS) { |
||
168 | return std::make_tuple(LHS.RemarkType, LHS.PassName, LHS.RemarkName, |
||
169 | LHS.FunctionName, LHS.Loc, LHS.Hotness, LHS.Args) < |
||
170 | std::make_tuple(RHS.RemarkType, RHS.PassName, RHS.RemarkName, |
||
171 | RHS.FunctionName, RHS.Loc, RHS.Hotness, RHS.Args); |
||
172 | } |
||
173 | |||
174 | } // end namespace remarks |
||
175 | } // end namespace llvm |
||
176 | |||
177 | #endif /* LLVM_REMARKS_REMARK_H */ |