MLIR 22.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//===----------------------------------------------------------------------===//
114/// Tablegen Attribute Definitions
115//===----------------------------------------------------------------------===//
116
117#define GET_ATTRDEF_CLASSES
118#include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
119
120//===----------------------------------------------------------------------===//
121// LocationAttr
122//===----------------------------------------------------------------------===//
123
125 AttrTypeWalker walker;
126 // Walk locations, but skip any other attribute.
127 walker.addWalk([&](Attribute attr) {
128 if (auto loc = llvm::dyn_cast<LocationAttr>(attr))
129 return walkFn(loc);
130
131 return WalkResult::skip();
132 });
133 return walker.walk<WalkOrder::PreOrder>(*this);
134}
135
136/// Methods for support type inquiry through isa, cast, and dyn_cast.
140
141//===----------------------------------------------------------------------===//
142// CallSiteLoc
143//===----------------------------------------------------------------------===//
144
145CallSiteLoc CallSiteLoc::get(Location name, ArrayRef<Location> frames) {
146 assert(!frames.empty() && "required at least 1 call frame");
147 Location caller = frames.back();
148 for (auto frame : llvm::reverse(frames.drop_back()))
149 caller = CallSiteLoc::get(frame, caller);
150 return CallSiteLoc::get(name, caller);
151}
152
153//===----------------------------------------------------------------------===//
154// FileLineColLoc
155//===----------------------------------------------------------------------===//
156
157FileLineColLoc FileLineColLoc::get(StringAttr filename, unsigned line,
158 unsigned column) {
159 return llvm::cast<FileLineColLoc>(
160 FileLineColRange::get(filename, line, column));
161}
162
163FileLineColLoc FileLineColLoc::get(MLIRContext *context, StringRef fileName,
164 unsigned line, unsigned column) {
165 return llvm::cast<FileLineColLoc>(
166 FileLineColRange::get(context, fileName, line, column));
167}
168
169StringAttr FileLineColLoc::getFilename() const {
170 return FileLineColRange::getFilename();
171}
172
173unsigned FileLineColLoc::getLine() const { return getStartLine(); }
174
175unsigned FileLineColLoc::getColumn() const { return getStartColumn(); }
176
178 if (auto range = mlir::dyn_cast<FileLineColRange>(loc))
179 return range.getImpl()->size() == 2;
180 return false;
181}
182
183//===----------------------------------------------------------------------===//
184// FileLineColRange
185//===----------------------------------------------------------------------===//
186
187StringAttr FileLineColRange::getFilename() const {
188 return getImpl()->filenameAndTrailing.getPointer();
189}
190
191unsigned FileLineColRange::getStartLine() const {
192 return getImpl()->getStartLine();
193}
194unsigned FileLineColRange::getStartColumn() const {
195 return getImpl()->getStartColumn();
196}
197unsigned FileLineColRange::getEndColumn() const {
198 return getImpl()->getEndColumn();
199}
200unsigned FileLineColRange::getEndLine() const {
201 return getImpl()->getEndLine();
202}
203
204//===----------------------------------------------------------------------===//
205// FusedLoc
206//===----------------------------------------------------------------------===//
207
208Location FusedLoc::get(ArrayRef<Location> locs, Attribute metadata,
209 MLIRContext *context) {
210 // Unique the set of locations to be fused.
211 llvm::SmallSetVector<Location, 4> decomposedLocs;
212 for (auto loc : locs) {
213 // If the location is a fused location we decompose it if it has no
214 // metadata or the metadata is the same as the top level metadata.
215 if (auto fusedLoc = llvm::dyn_cast<FusedLoc>(loc)) {
216 if (fusedLoc.getMetadata() == metadata) {
217 // UnknownLoc's have already been removed from FusedLocs so we can
218 // simply add all of the internal locations.
219 decomposedLocs.insert_range(fusedLoc.getLocations());
220 continue;
221 }
222 }
223 // Otherwise, only add known locations to the set.
224 if (!llvm::isa<UnknownLoc>(loc))
225 decomposedLocs.insert(loc);
226 }
227 locs = decomposedLocs.getArrayRef();
228
229 // Handle the simple cases of less than two locations. Ensure the metadata (if
230 // provided) is not dropped.
231 if (locs.empty()) {
232 if (!metadata)
233 return UnknownLoc::get(context);
234 // TODO: Investigate ASAN failure when using implicit conversion from
235 // Location to ArrayRef<Location> below.
236 return Base::get(context, ArrayRef<Location>{UnknownLoc::get(context)},
237 metadata);
238 }
239 if (locs.size() == 1 && !metadata)
240 return locs.front();
241
242 return Base::get(context, locs, metadata);
243}
244
245//===----------------------------------------------------------------------===//
246// BuiltinDialect
247//===----------------------------------------------------------------------===//
248
249void BuiltinDialect::registerLocationAttributes() {
250 addAttributes<
251#define GET_ATTRDEF_LIST
252#include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
253 >();
254}
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:92
An instance of this location represents a tuple of file, line number, and column number.
Definition Location.h:174
unsigned getLine() const
Definition Location.cpp:173
StringAttr getFilename() const
Definition Location.cpp:169
static FileLineColLoc get(StringAttr filename, unsigned line, unsigned column)
Definition Location.cpp:157
unsigned getColumn() const
Definition Location.cpp:175
WalkResult walk(function_ref< WalkResult(Location)> walkFn)
Walk all of the locations nested directly under, and including, the current.
Definition Location.cpp:124
static bool classof(Attribute attr)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition Location.cpp:137
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
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
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:152
bool isStrictFileLineColLoc(Location loc)
Returns true iff the given location is a FileLineColRange with exactly one line and column.
Definition Location.cpp:177
This trait is used to determine if an attribute is a location or not.
Definition Attributes.h:294
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