1 //===- LocationDetail.h - MLIR Location storage details ---------*- C++ -*-===// 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 // This holds implementation details of the location attributes. 10 // 11 //===----------------------------------------------------------------------===// 12 #ifndef MLIR_IR_LOCATIONDETAIL_H_ 13 #define MLIR_IR_LOCATIONDETAIL_H_ 14 15 #include "mlir/IR/Attributes.h" 16 #include "mlir/IR/Identifier.h" 17 #include "mlir/IR/Location.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/Support/TrailingObjects.h" 20 21 namespace mlir { 22 23 namespace detail { 24 25 struct CallSiteLocationStorage : public AttributeStorage { CallSiteLocationStorageCallSiteLocationStorage26 CallSiteLocationStorage(Location callee, Location caller) 27 : callee(callee), caller(caller) {} 28 29 /// The hash key used for uniquing. 30 using KeyTy = std::pair<Location, Location>; 31 bool operator==(const KeyTy &key) const { 32 return key == KeyTy(callee, caller); 33 } 34 35 /// Construct a new storage instance. 36 static CallSiteLocationStorage * constructCallSiteLocationStorage37 construct(AttributeStorageAllocator &allocator, const KeyTy &key) { 38 return new (allocator.allocate<CallSiteLocationStorage>()) 39 CallSiteLocationStorage(key.first, key.second); 40 } 41 42 Location callee, caller; 43 }; 44 45 struct FileLineColLocationStorage : public AttributeStorage { FileLineColLocationStorageFileLineColLocationStorage46 FileLineColLocationStorage(Identifier filename, unsigned line, 47 unsigned column) 48 : filename(filename), line(line), column(column) {} 49 50 /// The hash key used for uniquing. 51 using KeyTy = std::tuple<Identifier, unsigned, unsigned>; 52 bool operator==(const KeyTy &key) const { 53 return key == KeyTy(filename, line, column); 54 } 55 56 /// Construct a new storage instance. 57 static FileLineColLocationStorage * constructFileLineColLocationStorage58 construct(AttributeStorageAllocator &allocator, const KeyTy &key) { 59 return new (allocator.allocate<FileLineColLocationStorage>()) 60 FileLineColLocationStorage(std::get<0>(key), std::get<1>(key), 61 std::get<2>(key)); 62 } 63 64 Identifier filename; 65 unsigned line, column; 66 }; 67 68 struct FusedLocationStorage final 69 : public AttributeStorage, 70 public llvm::TrailingObjects<FusedLocationStorage, Location> { FusedLocationStoragefinal71 FusedLocationStorage(unsigned numLocs, Attribute metadata) 72 : numLocs(numLocs), metadata(metadata) {} 73 getLocationsfinal74 ArrayRef<Location> getLocations() const { 75 return ArrayRef<Location>(getTrailingObjects<Location>(), numLocs); 76 } 77 78 /// The hash key used for uniquing. 79 using KeyTy = std::pair<ArrayRef<Location>, Attribute>; 80 bool operator==(const KeyTy &key) const { 81 return key == KeyTy(getLocations(), metadata); 82 } 83 84 /// Construct a new storage instance. constructfinal85 static FusedLocationStorage *construct(AttributeStorageAllocator &allocator, 86 const KeyTy &key) { 87 ArrayRef<Location> locs = key.first; 88 89 auto byteSize = totalSizeToAlloc<Location>(locs.size()); 90 auto rawMem = allocator.allocate(byteSize, alignof(FusedLocationStorage)); 91 auto result = new (rawMem) FusedLocationStorage(locs.size(), key.second); 92 93 std::uninitialized_copy(locs.begin(), locs.end(), 94 result->getTrailingObjects<Location>()); 95 return result; 96 } 97 98 // This stuff is used by the TrailingObjects template. 99 friend llvm::TrailingObjects<FusedLocationStorage, Location>; numTrailingObjectsfinal100 size_t numTrailingObjects(OverloadToken<Location>) const { return numLocs; } 101 102 /// Number of trailing location objects. 103 unsigned numLocs; 104 105 /// Metadata used to reason about the generation of this fused location. 106 Attribute metadata; 107 }; 108 109 struct NameLocationStorage : public AttributeStorage { NameLocationStorageNameLocationStorage110 NameLocationStorage(Identifier name, Location child) 111 : name(name), child(child) {} 112 113 /// The hash key used for uniquing. 114 using KeyTy = std::pair<Identifier, Location>; 115 bool operator==(const KeyTy &key) const { return key == KeyTy(name, child); } 116 117 /// Construct a new storage instance. constructNameLocationStorage118 static NameLocationStorage *construct(AttributeStorageAllocator &allocator, 119 const KeyTy &key) { 120 return new (allocator.allocate<NameLocationStorage>()) 121 NameLocationStorage(key.first, key.second); 122 } 123 124 Identifier name; 125 Location child; 126 }; 127 128 struct OpaqueLocationStorage : public AttributeStorage { OpaqueLocationStorageOpaqueLocationStorage129 OpaqueLocationStorage(uintptr_t underlyingLocation, TypeID typeID, 130 Location fallbackLocation) 131 : underlyingLocation(underlyingLocation), typeID(typeID), 132 fallbackLocation(fallbackLocation) {} 133 134 /// The hash key used for uniquing. 135 using KeyTy = std::tuple<uintptr_t, TypeID, Location>; 136 bool operator==(const KeyTy &key) const { 137 return key == KeyTy(underlyingLocation, typeID, fallbackLocation); 138 } 139 140 /// Construct a new storage instance. constructOpaqueLocationStorage141 static OpaqueLocationStorage *construct(AttributeStorageAllocator &allocator, 142 const KeyTy &key) { 143 return new (allocator.allocate<OpaqueLocationStorage>()) 144 OpaqueLocationStorage(std::get<0>(key), std::get<1>(key), 145 std::get<2>(key)); 146 } 147 148 /// Pointer to the corresponding object. 149 uintptr_t underlyingLocation; 150 151 /// A unique pointer for each type of underlyingLocation. 152 TypeID typeID; 153 154 /// An additional location that can be used if the external one is not 155 /// suitable. 156 Location fallbackLocation; 157 }; 158 159 } // end namespace detail 160 } // end namespace mlir 161 162 #endif // MLIR_IR_LOCATIONDETAIL_H_ 163