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 // CallSiteLoc 18 //===----------------------------------------------------------------------===// 19 20 Location CallSiteLoc::get(Location callee, Location caller) { 21 return Base::get(callee->getContext(), StandardAttributes::CallSiteLocation, 22 callee, caller); 23 } 24 25 Location CallSiteLoc::get(Location name, ArrayRef<Location> frames) { 26 assert(!frames.empty() && "required at least 1 call frame"); 27 Location caller = frames.back(); 28 for (auto frame : llvm::reverse(frames.drop_back())) 29 caller = CallSiteLoc::get(frame, caller); 30 return CallSiteLoc::get(name, caller); 31 } 32 33 Location CallSiteLoc::getCallee() const { return getImpl()->callee; } 34 35 Location CallSiteLoc::getCaller() const { return getImpl()->caller; } 36 37 //===----------------------------------------------------------------------===// 38 // FileLineColLoc 39 //===----------------------------------------------------------------------===// 40 41 Location FileLineColLoc::get(Identifier filename, unsigned line, 42 unsigned column, MLIRContext *context) { 43 return Base::get(context, StandardAttributes::FileLineColLocation, filename, 44 line, column); 45 } 46 47 Location FileLineColLoc::get(StringRef filename, unsigned line, unsigned column, 48 MLIRContext *context) { 49 return get(Identifier::get(filename.empty() ? "-" : filename, context), line, 50 column, context); 51 } 52 53 StringRef FileLineColLoc::getFilename() const { return getImpl()->filename; } 54 unsigned FileLineColLoc::getLine() const { return getImpl()->line; } 55 unsigned FileLineColLoc::getColumn() const { return getImpl()->column; } 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, StandardAttributes::FusedLocation, locs, metadata); 89 } 90 91 ArrayRef<Location> FusedLoc::getLocations() const { 92 return getImpl()->getLocations(); 93 } 94 95 Attribute FusedLoc::getMetadata() const { return getImpl()->metadata; } 96 97 //===----------------------------------------------------------------------===// 98 // NameLoc 99 //===----------------------------------------------------------------------===// 100 101 Location NameLoc::get(Identifier name, Location child) { 102 assert(!child.isa<NameLoc>() && 103 "a NameLoc cannot be used as a child of another NameLoc"); 104 return Base::get(child->getContext(), StandardAttributes::NameLocation, name, 105 child); 106 } 107 108 Location NameLoc::get(Identifier name, MLIRContext *context) { 109 return get(name, UnknownLoc::get(context)); 110 } 111 112 /// Return the name identifier. 113 Identifier NameLoc::getName() const { return getImpl()->name; } 114 115 /// Return the child location. 116 Location NameLoc::getChildLoc() const { return getImpl()->child; } 117 118 //===----------------------------------------------------------------------===// 119 // OpaqueLoc 120 //===----------------------------------------------------------------------===// 121 122 Location OpaqueLoc::get(uintptr_t underlyingLocation, TypeID typeID, 123 Location fallbackLocation) { 124 return Base::get(fallbackLocation->getContext(), 125 StandardAttributes::OpaqueLocation, underlyingLocation, 126 typeID, fallbackLocation); 127 } 128 129 uintptr_t OpaqueLoc::getUnderlyingLocation() const { 130 return Base::getImpl()->underlyingLocation; 131 } 132 133 TypeID OpaqueLoc::getUnderlyingTypeID() const { return getImpl()->typeID; } 134 135 Location OpaqueLoc::getFallbackLocation() const { 136 return Base::getImpl()->fallbackLocation; 137 } 138