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"
10 #include "mlir/IR/BuiltinDialect.h"
11 #include "mlir/IR/Identifier.h"
12 #include "llvm/ADT/SetVector.h"
13 
14 using namespace mlir;
15 using namespace mlir::detail;
16 
17 //===----------------------------------------------------------------------===//
18 /// Tablegen Attribute Definitions
19 //===----------------------------------------------------------------------===//
20 
21 #define GET_ATTRDEF_CLASSES
22 #include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
23 
24 //===----------------------------------------------------------------------===//
25 // BuiltinDialect
26 //===----------------------------------------------------------------------===//
27 
28 void BuiltinDialect::registerLocationAttributes() {
29   addAttributes<
30 #define GET_ATTRDEF_LIST
31 #include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
32       >();
33 }
34 
35 //===----------------------------------------------------------------------===//
36 // LocationAttr
37 //===----------------------------------------------------------------------===//
38 
39 /// Methods for support type inquiry through isa, cast, and dyn_cast.
40 bool LocationAttr::classof(Attribute attr) {
41   return attr.isa<CallSiteLoc, FileLineColLoc, FusedLoc, NameLoc, OpaqueLoc,
42                   UnknownLoc>();
43 }
44 
45 //===----------------------------------------------------------------------===//
46 // CallSiteLoc
47 //===----------------------------------------------------------------------===//
48 
49 CallSiteLoc CallSiteLoc::get(Location name, ArrayRef<Location> frames) {
50   assert(!frames.empty() && "required at least 1 call frame");
51   Location caller = frames.back();
52   for (auto frame : llvm::reverse(frames.drop_back()))
53     caller = CallSiteLoc::get(frame, caller);
54   return CallSiteLoc::get(name, caller);
55 }
56 
57 //===----------------------------------------------------------------------===//
58 // FusedLoc
59 //===----------------------------------------------------------------------===//
60 
61 Location FusedLoc::get(ArrayRef<Location> locs, Attribute metadata,
62                        MLIRContext *context) {
63   // Unique the set of locations to be fused.
64   llvm::SmallSetVector<Location, 4> decomposedLocs;
65   for (auto loc : locs) {
66     // If the location is a fused location we decompose it if it has no
67     // metadata or the metadata is the same as the top level metadata.
68     if (auto fusedLoc = loc.dyn_cast<FusedLoc>()) {
69       if (fusedLoc.getMetadata() == metadata) {
70         // UnknownLoc's have already been removed from FusedLocs so we can
71         // simply add all of the internal locations.
72         decomposedLocs.insert(fusedLoc.getLocations().begin(),
73                               fusedLoc.getLocations().end());
74         continue;
75       }
76     }
77     // Otherwise, only add known locations to the set.
78     if (!loc.isa<UnknownLoc>())
79       decomposedLocs.insert(loc);
80   }
81   locs = decomposedLocs.getArrayRef();
82 
83   // Handle the simple cases of less than two locations.
84   if (locs.empty())
85     return UnknownLoc::get(context);
86   if (locs.size() == 1)
87     return locs.front();
88   return Base::get(context, locs, metadata);
89 }
90