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