diff --git a/mlir/include/mlir/IR/BuiltinLocationAttributes.td b/mlir/include/mlir/IR/BuiltinLocationAttributes.td new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/IR/BuiltinLocationAttributes.td @@ -0,0 +1,272 @@ +//===- BuiltinLocationAttributes.td - Builtin Locations ----*- tablegen -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Defines the set of builtin MLIR location attributes. +// +//===----------------------------------------------------------------------===// + +#ifndef BUILTIN_LOCATION_ATTRIBUTES_TD +#define BUILTIN_LOCATION_ATTRIBUTES_TD + +include "mlir/IR/BuiltinDialect.td" + +// Base class for Builtin dialect location attributes. +class Builtin_LocationAttr + : AttrDef { + let cppClassName = name; + let mnemonic = ?; +} + +//===----------------------------------------------------------------------===// +// CallSiteLoc +//===----------------------------------------------------------------------===// + +def CallSiteLoc : Builtin_LocationAttr<"CallSiteLoc"> { + let summary = "A callsite source location"; + let description = [{ + Syntax: + + ``` + callsite-location ::= `callsite` `(` location `at` location `)` + ``` + + An instance of this location allows for representing a directed stack of + location usages. This connects a location of a `callee` with the location + of a `caller`. + + Example: + + ```mlir + loc(callsite("foo" at "mysource.cc":10:8)) + ``` + }]; + let parameters = (ins "Location":$callee, "Location":$caller); + let builders = [ + AttrBuilderWithInferredContext<(ins "Location":$callee, + "Location":$caller), [{ + return $_get(callee->getContext(), callee, caller); + }]>, + AttrBuilderWithInferredContext<(ins "Location":$name, + "ArrayRef":$frames)> + ]; + let skipDefaultBuilders = 1; +} + +//===----------------------------------------------------------------------===// +// FileLineColLoc +//===----------------------------------------------------------------------===// + +def FileLineColLoc : Builtin_LocationAttr<"FileLineColLoc"> { + let summary = "A file:line:column source location"; + let description = [{ + Syntax: + + ``` + filelinecol-location ::= string-literal `:` integer-literal `:` + integer-literal + ``` + + An instance of this location represents a tuple of file, line number, and + column number. This is similar to the type of location that you get from + most source languages. + + Example: + + ```mlir + loc("mysource.cc":10:8) + ``` + }]; + let parameters = (ins "Identifier":$filename, "unsigned":$line, + "unsigned":$column); + let builders = [ + AttrBuilderWithInferredContext<(ins "Identifier":$filename, + "unsigned":$line, + "unsigned":$column), [{ + return $_get(filename.getContext(), filename, line, column); + }]>, + AttrBuilder<(ins "StringRef":$filename, "unsigned":$line, + "unsigned":$column), [{ + return $_get($_ctxt, + Identifier::get(filename.empty() ? "-" : filename, $_ctxt), + line, column); + }]> + ]; + let skipDefaultBuilders = 1; +} + +//===----------------------------------------------------------------------===// +// FusedLoc +//===----------------------------------------------------------------------===// + +def FusedLoc : Builtin_LocationAttr<"FusedLoc"> { + let summary = "A tuple of other source locations"; + let description = [{ + Syntax: + + ``` + fused-location ::= `fused` fusion-metadata? `[` location (location `,`)* `]` + fusion-metadata ::= `<` attribute-value `>` + ``` + + An instance of a `fused` location represents a grouping of several other + source locations, with optional metadata that describes the context of the + fusion. There are many places within a compiler in which several constructs + may be fused together, e.g. pattern rewriting, that normally result partial + or even total loss of location information. With `fused` locations, this is + a non-issue. + + Example: + + ```mlir + loc(fused["mysource.cc":10:8, "mysource.cc":22:8) + loc(fused<"CSE">["mysource.cc":10:8, "mysource.cc":22:8]) + ``` + }]; + let parameters = (ins ArrayRefParameter<"Location", "">:$locations, + "Attribute":$metadata); + let extraClassDeclaration = [{ + static Location get(ArrayRef locs, Attribute metadata, + MLIRContext *context); + static Location get(MLIRContext *context, ArrayRef locs) { + return get(locs, Attribute(), context); + } + }]; +} + +//===----------------------------------------------------------------------===// +// NameLoc +//===----------------------------------------------------------------------===// + +def NameLoc : Builtin_LocationAttr<"NameLoc"> { + let summary = "A named source location"; + let description = [{ + Syntax: + + ``` + name-location ::= string-literal (`(` location `)`)? + ``` + + An instance of this location allows for attaching a name to a child location. + This can be useful for representing the locations of variable, or node, + definitions. + + Example: + + ```mlir + loc("CSE"("mysource.cc":10:8)) + ``` + }]; + let parameters = (ins "Identifier":$name, "Location":$childLoc); + let builders = [ + AttrBuilderWithInferredContext<(ins "Identifier":$name, + "Location":$childLoc), [{ + return $_get(name.getContext(), name, childLoc); + }]>, + AttrBuilderWithInferredContext<(ins "Identifier":$name), [{ + return $_get(name.getContext(), name, + UnknownLoc::get(name.getContext())); + }]> + ]; + let skipDefaultBuilders = 1; +} + +//===----------------------------------------------------------------------===// +// OpaqueLoc +//===----------------------------------------------------------------------===// + +def OpaqueLoc : Builtin_LocationAttr<"OpaqueLoc"> { + let summary = "An opaque source location"; + let description = [{ + An instance of this location essentially contains a pointer to some data + structure that is external to MLIR and an optional location that can be used + if the first one is not suitable. Since it contains an external structure, + only the optional location is used during serialization. + }]; + let parameters = (ins "uintptr_t":$underlyingLocation, + "TypeID":$underlyingTypeID, + "Location":$fallbackLocation); + let builders = [ + AttrBuilderWithInferredContext<(ins "uintptr_t":$underlyingLocation, + "TypeID":$underlyingTypeID, + "Location":$fallbackLocation), [{ + return $_get(fallbackLocation->getContext(), underlyingLocation, + underlyingTypeID, fallbackLocation); + }]> + ]; + let extraClassDeclaration = [{ + /// Returns an instance of opaque location which contains a given pointer to + /// an object. The corresponding MLIR location is set to UnknownLoc. + template + static Location get(T underlyingLocation, MLIRContext *context); + + /// Returns an instance of opaque location which contains a given pointer to + /// an object and an additional MLIR location. + template + static Location get(T underlyingLocation, Location fallbackLocation) { + return get(reinterpret_cast(underlyingLocation), + TypeID::get(), fallbackLocation); + } + + /// Returns a pointer to some data structure that opaque location stores. + template static T getUnderlyingLocation(Location location) { + assert(isa(location)); + return reinterpret_cast( + location.cast().getUnderlyingLocation()); + } + + /// Returns a pointer to some data structure that opaque location stores. + /// Returns nullptr if provided location is not opaque location or if it + /// contains a pointer of different type. + template + static T getUnderlyingLocationOrNull(Location location) { + return isa(location) + ? reinterpret_cast( + location.cast().getUnderlyingLocation()) + : T(nullptr); + } + + /// Checks whether provided location is opaque location and contains a + /// pointer to an object of particular type. + template static bool isa(Location location) { + auto opaque_loc = location.dyn_cast(); + return opaque_loc && opaque_loc.getUnderlyingTypeID() == TypeID::get(); + } + }]; + let skipDefaultBuilders = 1; +} + +//===----------------------------------------------------------------------===// +// UnknownLoc +//===----------------------------------------------------------------------===// + +def UnknownLoc : Builtin_LocationAttr<"UnknownLoc"> { + let summary = "An unspecified source location"; + let description = [{ + Syntax: + + ``` + unknown-location ::= `?` + ``` + + Source location information is an extremely integral part of the MLIR + infrastructure. As such, location information is always present in the IR, + and must explicitly be set to unknown. Thus, an instance of the `unknown` + location represents an unspecified source location. + + Example: + + ```mlir + loc(?) + ``` + }]; + let extraClassDeclaration = [{ + static UnknownLoc get(MLIRContext *context); + }]; +} + +#endif // BUILTIN_LOCATION_ATTRIBUTES_TD diff --git a/mlir/include/mlir/IR/CMakeLists.txt b/mlir/include/mlir/IR/CMakeLists.txt --- a/mlir/include/mlir/IR/CMakeLists.txt +++ b/mlir/include/mlir/IR/CMakeLists.txt @@ -11,6 +11,11 @@ mlir_tablegen(BuiltinDialect.h.inc -gen-dialect-decls) add_public_tablegen_target(MLIRBuiltinDialectIncGen) +set(LLVM_TARGET_DEFINITIONS BuiltinLocationAttributes.td) +mlir_tablegen(BuiltinLocationAttributes.h.inc -gen-attrdef-decls) +mlir_tablegen(BuiltinLocationAttributes.cpp.inc -gen-attrdef-defs) +add_public_tablegen_target(MLIRBuiltinLocationAttributesIncGen) + set(LLVM_TARGET_DEFINITIONS BuiltinOps.td) mlir_tablegen(BuiltinOps.h.inc -gen-op-decls) mlir_tablegen(BuiltinOps.cpp.inc -gen-op-defs) diff --git a/mlir/include/mlir/IR/Location.h b/mlir/include/mlir/IR/Location.h --- a/mlir/include/mlir/IR/Location.h +++ b/mlir/include/mlir/IR/Location.h @@ -19,21 +19,11 @@ namespace mlir { -class Attribute; -class MLIRContext; class Identifier; -namespace detail { - -struct CallSiteLocationStorage; -struct FileLineColLocationStorage; -struct FusedLocationStorage; -struct LocationStorage; -struct NameLocationStorage; -struct OpaqueLocationStorage; -struct UnknownLocationStorage; - -} // namespace detail +//===----------------------------------------------------------------------===// +// LocationAttr +//===----------------------------------------------------------------------===// /// Location objects represent source locations information in MLIR. /// LocationAttr acts as the anchor for all Location based attributes. @@ -45,6 +35,10 @@ static bool classof(Attribute attr); }; +//===----------------------------------------------------------------------===// +// Location +//===----------------------------------------------------------------------===// + /// This class defines the main interface for locations in MLIR and acts as a /// non-nullable wrapper around a LocationAttr. class Location { @@ -94,177 +88,38 @@ return os; } -/// Represents a location as call site. "callee" is the concrete location -/// (Unknown/NameLocation/FileLineColLoc/OpaqueLoc) and "caller" points to the -/// caller's location (another CallLocation or a concrete location). Multiple -/// CallSiteLocs can be chained to form a call stack. -class CallSiteLoc - : public Attribute::AttrBase { -public: - using Base::Base; - - /// Return a uniqued call location object. - static Location get(Location callee, Location caller); - - /// Return a call site location which represents a name reference in one line - /// or a stack of frames. The input frames are ordered from innermost to - /// outermost. - static Location get(Location name, ArrayRef frames); - - /// The concrete location information this object presents. - Location getCallee() const; - - /// The caller's location. - Location getCaller() const; -}; - -/// Represents a location derived from a file/line/column location. The column -/// and line may be zero to represent unknown column and/or unknown line/column -/// information. -class FileLineColLoc - : public Attribute::AttrBase { -public: - using Base::Base; - - /// Return a uniqued FileLineCol location object. - static Location get(Identifier filename, unsigned line, unsigned column); - static Location get(StringRef filename, unsigned line, unsigned column, - MLIRContext *context); - - StringRef getFilename() const; - - unsigned getLine() const; - unsigned getColumn() const; -}; - -/// Represents a value composed of multiple source constructs, with an optional -/// metadata attribute. -class FusedLoc : public Attribute::AttrBase { -public: - using Base::Base; - - /// Return a uniqued Fused Location object. The first location in the list - /// will get precedence during diagnostic emission, with the rest being - /// displayed as supplementary "fused from here" style notes. - static Location get(ArrayRef locs, Attribute metadata, - MLIRContext *context); - static Location get(ArrayRef locs, MLIRContext *context) { - return get(locs, Attribute(), context); - } - - ArrayRef getLocations() const; - - /// Returns the optional metadata attached to this fused location. Given that - /// it is optional, the return value may be a null node. - Attribute getMetadata() const; -}; - -/// Represents an identity name attached to a child location. -class NameLoc : public Attribute::AttrBase { -public: - using Base::Base; - - /// Return a uniqued name location object. The child location must not be - /// another NameLoc. - static Location get(Identifier name, Location child); - - /// Return a uniqued name location object with an unknown child. - static Location get(Identifier name); - - /// Return the name identifier. - Identifier getName() const; - - /// Return the child location. - Location getChildLoc() const; -}; - -/// Represents an unknown location. This is always a singleton for a given -/// MLIRContext. -class UnknownLoc - : public Attribute::AttrBase { -public: - using Base::Base; - - /// Get an instance of the UnknownLoc. - static Location get(MLIRContext *context); -}; - -/// Represents a location that is external to MLIR. Contains a pointer to some -/// data structure and an optional location that can be used if the first one is -/// not suitable. Since it contains an external structure, only optional -/// location is used during serialization. -/// The class also provides a number of methods for making type-safe casts -/// between a pointer to an object and opaque location. -class OpaqueLoc : public Attribute::AttrBase { -public: - using Base::Base; - - /// Returns an instance of opaque location which contains a given pointer to - /// an object. The corresponding MLIR location is set to UnknownLoc. - template - static Location get(T underlyingLocation, MLIRContext *context) { - return get(reinterpret_cast(underlyingLocation), - TypeID::get(), UnknownLoc::get(context)); - } - - /// Returns an instance of opaque location which contains a given pointer to - /// an object and an additional MLIR location. - template - static Location get(T underlyingLocation, Location fallbackLocation) { - return get(reinterpret_cast(underlyingLocation), - TypeID::get(), fallbackLocation); - } - - /// Returns a pointer to some data structure that opaque location stores. - template static T getUnderlyingLocation(Location location) { - assert(isa(location)); - return reinterpret_cast( - location.cast().getUnderlyingLocation()); - } - - /// Returns a pointer to some data structure that opaque location stores. - /// Returns nullptr if provided location is not opaque location or if it - /// contains a pointer of different type. - template - static T getUnderlyingLocationOrNull(Location location) { - return isa(location) - ? reinterpret_cast( - location.cast().getUnderlyingLocation()) - : T(nullptr); - } +// Make Location hashable. +inline ::llvm::hash_code hash_value(Location arg) { + return hash_value(arg.impl); +} - /// Checks whether provided location is opaque location and contains a pointer - /// to an object of particular type. - template static bool isa(Location location) { - auto opaque_loc = location.dyn_cast(); - return opaque_loc && opaque_loc.getUnderlyingTypeID() == TypeID::get(); - } +} // end namespace mlir - /// Returns a pointer to the corresponding object. - uintptr_t getUnderlyingLocation() const; +//===----------------------------------------------------------------------===// +// Tablegen Attribute Declarations +//===----------------------------------------------------------------------===// - /// Returns a TypeID that represents the underlying objects c++ type. - TypeID getUnderlyingTypeID() const; +#define GET_ATTRDEF_CLASSES +#include "mlir/IR/BuiltinLocationAttributes.h.inc" - /// Returns a fallback location. - Location getFallbackLocation() const; +namespace mlir { -private: - static Location get(uintptr_t underlyingLocation, TypeID typeID, - Location fallbackLocation); -}; +//===----------------------------------------------------------------------===// +// OpaqueLoc +//===----------------------------------------------------------------------===// -// Make Location hashable. -inline ::llvm::hash_code hash_value(Location arg) { - return hash_value(arg.impl); +/// Returns an instance of opaque location which contains a given pointer to +/// an object. The corresponding MLIR location is set to UnknownLoc. +template +inline Location OpaqueLoc::get(T underlyingLocation, MLIRContext *context) { + return get(reinterpret_cast(underlyingLocation), TypeID::get(), + UnknownLoc::get(context)); } +} // namespace mlir -} // end namespace mlir +//===----------------------------------------------------------------------===// +// LLVM Utilities +//===----------------------------------------------------------------------===// namespace llvm { diff --git a/mlir/lib/CAPI/IR/IR.cpp b/mlir/lib/CAPI/IR/IR.cpp --- a/mlir/lib/CAPI/IR/IR.cpp +++ b/mlir/lib/CAPI/IR/IR.cpp @@ -113,16 +113,16 @@ MlirLocation mlirLocationFileLineColGet(MlirContext context, MlirStringRef filename, unsigned line, unsigned col) { - return wrap( - FileLineColLoc::get(unwrap(filename), line, col, unwrap(context))); + return wrap(Location( + FileLineColLoc::get(unwrap(context), unwrap(filename), line, col))); } MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller) { - return wrap(CallSiteLoc::get(unwrap(callee), unwrap(caller))); + return wrap(Location(CallSiteLoc::get(unwrap(callee), unwrap(caller)))); } MlirLocation mlirLocationUnknownGet(MlirContext context) { - return wrap(UnknownLoc::get(unwrap(context))); + return wrap(Location(UnknownLoc::get(unwrap(context)))); } bool mlirLocationEqual(MlirLocation l1, MlirLocation l2) { diff --git a/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp b/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp --- a/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp +++ b/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp @@ -81,9 +81,8 @@ // When creating the new const op, use a fused location that combines the // original const and the qbarrier that led to the quantization. - auto fusedLoc = FusedLoc::get( - {qbarrier.arg().getDefiningOp()->getLoc(), qbarrier.getLoc()}, - rewriter.getContext()); + auto fusedLoc = rewriter.getFusedLoc( + {qbarrier.arg().getDefiningOp()->getLoc(), qbarrier.getLoc()}); auto newConstOp = rewriter.create(fusedLoc, newConstValueType, newConstValue); rewriter.replaceOpWithNewOp(qbarrier, qbarrier.getType(), diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt --- a/mlir/lib/IR/CMakeLists.txt +++ b/mlir/lib/IR/CMakeLists.txt @@ -35,6 +35,7 @@ DEPENDS MLIRBuiltinAttributesIncGen MLIRBuiltinDialectIncGen + MLIRBuiltinLocationAttributesIncGen MLIRBuiltinOpsIncGen MLIRBuiltinTypesIncGen MLIRCallInterfacesIncGen diff --git a/mlir/lib/IR/Location.cpp b/mlir/lib/IR/Location.cpp --- a/mlir/lib/IR/Location.cpp +++ b/mlir/lib/IR/Location.cpp @@ -7,12 +7,19 @@ //===----------------------------------------------------------------------===// #include "mlir/IR/Location.h" -#include "LocationDetail.h" +#include "mlir/IR/Identifier.h" #include "llvm/ADT/SetVector.h" using namespace mlir; using namespace mlir::detail; +//===----------------------------------------------------------------------===// +/// Tablegen Attribute Definitions +//===----------------------------------------------------------------------===// + +#define GET_ATTRDEF_CLASSES +#include "mlir/IR/BuiltinLocationAttributes.cpp.inc" + //===----------------------------------------------------------------------===// // LocationAttr //===----------------------------------------------------------------------===// @@ -27,11 +34,7 @@ // CallSiteLoc //===----------------------------------------------------------------------===// -Location CallSiteLoc::get(Location callee, Location caller) { - return Base::get(callee->getContext(), callee, caller); -} - -Location CallSiteLoc::get(Location name, ArrayRef frames) { +CallSiteLoc CallSiteLoc::get(Location name, ArrayRef frames) { assert(!frames.empty() && "required at least 1 call frame"); Location caller = frames.back(); for (auto frame : llvm::reverse(frames.drop_back())) @@ -39,29 +42,6 @@ return CallSiteLoc::get(name, caller); } -Location CallSiteLoc::getCallee() const { return getImpl()->callee; } - -Location CallSiteLoc::getCaller() const { return getImpl()->caller; } - -//===----------------------------------------------------------------------===// -// FileLineColLoc -//===----------------------------------------------------------------------===// - -Location FileLineColLoc::get(Identifier filename, unsigned line, - unsigned column) { - return Base::get(filename.getContext(), filename, line, column); -} - -Location FileLineColLoc::get(StringRef filename, unsigned line, unsigned column, - MLIRContext *context) { - return get(Identifier::get(filename.empty() ? "-" : filename, context), line, - column); -} - -StringRef FileLineColLoc::getFilename() const { return getImpl()->filename; } -unsigned FileLineColLoc::getLine() const { return getImpl()->line; } -unsigned FileLineColLoc::getColumn() const { return getImpl()->column; } - //===----------------------------------------------------------------------===// // FusedLoc //===----------------------------------------------------------------------===// @@ -95,49 +75,3 @@ return locs.front(); return Base::get(context, locs, metadata); } - -ArrayRef FusedLoc::getLocations() const { - return getImpl()->getLocations(); -} - -Attribute FusedLoc::getMetadata() const { return getImpl()->metadata; } - -//===----------------------------------------------------------------------===// -// NameLoc -//===----------------------------------------------------------------------===// - -Location NameLoc::get(Identifier name, Location child) { - assert(!child.isa() && - "a NameLoc cannot be used as a child of another NameLoc"); - return Base::get(child->getContext(), name, child); -} - -Location NameLoc::get(Identifier name) { - return get(name, UnknownLoc::get(name.getContext())); -} - -/// Return the name identifier. -Identifier NameLoc::getName() const { return getImpl()->name; } - -/// Return the child location. -Location NameLoc::getChildLoc() const { return getImpl()->child; } - -//===----------------------------------------------------------------------===// -// OpaqueLoc -//===----------------------------------------------------------------------===// - -Location OpaqueLoc::get(uintptr_t underlyingLocation, TypeID typeID, - Location fallbackLocation) { - return Base::get(fallbackLocation->getContext(), underlyingLocation, typeID, - fallbackLocation); -} - -uintptr_t OpaqueLoc::getUnderlyingLocation() const { - return Base::getImpl()->underlyingLocation; -} - -TypeID OpaqueLoc::getUnderlyingTypeID() const { return getImpl()->typeID; } - -Location OpaqueLoc::getFallbackLocation() const { - return Base::getImpl()->fallbackLocation; -} diff --git a/mlir/lib/IR/LocationDetail.h b/mlir/lib/IR/LocationDetail.h deleted file mode 100644 --- a/mlir/lib/IR/LocationDetail.h +++ /dev/null @@ -1,162 +0,0 @@ -//===- 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_ diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp --- a/mlir/lib/IR/MLIRContext.cpp +++ b/mlir/lib/IR/MLIRContext.cpp @@ -11,7 +11,6 @@ #include "AffineMapDetail.h" #include "AttributeDetail.h" #include "IntegerSetDetail.h" -#include "LocationDetail.h" #include "TypeDetail.h" #include "mlir/IR/AffineExpr.h" #include "mlir/IR/AffineMap.h" @@ -920,7 +919,7 @@ return context->getImpl().unitAttr; } -Location UnknownLoc::get(MLIRContext *context) { +UnknownLoc UnknownLoc::get(MLIRContext *context) { return context->getImpl().unknownLocAttr; } diff --git a/mlir/lib/Parser/Lexer.cpp b/mlir/lib/Parser/Lexer.cpp --- a/mlir/lib/Parser/Lexer.cpp +++ b/mlir/lib/Parser/Lexer.cpp @@ -44,8 +44,8 @@ auto lineAndColumn = sourceMgr.getLineAndColumn(loc, mainFileID); auto *buffer = sourceMgr.getMemoryBuffer(mainFileID); - return FileLineColLoc::get(buffer->getBufferIdentifier(), lineAndColumn.first, - lineAndColumn.second, context); + return FileLineColLoc::get(context, buffer->getBufferIdentifier(), + lineAndColumn.first, lineAndColumn.second); } /// emitError - Emit an error message and return an Token::error token. diff --git a/mlir/lib/Parser/LocationParser.cpp b/mlir/lib/Parser/LocationParser.cpp --- a/mlir/lib/Parser/LocationParser.cpp +++ b/mlir/lib/Parser/LocationParser.cpp @@ -119,7 +119,7 @@ return emitError("expected integer column number in FileLineColLoc"); consumeToken(Token::integer); - loc = FileLineColLoc::get(str, line.getValue(), column.getValue(), ctx); + loc = FileLineColLoc::get(ctx, str, line.getValue(), column.getValue()); return success(); } diff --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -2088,8 +2088,8 @@ LocationAttr *sourceFileLoc) { const auto *sourceBuf = sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID()); - Location parserLoc = FileLineColLoc::get(sourceBuf->getBufferIdentifier(), - /*line=*/0, /*column=*/0, context); + Location parserLoc = FileLineColLoc::get( + context, sourceBuf->getBufferIdentifier(), /*line=*/0, /*column=*/0); if (sourceFileLoc) *sourceFileLoc = parserLoc; diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -212,7 +212,7 @@ public: Importer(MLIRContext *context, ModuleOp module) : b(context), context(context), module(module), - unknownLoc(FileLineColLoc::get("imported-bitcode", 0, 0, context)), + unknownLoc(FileLineColLoc::get(context, "imported-bitcode", 0, 0)), typeTranslator(*context) { b.setInsertionPointToStart(module.getBody()); } @@ -303,13 +303,13 @@ llvm::raw_string_ostream os(s); os << "llvm-imported-inst-%"; inst->printAsOperand(os, /*PrintType=*/false); - return FileLineColLoc::get(os.str(), 0, 0, context); + return FileLineColLoc::get(context, os.str(), 0, 0); } else if (!loc) { return unknownLoc; } // FIXME: Obtain the filename from DILocationInfo. - return FileLineColLoc::get("imported-bitcode", loc.getLine(), loc.getCol(), - context); + return FileLineColLoc::get(context, "imported-bitcode", loc.getLine(), + loc.getCol()); } Type Importer::processType(llvm::Type *type) { @@ -996,7 +996,7 @@ MLIRContext *context) { context->loadDialect(); OwningModuleRef module(ModuleOp::create( - FileLineColLoc::get("", /*line=*/0, /*column=*/0, context))); + FileLineColLoc::get(context, "", /*line=*/0, /*column=*/0))); Importer deserializer(context, module.get()); for (llvm::GlobalVariable &gv : llvmModule->globals()) { diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -95,7 +95,8 @@ return; FileLineColLoc fileLoc = extractFileLoc(func.getLoc()); - auto *file = translateFile(fileLoc ? fileLoc.getFilename() : ""); + auto *file = + translateFile(fileLoc ? fileLoc.getFilename().strref() : ""); unsigned line = fileLoc ? fileLoc.getLine() : 0; // TODO: This is the bare essentials for now. We will likely end diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp --- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp +++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp @@ -175,7 +175,7 @@ if (!emitDebugInfo) return; auto fileLoc = module.getLoc().dyn_cast(); - auto fileName = fileLoc ? fileLoc.getFilename() : ""; + auto fileName = fileLoc ? fileLoc.getFilename().strref() : ""; fileID = getNextID(); SmallVector operands; operands.push_back(fileID); diff --git a/mlir/lib/Target/SPIRV/TranslateRegistration.cpp b/mlir/lib/Target/SPIRV/TranslateRegistration.cpp --- a/mlir/lib/Target/SPIRV/TranslateRegistration.cpp +++ b/mlir/lib/Target/SPIRV/TranslateRegistration.cpp @@ -57,7 +57,7 @@ return {}; OwningModuleRef module(ModuleOp::create(FileLineColLoc::get( - input->getBufferIdentifier(), /*line=*/0, /*column=*/0, context))); + context, input->getBufferIdentifier(), /*line=*/0, /*column=*/0))); module->getBody()->push_front(spirvModule.release()); return module; @@ -146,8 +146,9 @@ return failure(); // Wrap around in a new MLIR module. - OwningModuleRef dstModule(ModuleOp::create(FileLineColLoc::get( - /*filename=*/"", /*line=*/0, /*column=*/0, &deserializationContext))); + OwningModuleRef dstModule(ModuleOp::create( + FileLineColLoc::get(&deserializationContext, + /*filename=*/"", /*line=*/0, /*column=*/0))); dstModule->getBody()->push_front(spirvModule.release()); dstModule->print(output);