Coverage Report

Created: 2020-06-26 05:44

/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