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"
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/Support/Casting.h"
22 #include "llvm/Support/TrailingObjects.h"
23 #include <cassert>
24 #include <tuple>
25 #include <utility>
26 
27 using namespace mlir;
28 using namespace mlir::detail;
29 
30 namespace mlir::detail {
32  : public ::mlir::AttributeStorage,
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 
42  construct(::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey) {
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) FileLineColRangeAttrStorage(
56  std::move(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.
138  return attr.hasTrait<AttributeTrait::IsLocation>();
139 }
140 
141 //===----------------------------------------------------------------------===//
142 // CallSiteLoc
143 //===----------------------------------------------------------------------===//
144 
145 CallSiteLoc 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 
157 FileLineColLoc FileLineColLoc::get(StringAttr filename, unsigned line,
158  unsigned column) {
159  return llvm::cast<FileLineColLoc>(
160  FileLineColRange::get(filename, line, column));
161 }
162 
163 FileLineColLoc 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 
169 StringAttr FileLineColLoc::getFilename() const {
170  return FileLineColRange::getFilename();
171 }
172 
173 unsigned FileLineColLoc::getLine() const { return getStartLine(); }
174 
175 unsigned 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 
187 StringAttr FileLineColRange::getFilename() const {
188  return getImpl()->filenameAndTrailing.getPointer();
189 }
190 
191 unsigned FileLineColRange::getStartLine() const {
192  return getImpl()->getStartLine();
193 }
194 unsigned FileLineColRange::getStartColumn() const {
195  return getImpl()->getStartColumn();
196 }
197 unsigned FileLineColRange::getEndColumn() const {
198  return getImpl()->getEndColumn();
199 }
200 unsigned FileLineColRange::getEndLine() const {
201  return getImpl()->getEndLine();
202 }
203 
204 //===----------------------------------------------------------------------===//
205 // FusedLoc
206 //===----------------------------------------------------------------------===//
207 
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 
249 void 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
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: WalkResult.h:29
static WalkResult skip()
Definition: WalkResult.h:48
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: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
static FileLineColRangeAttrStorage * construct(::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey)
Definition: Location.cpp:42
FileLineColRangeAttrStorage(StringAttr filename, int numLocs)
Definition: Location.cpp:38
::llvm::hash_code hashKey(const KeyTy &tblgenKey)
Definition: Location.cpp:99
std::tuple< StringAttr, ::llvm::ArrayRef< unsigned > > KeyTy
Definition: Location.cpp:36
llvm::PointerIntPair< StringAttr, 2 > PointerPair
Definition: Location.cpp:35
llvm::PointerIntPair< StringAttr, 2 > filenameAndTrailing
Definition: Location.cpp:108
bool operator==(const KeyTy &tblgenKey) const
Definition: Location.cpp:70