MLIR 24.0.0git
Location.cpp
Go to the documentation of this file.
1//===- Location.cpp - MLIR Location Classes -------------------------------===//
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#include "mlir/IR/Location.h"
13#include "mlir/IR/MLIRContext.h"
14#include "mlir/IR/Visitors.h"
15#include "mlir/Support/LLVM.h"
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/Hashing.h"
18#include "llvm/ADT/PointerIntPair.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/SetVector.h"
21#include "llvm/Support/Casting.h"
22#include "llvm/Support/TrailingObjects.h"
23#include <cassert>
24#include <tuple>
25#include <utility>
26
27using namespace mlir;
28using namespace mlir::detail;
29
30namespace mlir::detail {
33 private llvm::TrailingObjects<FileLineColRangeAttrStorage, unsigned> {
34 friend llvm::TrailingObjects<FileLineColRangeAttrStorage, unsigned>;
35 using PointerPair = llvm::PointerIntPair<StringAttr, 2>;
36 using KeyTy = std::tuple<StringAttr, ::llvm::ArrayRef<unsigned>>;
37
38 FileLineColRangeAttrStorage(StringAttr filename, int numLocs)
39 : filenameAndTrailing(filename, numLocs) {}
40
43 auto numInArray = std::get<1>(tblgenKey).size();
44 // Note: Considered asserting that numInArray is at least 1, but this
45 // is not needed in memory or in printed form. This should very rarely be
46 // 0 here as that means a NamedLoc would have been more efficient. But this
47 // does allow for location with just a file, and also having the interface
48 // be more uniform.
49 auto locEnc = numInArray == 0 ? 1 : numInArray;
50 // Allocate a new storage instance.
51 auto byteSize =
52 FileLineColRangeAttrStorage::totalSizeToAlloc<unsigned>(locEnc - 1);
53 auto *rawMem =
54 allocator.allocate(byteSize, alignof(FileLineColRangeAttrStorage));
55 auto *result = ::new (rawMem)
56 FileLineColRangeAttrStorage(std::get<0>(tblgenKey), locEnc - 1);
57 if (numInArray > 0) {
58 ArrayRef<unsigned> elements = std::get<1>(tblgenKey);
59 result->startLine = elements[0];
60 // Copy in the element types into the trailing storage.
61 llvm::uninitialized_copy(elements.drop_front(),
62 result->getTrailingObjects());
63 }
64 return result;
65 }
66
67 // Return the number of held types.
68 unsigned size() const { return filenameAndTrailing.getInt() + 1; }
69
70 bool operator==(const KeyTy &tblgenKey) const {
71 return (filenameAndTrailing.getPointer() == std::get<0>(tblgenKey)) &&
72 (size() == std::get<1>(tblgenKey).size()) &&
73 (startLine == std::get<1>(tblgenKey)[0]) &&
74 (getTrailingObjects(size() - 1) ==
75 std::get<1>(tblgenKey).drop_front());
76 }
77
78 unsigned getLineCols(unsigned index) const {
79 return getTrailingObjects()[index - 1];
80 }
81
82 unsigned getStartLine() const { return startLine; }
83 unsigned getStartColumn() const {
84 if (size() <= 1)
85 return 0;
86 return getLineCols(1);
87 }
88 unsigned getEndColumn() const {
89 if (size() <= 2)
90 return getStartColumn();
91 return getLineCols(2);
92 }
93 unsigned getEndLine() const {
94 if (size() <= 3)
95 return getStartLine();
96 return getLineCols(3);
97 }
98
99 static ::llvm::hash_code hashKey(const KeyTy &tblgenKey) {
100 return ::llvm::hash_combine(std::get<0>(tblgenKey), std::get<1>(tblgenKey));
101 }
102
103 // Supports
104 // - 0 (file:line)
105 // - 1 (file:line:col)
106 // - 2 (file:line:start_col to file:line:end_col) and
107 // - 3 (file:start_line:start_col to file:end_line:end_col)
108 llvm::PointerIntPair<StringAttr, 2> filenameAndTrailing;
109 unsigned startLine = 0;
110};
111} // namespace mlir::detail
112
113#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
114void Location::dump() const { impl.dump(); }
115#endif
116
117//===----------------------------------------------------------------------===//
118/// Tablegen Attribute Definitions
119//===----------------------------------------------------------------------===//
120
121#define GET_ATTRDEF_CLASSES
122#include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
123
124//===----------------------------------------------------------------------===//
125// LocationAttr
126//===----------------------------------------------------------------------===//
127
129 AttrTypeWalker walker;
130 // Walk locations, but skip any other attribute.
131 walker.addWalk([&](Attribute attr) {
132 if (auto loc = llvm::dyn_cast<LocationAttr>(attr))
133 return walkFn(loc);
134
135 return WalkResult::skip();
136 });
137 return walker.walk<WalkOrder::PreOrder>(*this);
138}
139
140/// Methods for support type inquiry through isa, cast, and dyn_cast.
144
145//===----------------------------------------------------------------------===//
146// CallSiteLoc
147//===----------------------------------------------------------------------===//
148
149CallSiteLoc CallSiteLoc::get(Location name, ArrayRef<Location> frames) {
150 assert(!frames.empty() && "required at least 1 call frame");
151 Location caller = frames.back();
152 for (auto frame : llvm::reverse(frames.drop_back()))
153 caller = CallSiteLoc::get(frame, caller);
154 return CallSiteLoc::get(name, caller);
155}
156
157//===----------------------------------------------------------------------===//
158// FileLineColLoc
159//===----------------------------------------------------------------------===//
160
161FileLineColLoc FileLineColLoc::get(StringAttr filename, unsigned line,
162 unsigned column) {
163 return llvm::cast<FileLineColLoc>(
164 FileLineColRange::get(filename, line, column));
165}
166
167FileLineColLoc FileLineColLoc::get(MLIRContext *context, StringRef fileName,
168 unsigned line, unsigned column) {
169 return llvm::cast<FileLineColLoc>(
170 FileLineColRange::get(context, fileName, line, column));
171}
172
173StringAttr FileLineColLoc::getFilename() const {
174 return FileLineColRange::getFilename();
175}
176
177unsigned FileLineColLoc::getLine() const { return getStartLine(); }
178
179unsigned FileLineColLoc::getColumn() const { return getStartColumn(); }
180
182 if (auto range = mlir::dyn_cast<FileLineColRange>(loc))
183 return range.getImpl()->size() == 2;
184 return false;
185}
186
187//===----------------------------------------------------------------------===//
188// FileLineColRange
189//===----------------------------------------------------------------------===//
190
191StringAttr FileLineColRange::getFilename() const {
192 return getImpl()->filenameAndTrailing.getPointer();
193}
194
195unsigned FileLineColRange::getStartLine() const {
196 return getImpl()->getStartLine();
197}
198unsigned FileLineColRange::getStartColumn() const {
199 return getImpl()->getStartColumn();
200}
201unsigned FileLineColRange::getEndColumn() const {
202 return getImpl()->getEndColumn();
203}
204unsigned FileLineColRange::getEndLine() const {
205 return getImpl()->getEndLine();
206}
207
208//===----------------------------------------------------------------------===//
209// FusedLoc
210//===----------------------------------------------------------------------===//
211
212Location FusedLoc::get(ArrayRef<Location> locs, Attribute metadata,
213 MLIRContext *context) {
214 // Unique the set of locations to be fused.
215 llvm::SmallSetVector<Location, 4> decomposedLocs;
216 for (auto loc : locs) {
217 // If the location is a fused location we decompose it if it has no
218 // metadata or the metadata is the same as the top level metadata.
219 if (auto fusedLoc = llvm::dyn_cast<FusedLoc>(loc)) {
220 if (fusedLoc.getMetadata() == metadata) {
221 // UnknownLoc's have already been removed from FusedLocs so we can
222 // simply add all of the internal locations.
223 decomposedLocs.insert_range(fusedLoc.getLocations());
224 continue;
225 }
226 }
227 // Otherwise, only add known locations to the set.
228 if (!llvm::isa<UnknownLoc>(loc))
229 decomposedLocs.insert(loc);
230 }
231 locs = decomposedLocs.getArrayRef();
232
233 // Handle the simple cases of less than two locations. Ensure the metadata (if
234 // provided) is not dropped.
235 if (locs.empty()) {
236 if (!metadata)
237 return UnknownLoc::get(context);
238 // TODO: Investigate ASAN failure when using implicit conversion from
239 // Location to ArrayRef<Location> below.
240 return Base::get(context, ArrayRef<Location>{UnknownLoc::get(context)},
241 metadata);
242 }
243 if (locs.size() == 1 && !metadata)
244 return locs.front();
245
246 return Base::get(context, locs, metadata);
247}
248
249//===----------------------------------------------------------------------===//
250// BuiltinDialect
251//===----------------------------------------------------------------------===//
252
253void BuiltinDialect::registerLocationAttributes() {
254 addAttributes<
255#define GET_ATTRDEF_LIST
256#include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
257 >();
258}
void addWalk(WalkFn< Attribute > &&fn)
Register a walk function for a given attribute or type.
WalkResult walk(T element)
Walk the given attribute/type, and recursively walk any sub elements.
Base storage class appearing in an attribute.
Attributes are known-constant values of operations.
Definition Attributes.h:25
bool hasTrait()
Returns true if the type was registered with a particular trait.
Definition Attributes.h:94
An instance of this location represents a tuple of file, line number, and column number.
Definition Location.h:176
unsigned getLine() const
Definition Location.cpp:177
StringAttr getFilename() const
Definition Location.cpp:173
static FileLineColLoc get(StringAttr filename, unsigned line, unsigned column)
Definition Location.cpp:161
unsigned getColumn() const
Definition Location.cpp:179
WalkResult walk(function_ref< WalkResult(Location)> walkFn)
Walk all of the locations nested directly under, and including, the current.
Definition Location.cpp:128
static bool classof(Attribute attr)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition Location.cpp:141
constexpr Attribute()=default
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
LLVM_DUMP_METHOD void dump() const
Definition Location.cpp:114
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:71
T * allocate()
Allocate an instance of the provided type.
A utility result that is used to signal how to proceed with an ongoing walk:
Definition WalkResult.h:29
static WalkResult skip()
Definition WalkResult.h:48
AttrTypeReplacer.
Include the generated interface declarations.
StorageUniquer::StorageAllocator AttributeStorageAllocator
llvm::function_ref< Fn > function_ref
Definition LLVM.h:155
bool isStrictFileLineColLoc(Location loc)
Returns true iff the given location is a FileLineColRange with exactly one line and column.
Definition Location.cpp:181
This trait is used to determine if an attribute is a location or not.
Definition Attributes.h:296
unsigned getLineCols(unsigned index) const
Definition Location.cpp:78
FileLineColRangeAttrStorage(StringAttr filename, int numLocs)
Definition Location.cpp:38
::llvm::hash_code hashKey(const KeyTy &tblgenKey)
Definition Location.cpp:99
static FileLineColRangeAttrStorage * construct(::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey)
Definition Location.cpp:42
llvm::PointerIntPair< StringAttr, 2 > PointerPair
Definition Location.cpp:35
llvm::PointerIntPair< StringAttr, 2 > filenameAndTrailing
Definition Location.cpp:108
std::tuple< StringAttr, ::llvm::ArrayRef< unsigned > > KeyTy
Definition Location.cpp:36
bool operator==(const KeyTy &tblgenKey) const
Definition Location.cpp:70