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