MLIR  21.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"
12 #include "mlir/IR/BuiltinDialect.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/ADT/TypeSwitch.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/TrailingObjects.h"
24 #include <cassert>
25 #include <iterator>
26 #include <memory>
27 #include <optional>
28 #include <tuple>
29 #include <utility>
30 
31 using namespace mlir;
32 using namespace mlir::detail;
33 
34 namespace mlir::detail {
36  : public ::mlir::AttributeStorage,
37  private llvm::TrailingObjects<FileLineColRangeAttrStorage, unsigned> {
38  friend llvm::TrailingObjects<FileLineColRangeAttrStorage, unsigned>;
39  using PointerPair = llvm::PointerIntPair<StringAttr, 2>;
40  using KeyTy = std::tuple<StringAttr, ::llvm::ArrayRef<unsigned>>;
41 
42  FileLineColRangeAttrStorage(StringAttr filename, int numLocs)
43  : filenameAndTrailing(filename, numLocs) {}
44 
46  construct(::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey) {
47  auto numInArray = std::get<1>(tblgenKey).size();
48  // Note: Considered asserting that numInArray is at least 1, but this
49  // is not needed in memory or in printed form. This should very rarely be
50  // 0 here as that means a NamedLoc would have been more efficient. But this
51  // does allow for location with just a file, and also having the interface
52  // be more uniform.
53  auto locEnc = numInArray == 0 ? 1 : numInArray;
54  // Allocate a new storage instance.
55  auto byteSize =
56  FileLineColRangeAttrStorage::totalSizeToAlloc<unsigned>(locEnc - 1);
57  auto *rawMem =
58  allocator.allocate(byteSize, alignof(FileLineColRangeAttrStorage));
59  auto *result = ::new (rawMem) FileLineColRangeAttrStorage(
60  std::move(std::get<0>(tblgenKey)), locEnc - 1);
61  if (numInArray > 0) {
62  ArrayRef<unsigned> elements = std::get<1>(tblgenKey);
63  result->startLine = elements[0];
64  // Copy in the element types into the trailing storage.
65  llvm::uninitialized_copy(elements.drop_front(),
66  result->getTrailingObjects());
67  }
68  return result;
69  }
70 
71  // Return the number of held types.
72  unsigned size() const { return filenameAndTrailing.getInt() + 1; }
73 
74  bool operator==(const KeyTy &tblgenKey) const {
75  return (filenameAndTrailing.getPointer() == std::get<0>(tblgenKey)) &&
76  (size() == std::get<1>(tblgenKey).size()) &&
77  (startLine == std::get<1>(tblgenKey)[0]) &&
78  (getTrailingObjects(size() - 1) ==
79  std::get<1>(tblgenKey).drop_front());
80  }
81 
82  unsigned getLineCols(unsigned index) const {
83  return getTrailingObjects()[index - 1];
84  }
85 
86  unsigned getStartLine() const { return startLine; }
87  unsigned getStartColumn() const {
88  if (size() <= 1)
89  return 0;
90  return getLineCols(1);
91  }
92  unsigned getEndColumn() const {
93  if (size() <= 2)
94  return getStartColumn();
95  return getLineCols(2);
96  }
97  unsigned getEndLine() const {
98  if (size() <= 3)
99  return getStartLine();
100  return getLineCols(3);
101  }
102 
103  static ::llvm::hash_code hashKey(const KeyTy &tblgenKey) {
104  return ::llvm::hash_combine(std::get<0>(tblgenKey), std::get<1>(tblgenKey));
105  }
106 
107  // Supports
108  // - 0 (file:line)
109  // - 1 (file:line:col)
110  // - 2 (file:line:start_col to file:line:end_col) and
111  // - 3 (file:start_line:start_col to file:end_line:end_col)
112  llvm::PointerIntPair<StringAttr, 2> filenameAndTrailing;
113  unsigned startLine = 0;
114 };
115 } // namespace mlir::detail
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.
142  return attr.hasTrait<AttributeTrait::IsLocation>();
143 }
144 
145 //===----------------------------------------------------------------------===//
146 // CallSiteLoc
147 //===----------------------------------------------------------------------===//
148 
149 CallSiteLoc 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 
161 FileLineColLoc FileLineColLoc::get(StringAttr filename, unsigned line,
162  unsigned column) {
163  return llvm::cast<FileLineColLoc>(
164  FileLineColRange::get(filename, line, column));
165 }
166 
167 FileLineColLoc 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 
173 StringAttr FileLineColLoc::getFilename() const {
174  return FileLineColRange::getFilename();
175 }
176 
177 unsigned FileLineColLoc::getLine() const { return getStartLine(); }
178 
179 unsigned 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 
191 StringAttr FileLineColRange::getFilename() const {
192  return getImpl()->filenameAndTrailing.getPointer();
193 }
194 
195 unsigned FileLineColRange::getStartLine() const {
196  return getImpl()->getStartLine();
197 }
198 unsigned FileLineColRange::getStartColumn() const {
199  return getImpl()->getStartColumn();
200 }
201 unsigned FileLineColRange::getEndColumn() const {
202  return getImpl()->getEndColumn();
203 }
204 unsigned FileLineColRange::getEndLine() const {
205  return getImpl()->getEndLine();
206 }
207 
208 //===----------------------------------------------------------------------===//
209 // FusedLoc
210 //===----------------------------------------------------------------------===//
211 
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 
253 void 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: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: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
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:60
This is a utility allocator used to allocate memory for instances of derived types.
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: Visitors.h:33
static WalkResult skip()
Definition: Visitors.h:52
AttrTypeReplacer.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
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:294
unsigned getLineCols(unsigned index) const
Definition: Location.cpp:82
static FileLineColRangeAttrStorage * construct(::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey)
Definition: Location.cpp:46
FileLineColRangeAttrStorage(StringAttr filename, int numLocs)
Definition: Location.cpp:42
::llvm::hash_code hashKey(const KeyTy &tblgenKey)
Definition: Location.cpp:103
std::tuple< StringAttr, ::llvm::ArrayRef< unsigned > > KeyTy
Definition: Location.cpp:40
llvm::PointerIntPair< StringAttr, 2 > PointerPair
Definition: Location.cpp:39
llvm::PointerIntPair< StringAttr, 2 > filenameAndTrailing
Definition: Location.cpp:112
bool operator==(const KeyTy &tblgenKey) const
Definition: Location.cpp:74