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