MLIR  19.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"
10 #include "mlir/IR/BuiltinDialect.h"
11 #include "mlir/IR/Visitors.h"
12 #include "llvm/ADT/SetVector.h"
13 #include "llvm/ADT/TypeSwitch.h"
14 
15 using namespace mlir;
16 using namespace mlir::detail;
17 
18 //===----------------------------------------------------------------------===//
19 /// Tablegen Attribute Definitions
20 //===----------------------------------------------------------------------===//
21 
22 #define GET_ATTRDEF_CLASSES
23 #include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
24 
25 //===----------------------------------------------------------------------===//
26 // BuiltinDialect
27 //===----------------------------------------------------------------------===//
28 
29 void BuiltinDialect::registerLocationAttributes() {
30  addAttributes<
31 #define GET_ATTRDEF_LIST
32 #include "mlir/IR/BuiltinLocationAttributes.cpp.inc"
33  >();
34 }
35 
36 //===----------------------------------------------------------------------===//
37 // LocationAttr
38 //===----------------------------------------------------------------------===//
39 
41  if (walkFn(*this).wasInterrupted())
42  return WalkResult::interrupt();
43 
45  .Case([&](CallSiteLoc callLoc) -> WalkResult {
46  if (callLoc.getCallee()->walk(walkFn).wasInterrupted())
47  return WalkResult::interrupt();
48  return callLoc.getCaller()->walk(walkFn);
49  })
50  .Case([&](FusedLoc fusedLoc) -> WalkResult {
51  for (Location subLoc : fusedLoc.getLocations())
52  if (subLoc->walk(walkFn).wasInterrupted())
53  return WalkResult::interrupt();
54  return WalkResult::advance();
55  })
56  .Case([&](NameLoc nameLoc) -> WalkResult {
57  return nameLoc.getChildLoc()->walk(walkFn);
58  })
59  .Case([&](OpaqueLoc opaqueLoc) -> WalkResult {
60  return opaqueLoc.getFallbackLocation()->walk(walkFn);
61  })
62  .Default(WalkResult::advance());
63 }
64 
65 /// Methods for support type inquiry through isa, cast, and dyn_cast.
67  return llvm::isa<CallSiteLoc, FileLineColLoc, FusedLoc, NameLoc, OpaqueLoc,
68  UnknownLoc>(attr);
69 }
70 
71 //===----------------------------------------------------------------------===//
72 // CallSiteLoc
73 //===----------------------------------------------------------------------===//
74 
75 CallSiteLoc CallSiteLoc::get(Location name, ArrayRef<Location> frames) {
76  assert(!frames.empty() && "required at least 1 call frame");
77  Location caller = frames.back();
78  for (auto frame : llvm::reverse(frames.drop_back()))
79  caller = CallSiteLoc::get(frame, caller);
80  return CallSiteLoc::get(name, caller);
81 }
82 
83 //===----------------------------------------------------------------------===//
84 // FusedLoc
85 //===----------------------------------------------------------------------===//
86 
88  MLIRContext *context) {
89  // Unique the set of locations to be fused.
90  llvm::SmallSetVector<Location, 4> decomposedLocs;
91  for (auto loc : locs) {
92  // If the location is a fused location we decompose it if it has no
93  // metadata or the metadata is the same as the top level metadata.
94  if (auto fusedLoc = llvm::dyn_cast<FusedLoc>(loc)) {
95  if (fusedLoc.getMetadata() == metadata) {
96  // UnknownLoc's have already been removed from FusedLocs so we can
97  // simply add all of the internal locations.
98  decomposedLocs.insert(fusedLoc.getLocations().begin(),
99  fusedLoc.getLocations().end());
100  continue;
101  }
102  }
103  // Otherwise, only add known locations to the set.
104  if (!llvm::isa<UnknownLoc>(loc))
105  decomposedLocs.insert(loc);
106  }
107  locs = decomposedLocs.getArrayRef();
108 
109  // Handle the simple cases of less than two locations. Ensure the metadata (if
110  // provided) is not dropped.
111  if (locs.empty()) {
112  if (!metadata)
113  return UnknownLoc::get(context);
114  // TODO: Investigate ASAN failure when using implicit conversion from
115  // Location to ArrayRef<Location> below.
116  return Base::get(context, ArrayRef<Location>{UnknownLoc::get(context)},
117  metadata);
118  }
119  if (locs.size() == 1 && !metadata)
120  return locs.front();
121 
122  return Base::get(context, locs, metadata);
123 }
Attributes are known-constant values of operations.
Definition: Attributes.h:25
WalkResult walk(function_ref< WalkResult(Location)> walkFn)
Walk all of the locations nested under, and including, the current.
Definition: Location.cpp:40
static bool classof(Attribute attr)
Methods for support type inquiry through isa, cast, and dyn_cast.
Definition: Location.cpp:66
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
A utility result that is used to signal how to proceed with an ongoing walk:
Definition: Visitors.h:34
static WalkResult advance()
Definition: Visitors.h:52
static WalkResult interrupt()
Definition: Visitors.h:51
Detect if any of the given parameter types has a sub-element handler.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
Definition: Visitors.h:137
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...