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 "LocationDetail.h" 11 #include "llvm/ADT/SetVector.h" 12 13 using namespace mlir; 14 using namespace mlir::detail; 15 16 //===----------------------------------------------------------------------===// 17 // LocationAttr 18 //===----------------------------------------------------------------------===// 19 20 /// Methods for support type inquiry through isa, cast, and dyn_cast. 21 bool LocationAttr::classof(Attribute attr) { 22 return attr.isa<CallSiteLoc, FileLineColLoc, FusedLoc, NameLoc, OpaqueLoc, 23 UnknownLoc>(); 24 } 25 26 //===----------------------------------------------------------------------===// 27 // CallSiteLoc 28 //===----------------------------------------------------------------------===// 29 30 Location CallSiteLoc::get(Location callee, Location caller) { 31 return Base::get(callee->getContext(), StandardAttributes::CallSiteLocation, 32 callee, caller); 33 } 34 35 Location CallSiteLoc::get(Location name, ArrayRef<Location> frames) { 36 assert(!frames.empty() && "required at least 1 call frame"); 37 Location caller = frames.back(); 38 for (auto frame : llvm::reverse(frames.drop_back())) 39 caller = CallSiteLoc::get(frame, caller); 40 return CallSiteLoc::get(name, caller); 41 } 42 43 Location CallSiteLoc::getCallee() const { return getImpl()->callee; } 44 45 Location CallSiteLoc::getCaller() const { return getImpl()->caller; } 46 47 //===----------------------------------------------------------------------===// 48 // FileLineColLoc 49 //===----------------------------------------------------------------------===// 50 51 Location FileLineColLoc::get(Identifier filename, unsigned line, 52 unsigned column, MLIRContext *context) { 53 return Base::get(context, StandardAttributes::FileLineColLocation, filename, 54 line, column); 55 } 56 57 Location FileLineColLoc::get(StringRef filename, unsigned line, unsigned column, 58 MLIRContext *context) { 59 return get(Identifier::get(filename.empty() ? "-" : filename, context), line, 60 column, context); 61 } 62 63 StringRef FileLineColLoc::getFilename() const { return getImpl()->filename; } 64 unsigned FileLineColLoc::getLine() const { return getImpl()->line; } 65 unsigned FileLineColLoc::getColumn() const { return getImpl()->column; } 66 67 //===----------------------------------------------------------------------===// 68 // FusedLoc 69 //===----------------------------------------------------------------------===// 70 71 Location FusedLoc::get(ArrayRef<Location> locs, Attribute metadata, 72 MLIRContext *context) { 73 // Unique the set of locations to be fused. 74 llvm::SmallSetVector<Location, 4> decomposedLocs; 75 for (auto loc : locs) { 76 // If the location is a fused location we decompose it if it has no 77 // metadata or the metadata is the same as the top level metadata. 78 if (auto fusedLoc = loc.dyn_cast<FusedLoc>()) { 79 if (fusedLoc.getMetadata() == metadata) { 80 // UnknownLoc's have already been removed from FusedLocs so we can 81 // simply add all of the internal locations. 82 decomposedLocs.insert(fusedLoc.getLocations().begin(), 83 fusedLoc.getLocations().end()); 84 continue; 85 } 86 } 87 // Otherwise, only add known locations to the set. 88 if (!loc.isa<UnknownLoc>()) 89 decomposedLocs.insert(loc); 90 } 91 locs = decomposedLocs.getArrayRef(); 92 93 // Handle the simple cases of less than two locations. 94 if (locs.empty()) 95 return UnknownLoc::get(context); 96 if (locs.size() == 1) 97 return locs.front(); 98 return Base::get(context, StandardAttributes::FusedLocation, locs, metadata); 99 } 100 101 ArrayRef<Location> FusedLoc::getLocations() const { 102 return getImpl()->getLocations(); 103 } 104 105 Attribute FusedLoc::getMetadata() const { return getImpl()->metadata; } 106 107 //===----------------------------------------------------------------------===// 108 // NameLoc 109 //===----------------------------------------------------------------------===// 110 111 Location NameLoc::get(Identifier name, Location child) { 112 assert(!child.isa<NameLoc>() && 113 "a NameLoc cannot be used as a child of another NameLoc"); 114 return Base::get(child->getContext(), StandardAttributes::NameLocation, name, 115 child); 116 } 117 118 Location NameLoc::get(Identifier name, MLIRContext *context) { 119 return get(name, UnknownLoc::get(context)); 120 } 121 122 /// Return the name identifier. 123 Identifier NameLoc::getName() const { return getImpl()->name; } 124 125 /// Return the child location. 126 Location NameLoc::getChildLoc() const { return getImpl()->child; } 127 128 //===----------------------------------------------------------------------===// 129 // OpaqueLoc 130 //===----------------------------------------------------------------------===// 131 132 Location OpaqueLoc::get(uintptr_t underlyingLocation, TypeID typeID, 133 Location fallbackLocation) { 134 return Base::get(fallbackLocation->getContext(), 135 StandardAttributes::OpaqueLocation, underlyingLocation, 136 typeID, fallbackLocation); 137 } 138 139 uintptr_t OpaqueLoc::getUnderlyingLocation() const { 140 return Base::getImpl()->underlyingLocation; 141 } 142 143 TypeID OpaqueLoc::getUnderlyingTypeID() const { return getImpl()->typeID; } 144 145 Location OpaqueLoc::getFallbackLocation() const { 146 return Base::getImpl()->fallbackLocation; 147 } 148