//===- LocationDetail.h - MLIR Location storage details ---------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This holds implementation details of the location attributes. // //===----------------------------------------------------------------------===// #ifndef MLIR_IR_LOCATIONDETAIL_H_ #define MLIR_IR_LOCATIONDETAIL_H_ #include "mlir/IR/Attributes.h" #include "mlir/IR/Identifier.h" #include "mlir/IR/Location.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/TrailingObjects.h" namespace mlir { namespace detail { struct CallSiteLocationStorage : public AttributeStorage { CallSiteLocationStorage(Location callee, Location caller) : callee(callee), caller(caller) {} /// The hash key used for uniquing. using KeyTy = std::pair; bool operator==(const KeyTy &key) const { return key == KeyTy(callee, caller); } /// Construct a new storage instance. static CallSiteLocationStorage * construct(AttributeStorageAllocator &allocator, const KeyTy &key) { return new (allocator.allocate()) CallSiteLocationStorage(key.first, key.second); } Location callee, caller; }; struct FileLineColLocationStorage : public AttributeStorage { FileLineColLocationStorage(Identifier filename, unsigned line, unsigned column) : filename(filename), line(line), column(column) {} /// The hash key used for uniquing. using KeyTy = std::tuple; bool operator==(const KeyTy &key) const { return key == KeyTy(filename, line, column); } /// Construct a new storage instance. static FileLineColLocationStorage * construct(AttributeStorageAllocator &allocator, const KeyTy &key) { return new (allocator.allocate()) FileLineColLocationStorage(std::get<0>(key), std::get<1>(key), std::get<2>(key)); } Identifier filename; unsigned line, column; }; struct FusedLocationStorage final : public AttributeStorage, public llvm::TrailingObjects { FusedLocationStorage(unsigned numLocs, Attribute metadata) : numLocs(numLocs), metadata(metadata) {} ArrayRef getLocations() const { return ArrayRef(getTrailingObjects(), numLocs); } /// The hash key used for uniquing. using KeyTy = std::pair, Attribute>; bool operator==(const KeyTy &key) const { return key == KeyTy(getLocations(), metadata); } /// Construct a new storage instance. static FusedLocationStorage *construct(AttributeStorageAllocator &allocator, const KeyTy &key) { ArrayRef locs = key.first; auto byteSize = totalSizeToAlloc(locs.size()); auto rawMem = allocator.allocate(byteSize, alignof(FusedLocationStorage)); auto result = new (rawMem) FusedLocationStorage(locs.size(), key.second); std::uninitialized_copy(locs.begin(), locs.end(), result->getTrailingObjects()); return result; } // This stuff is used by the TrailingObjects template. friend llvm::TrailingObjects; size_t numTrailingObjects(OverloadToken) const { return numLocs; } /// Number of trailing location objects. unsigned numLocs; /// Metadata used to reason about the generation of this fused location. Attribute metadata; }; struct NameLocationStorage : public AttributeStorage { NameLocationStorage(Identifier name, Location child) : name(name), child(child) {} /// The hash key used for uniquing. using KeyTy = std::pair; bool operator==(const KeyTy &key) const { return key == KeyTy(name, child); } /// Construct a new storage instance. static NameLocationStorage *construct(AttributeStorageAllocator &allocator, const KeyTy &key) { return new (allocator.allocate()) NameLocationStorage(key.first, key.second); } Identifier name; Location child; }; struct OpaqueLocationStorage : public AttributeStorage { OpaqueLocationStorage(uintptr_t underlyingLocation, TypeID typeID, Location fallbackLocation) : underlyingLocation(underlyingLocation), typeID(typeID), fallbackLocation(fallbackLocation) {} /// The hash key used for uniquing. using KeyTy = std::tuple; bool operator==(const KeyTy &key) const { return key == KeyTy(underlyingLocation, typeID, fallbackLocation); } /// Construct a new storage instance. static OpaqueLocationStorage *construct(AttributeStorageAllocator &allocator, const KeyTy &key) { return new (allocator.allocate()) OpaqueLocationStorage(std::get<0>(key), std::get<1>(key), std::get<2>(key)); } /// Pointer to the corresponding object. uintptr_t underlyingLocation; /// A unique pointer for each type of underlyingLocation. TypeID typeID; /// An additional location that can be used if the external one is not /// suitable. Location fallbackLocation; }; } // end namespace detail } // end namespace mlir #endif // MLIR_IR_LOCATIONDETAIL_H_