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