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 Location;
23 class WalkResult;
24
25 //===----------------------------------------------------------------------===//
26 // LocationAttr
27 //===----------------------------------------------------------------------===//
28
29 /// Location objects represent source locations information in MLIR.
30 /// LocationAttr acts as the anchor for all Location based attributes.
31 class LocationAttr : public Attribute {
32 public:
33 using Attribute::Attribute;
34
35 /// Walk all of the locations nested under, and including, the current.
36 WalkResult walk(function_ref<WalkResult(Location)> walkFn);
37
38 /// Methods for support type inquiry through isa, cast, and dyn_cast.
39 static bool classof(Attribute attr);
40 };
41
42 //===----------------------------------------------------------------------===//
43 // Location
44 //===----------------------------------------------------------------------===//
45
46 /// This class defines the main interface for locations in MLIR and acts as a
47 /// non-nullable wrapper around a LocationAttr.
48 class Location {
49 public:
Location(LocationAttr loc)50 Location(LocationAttr loc) : impl(loc) {
51 assert(loc && "location should never be null.");
52 }
Location(const LocationAttr::ImplType * impl)53 Location(const LocationAttr::ImplType *impl) : impl(impl) {
54 assert(impl && "location should never be null.");
55 }
56
57 /// Return the context this location is uniqued in.
getContext()58 MLIRContext *getContext() const { return impl.getContext(); }
59
60 /// Access the impl location attribute.
LocationAttr()61 operator LocationAttr() const { return impl; }
62 LocationAttr *operator->() const { return const_cast<LocationAttr *>(&impl); }
63
64 /// Type casting utilities on the underlying location.
65 template <typename U>
isa()66 bool isa() const {
67 return impl.isa<U>();
68 }
69 template <typename U>
dyn_cast()70 U dyn_cast() const {
71 return impl.dyn_cast<U>();
72 }
73 template <typename U>
cast()74 U cast() const {
75 return impl.cast<U>();
76 }
77
78 /// Comparison operators.
79 bool operator==(Location rhs) const { return impl == rhs.impl; }
80 bool operator!=(Location rhs) const { return !(*this == rhs); }
81
82 /// Print the location.
print(raw_ostream & os)83 void print(raw_ostream &os) const { impl.print(os); }
dump()84 void dump() const { impl.dump(); }
85
86 friend ::llvm::hash_code hash_value(Location arg);
87
88 /// Methods for supporting PointerLikeTypeTraits.
getAsOpaquePointer()89 const void *getAsOpaquePointer() const { return impl.getAsOpaquePointer(); }
getFromOpaquePointer(const void * pointer)90 static Location getFromOpaquePointer(const void *pointer) {
91 return LocationAttr(reinterpret_cast<const AttributeStorage *>(pointer));
92 }
93
94 protected:
95 /// The internal backing location attribute.
96 LocationAttr impl;
97 };
98
99 inline raw_ostream &operator<<(raw_ostream &os, const Location &loc) {
100 loc.print(os);
101 return os;
102 }
103
104 // Make Location hashable.
hash_value(Location arg)105 inline ::llvm::hash_code hash_value(Location arg) {
106 return hash_value(arg.impl);
107 }
108
109 } // namespace mlir
110
111 //===----------------------------------------------------------------------===//
112 // Tablegen Attribute Declarations
113 //===----------------------------------------------------------------------===//
114
115 #define GET_ATTRDEF_CLASSES
116 #include "mlir/IR/BuiltinLocationAttributes.h.inc"
117
118 namespace mlir {
119
120 //===----------------------------------------------------------------------===//
121 // OpaqueLoc
122 //===----------------------------------------------------------------------===//
123
124 /// Returns an instance of opaque location which contains a given pointer to
125 /// an object. The corresponding MLIR location is set to UnknownLoc.
126 template <typename T>
get(T underlyingLocation,MLIRContext * context)127 inline OpaqueLoc OpaqueLoc::get(T underlyingLocation, MLIRContext *context) {
128 return get(reinterpret_cast<uintptr_t>(underlyingLocation), TypeID::get<T>(),
129 UnknownLoc::get(context));
130 }
131 } // namespace mlir
132
133 //===----------------------------------------------------------------------===//
134 // LLVM Utilities
135 //===----------------------------------------------------------------------===//
136
137 namespace llvm {
138
139 // Type hash just like pointers.
140 template <>
141 struct DenseMapInfo<mlir::Location> {
142 static mlir::Location getEmptyKey() {
143 auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
144 return mlir::Location::getFromOpaquePointer(pointer);
145 }
146 static mlir::Location getTombstoneKey() {
147 auto *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
148 return mlir::Location::getFromOpaquePointer(pointer);
149 }
150 static unsigned getHashValue(mlir::Location val) {
151 return mlir::hash_value(val);
152 }
153 static bool isEqual(mlir::Location LHS, mlir::Location RHS) {
154 return LHS == RHS;
155 }
156 };
157
158 /// We align LocationStorage by 8, so allow LLVM to steal the low bits.
159 template <>
160 struct PointerLikeTypeTraits<mlir::Location> {
161 public:
162 static inline void *getAsVoidPointer(mlir::Location I) {
163 return const_cast<void *>(I.getAsOpaquePointer());
164 }
165 static inline mlir::Location getFromVoidPointer(void *P) {
166 return mlir::Location::getFromOpaquePointer(P);
167 }
168 static constexpr int NumLowBitsAvailable =
169 PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable;
170 };
171
172 } // namespace llvm
173
174 #endif
175