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