/home/arjun/llvm-project/mlir/include/mlir/IR/Location.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Location.h - MLIR Location Classes -----------------------*- 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 | | // These classes provide the ability to relate MLIR objects back to source |
10 | | // location position information. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef MLIR_IR_LOCATION_H |
15 | | #define MLIR_IR_LOCATION_H |
16 | | |
17 | | #include "mlir/IR/Attributes.h" |
18 | | #include "llvm/Support/PointerLikeTypeTraits.h" |
19 | | |
20 | | namespace mlir { |
21 | | |
22 | | class Attribute; |
23 | | class MLIRContext; |
24 | | class Identifier; |
25 | | |
26 | | namespace detail { |
27 | | |
28 | | struct CallSiteLocationStorage; |
29 | | struct FileLineColLocationStorage; |
30 | | struct FusedLocationStorage; |
31 | | struct LocationStorage; |
32 | | struct NameLocationStorage; |
33 | | struct OpaqueLocationStorage; |
34 | | struct UnknownLocationStorage; |
35 | | |
36 | | } // namespace detail |
37 | | |
38 | | /// Location objects represent source locations information in MLIR. |
39 | | /// LocationAttr acts as the anchor for all Location based attributes. |
40 | | class LocationAttr : public Attribute { |
41 | | public: |
42 | | using Attribute::Attribute; |
43 | | |
44 | | /// Methods for support type inquiry through isa, cast, and dyn_cast. |
45 | 0 | static bool classof(Attribute attr) { |
46 | 0 | return attr.getKind() >= StandardAttributes::FIRST_LOCATION_ATTR && |
47 | 0 | attr.getKind() <= StandardAttributes::LAST_LOCATION_ATTR; |
48 | 0 | } |
49 | | }; |
50 | | |
51 | | /// This class defines the main interface for locations in MLIR and acts as a |
52 | | /// non-nullable wrapper around a LocationAttr. |
53 | | class Location { |
54 | | public: |
55 | 0 | Location(LocationAttr loc) : impl(loc) { |
56 | 0 | assert(loc && "location should never be null."); |
57 | 0 | } |
58 | 0 | Location(const LocationAttr::ImplType *impl) : impl(impl) { |
59 | 0 | assert(impl && "location should never be null."); |
60 | 0 | } |
61 | | |
62 | | /// Return the context this location is uniqued in. |
63 | 0 | MLIRContext *getContext() const { return impl.getContext(); } |
64 | | |
65 | | /// Access the impl location attribute. |
66 | 0 | operator LocationAttr() const { return impl; } |
67 | 0 | LocationAttr *operator->() const { return const_cast<LocationAttr *>(&impl); } |
68 | | |
69 | | /// Type casting utilities on the underlying location. |
70 | 0 | template <typename U> bool isa() const { return impl.isa<U>(); } Unexecuted instantiation: _ZNK4mlir8Location3isaINS_10UnknownLocEEEbv Unexecuted instantiation: _ZNK4mlir8Location3isaINS_7NameLocEEEbv Unexecuted instantiation: _ZNK4mlir8Location3isaINS_14FileLineColLocEEEbv |
71 | 0 | template <typename U> U dyn_cast() const { return impl.dyn_cast<U>(); } |
72 | 0 | template <typename U> U cast() const { return impl.cast<U>(); } Unexecuted instantiation: _ZNK4mlir8Location4castINS_7NameLocEEET_v Unexecuted instantiation: _ZNK4mlir8Location4castINS_14FileLineColLocEEET_v Unexecuted instantiation: _ZNK4mlir8Location4castINS_11CallSiteLocEEET_v Unexecuted instantiation: _ZNK4mlir8Location4castINS_8FusedLocEEET_v |
73 | | |
74 | | /// Comparison operators. |
75 | 0 | bool operator==(Location rhs) const { return impl == rhs.impl; } |
76 | 0 | bool operator!=(Location rhs) const { return !(*this == rhs); } |
77 | | |
78 | | /// Print the location. |
79 | 0 | void print(raw_ostream &os) const { impl.print(os); } |
80 | 0 | void dump() const { impl.dump(); } |
81 | | |
82 | | friend ::llvm::hash_code hash_value(Location arg); |
83 | | |
84 | | /// Methods for supporting PointerLikeTypeTraits. |
85 | 0 | const void *getAsOpaquePointer() const { return impl.getAsOpaquePointer(); } |
86 | 0 | static Location getFromOpaquePointer(const void *pointer) { |
87 | 0 | return LocationAttr(reinterpret_cast<const AttributeStorage *>(pointer)); |
88 | 0 | } |
89 | | |
90 | | protected: |
91 | | /// The internal backing location attribute. |
92 | | LocationAttr impl; |
93 | | }; |
94 | | |
95 | 0 | inline raw_ostream &operator<<(raw_ostream &os, const Location &loc) { |
96 | 0 | loc.print(os); |
97 | 0 | return os; |
98 | 0 | } |
99 | | |
100 | | /// Represents a location as call site. "callee" is the concrete location |
101 | | /// (Unknown/NameLocation/FileLineColLoc/OpaqueLoc) and "caller" points to the |
102 | | /// caller's location (another CallLocation or a concrete location). Multiple |
103 | | /// CallSiteLocs can be chained to form a call stack. |
104 | | class CallSiteLoc |
105 | | : public Attribute::AttrBase<CallSiteLoc, LocationAttr, |
106 | | detail::CallSiteLocationStorage> { |
107 | | public: |
108 | | using Base::Base; |
109 | | |
110 | | /// Return a uniqued call location object. |
111 | | static Location get(Location callee, Location caller); |
112 | | |
113 | | /// Return a call site location which represents a name reference in one line |
114 | | /// or a stack of frames. The input frames are ordered from innermost to |
115 | | /// outermost. |
116 | | static Location get(Location name, ArrayRef<Location> frames); |
117 | | |
118 | | /// The concrete location information this object presents. |
119 | | Location getCallee() const; |
120 | | |
121 | | /// The caller's location. |
122 | | Location getCaller() const; |
123 | | |
124 | | /// Methods for support type inquiry through isa, cast, and dyn_cast. |
125 | 0 | static bool kindof(unsigned kind) { |
126 | 0 | return kind == StandardAttributes::CallSiteLocation; |
127 | 0 | } |
128 | | }; |
129 | | |
130 | | /// Represents a location derived from a file/line/column location. The column |
131 | | /// and line may be zero to represent unknown column and/or unknown line/column |
132 | | /// information. |
133 | | class FileLineColLoc |
134 | | : public Attribute::AttrBase<FileLineColLoc, LocationAttr, |
135 | | detail::FileLineColLocationStorage> { |
136 | | public: |
137 | | using Base::Base; |
138 | | |
139 | | /// Return a uniqued FileLineCol location object. |
140 | | static Location get(Identifier filename, unsigned line, unsigned column, |
141 | | MLIRContext *context); |
142 | | static Location get(StringRef filename, unsigned line, unsigned column, |
143 | | MLIRContext *context); |
144 | | |
145 | | StringRef getFilename() const; |
146 | | |
147 | | unsigned getLine() const; |
148 | | unsigned getColumn() const; |
149 | | |
150 | | /// Methods for support type inquiry through isa, cast, and dyn_cast. |
151 | 0 | static bool kindof(unsigned kind) { |
152 | 0 | return kind == StandardAttributes::FileLineColLocation; |
153 | 0 | } |
154 | | }; |
155 | | |
156 | | /// Represents a value composed of multiple source constructs, with an optional |
157 | | /// metadata attribute. |
158 | | class FusedLoc : public Attribute::AttrBase<FusedLoc, LocationAttr, |
159 | | detail::FusedLocationStorage> { |
160 | | public: |
161 | | using Base::Base; |
162 | | |
163 | | /// Return a uniqued Fused Location object. The first location in the list |
164 | | /// will get precedence during diagnostic emission, with the rest being |
165 | | /// displayed as supplementary "fused from here" style notes. |
166 | | static Location get(ArrayRef<Location> locs, Attribute metadata, |
167 | | MLIRContext *context); |
168 | 0 | static Location get(ArrayRef<Location> locs, MLIRContext *context) { |
169 | 0 | return get(locs, Attribute(), context); |
170 | 0 | } |
171 | | |
172 | | ArrayRef<Location> getLocations() const; |
173 | | |
174 | | /// Returns the optional metadata attached to this fused location. Given that |
175 | | /// it is optional, the return value may be a null node. |
176 | | Attribute getMetadata() const; |
177 | | |
178 | | /// Methods for support type inquiry through isa, cast, and dyn_cast. |
179 | 0 | static bool kindof(unsigned kind) { |
180 | 0 | return kind == StandardAttributes::FusedLocation; |
181 | 0 | } |
182 | | }; |
183 | | |
184 | | /// Represents an identity name attached to a child location. |
185 | | class NameLoc : public Attribute::AttrBase<NameLoc, LocationAttr, |
186 | | detail::NameLocationStorage> { |
187 | | public: |
188 | | using Base::Base; |
189 | | |
190 | | /// Return a uniqued name location object. The child location must not be |
191 | | /// another NameLoc. |
192 | | static Location get(Identifier name, Location child); |
193 | | |
194 | | /// Return a uniqued name location object with an unknown child. |
195 | | static Location get(Identifier name, MLIRContext *context); |
196 | | |
197 | | /// Return the name identifier. |
198 | | Identifier getName() const; |
199 | | |
200 | | /// Return the child location. |
201 | | Location getChildLoc() const; |
202 | | |
203 | | /// Methods for support type inquiry through isa, cast, and dyn_cast. |
204 | 0 | static bool kindof(unsigned kind) { |
205 | 0 | return kind == StandardAttributes::NameLocation; |
206 | 0 | } |
207 | | }; |
208 | | |
209 | | /// Represents an unknown location. This is always a singleton for a given |
210 | | /// MLIRContext. |
211 | | class UnknownLoc : public Attribute::AttrBase<UnknownLoc, LocationAttr> { |
212 | | public: |
213 | | using Base::Base; |
214 | | |
215 | | /// Get an instance of the UnknownLoc. |
216 | | static Location get(MLIRContext *context); |
217 | | |
218 | | /// Methods for support type inquiry through isa, cast, and dyn_cast. |
219 | 0 | static bool kindof(unsigned kind) { |
220 | 0 | return kind == StandardAttributes::UnknownLocation; |
221 | 0 | } |
222 | | }; |
223 | | |
224 | | /// Represents a location that is external to MLIR. Contains a pointer to some |
225 | | /// data structure and an optional location that can be used if the first one is |
226 | | /// not suitable. Since it contains an external structure, only optional |
227 | | /// location is used during serialization. |
228 | | /// The class also provides a number of methods for making type-safe casts |
229 | | /// between a pointer to an object and opaque location. |
230 | | class OpaqueLoc : public Attribute::AttrBase<OpaqueLoc, LocationAttr, |
231 | | detail::OpaqueLocationStorage> { |
232 | | public: |
233 | | using Base::Base; |
234 | | |
235 | | /// Returns an instance of opaque location which contains a given pointer to |
236 | | /// an object. The corresponding MLIR location is set to UnknownLoc. |
237 | | template <typename T> |
238 | | static Location get(T underlyingLocation, MLIRContext *context) { |
239 | | return get(reinterpret_cast<uintptr_t>(underlyingLocation), |
240 | | TypeID::get<T>(), UnknownLoc::get(context)); |
241 | | } |
242 | | |
243 | | /// Returns an instance of opaque location which contains a given pointer to |
244 | | /// an object and an additional MLIR location. |
245 | | template <typename T> |
246 | | static Location get(T underlyingLocation, Location fallbackLocation) { |
247 | | return get(reinterpret_cast<uintptr_t>(underlyingLocation), |
248 | | TypeID::get<T>(), fallbackLocation); |
249 | | } |
250 | | |
251 | | /// Returns a pointer to some data structure that opaque location stores. |
252 | | template <typename T> static T getUnderlyingLocation(Location location) { |
253 | | assert(isa<T>(location)); |
254 | | return reinterpret_cast<T>( |
255 | | location.cast<mlir::OpaqueLoc>().getUnderlyingLocation()); |
256 | | } |
257 | | |
258 | | /// Returns a pointer to some data structure that opaque location stores. |
259 | | /// Returns nullptr if provided location is not opaque location or if it |
260 | | /// contains a pointer of different type. |
261 | | template <typename T> |
262 | | static T getUnderlyingLocationOrNull(Location location) { |
263 | | return isa<T>(location) |
264 | | ? reinterpret_cast<T>( |
265 | | location.cast<mlir::OpaqueLoc>().getUnderlyingLocation()) |
266 | | : T(nullptr); |
267 | | } |
268 | | |
269 | | /// Checks whether provided location is opaque location and contains a pointer |
270 | | /// to an object of particular type. |
271 | | template <typename T> static bool isa(Location location) { |
272 | | auto opaque_loc = location.dyn_cast<OpaqueLoc>(); |
273 | | return opaque_loc && opaque_loc.getUnderlyingTypeID() == TypeID::get<T>(); |
274 | | } |
275 | | |
276 | | /// Returns a pointer to the corresponding object. |
277 | | uintptr_t getUnderlyingLocation() const; |
278 | | |
279 | | /// Returns a TypeID that represents the underlying objects c++ type. |
280 | | TypeID getUnderlyingTypeID() const; |
281 | | |
282 | | /// Returns a fallback location. |
283 | | Location getFallbackLocation() const; |
284 | | |
285 | | /// Methods for support type inquiry through isa, cast, and dyn_cast. |
286 | 0 | static bool kindof(unsigned kind) { |
287 | 0 | return kind == StandardAttributes::OpaqueLocation; |
288 | 0 | } |
289 | | |
290 | | private: |
291 | | static Location get(uintptr_t underlyingLocation, TypeID typeID, |
292 | | Location fallbackLocation); |
293 | | }; |
294 | | |
295 | | // Make Location hashable. |
296 | 0 | inline ::llvm::hash_code hash_value(Location arg) { |
297 | 0 | return hash_value(arg.impl); |
298 | 0 | } |
299 | | |
300 | | } // end namespace mlir |
301 | | |
302 | | namespace llvm { |
303 | | |
304 | | // Type hash just like pointers. |
305 | | template <> struct DenseMapInfo<mlir::Location> { |
306 | 0 | static mlir::Location getEmptyKey() { |
307 | 0 | auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey(); |
308 | 0 | return mlir::Location::getFromOpaquePointer(pointer); |
309 | 0 | } |
310 | 0 | static mlir::Location getTombstoneKey() { |
311 | 0 | auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey(); |
312 | 0 | return mlir::Location::getFromOpaquePointer(pointer); |
313 | 0 | } |
314 | 0 | static unsigned getHashValue(mlir::Location val) { |
315 | 0 | return mlir::hash_value(val); |
316 | 0 | } |
317 | 0 | static bool isEqual(mlir::Location LHS, mlir::Location RHS) { |
318 | 0 | return LHS == RHS; |
319 | 0 | } |
320 | | }; |
321 | | |
322 | | /// We align LocationStorage by 8, so allow LLVM to steal the low bits. |
323 | | template <> struct PointerLikeTypeTraits<mlir::Location> { |
324 | | public: |
325 | 0 | static inline void *getAsVoidPointer(mlir::Location I) { |
326 | 0 | return const_cast<void *>(I.getAsOpaquePointer()); |
327 | 0 | } |
328 | 0 | static inline mlir::Location getFromVoidPointer(void *P) { |
329 | 0 | return mlir::Location::getFromOpaquePointer(P); |
330 | 0 | } |
331 | | static constexpr int NumLowBitsAvailable = |
332 | | PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable; |
333 | | }; |
334 | | |
335 | | } // namespace llvm |
336 | | |
337 | | #endif |