[mlir][IR][NFC] Define the Location classes in ODS instead of C++
This also removes the need for LocationDetail.h. Differential Revision: https://reviews.llvm.org/D98092
This commit is contained in:
272
mlir/include/mlir/IR/BuiltinLocationAttributes.td
Normal file
272
mlir/include/mlir/IR/BuiltinLocationAttributes.td
Normal file
@@ -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<string name>
|
||||
: AttrDef<Builtin_Dialect, name, "::mlir::LocationAttr"> {
|
||||
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<Location>":$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<Location> locs, Attribute metadata,
|
||||
MLIRContext *context);
|
||||
static Location get(MLIRContext *context, ArrayRef<Location> 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 <typename T>
|
||||
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 <typename T>
|
||||
static Location get(T underlyingLocation, Location fallbackLocation) {
|
||||
return get(reinterpret_cast<uintptr_t>(underlyingLocation),
|
||||
TypeID::get<T>(), fallbackLocation);
|
||||
}
|
||||
|
||||
/// Returns a pointer to some data structure that opaque location stores.
|
||||
template <typename T> static T getUnderlyingLocation(Location location) {
|
||||
assert(isa<T>(location));
|
||||
return reinterpret_cast<T>(
|
||||
location.cast<mlir::OpaqueLoc>().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 <typename T>
|
||||
static T getUnderlyingLocationOrNull(Location location) {
|
||||
return isa<T>(location)
|
||||
? reinterpret_cast<T>(
|
||||
location.cast<mlir::OpaqueLoc>().getUnderlyingLocation())
|
||||
: T(nullptr);
|
||||
}
|
||||
|
||||
/// Checks whether provided location is opaque location and contains a
|
||||
/// pointer to an object of particular type.
|
||||
template <typename T> static bool isa(Location location) {
|
||||
auto opaque_loc = location.dyn_cast<OpaqueLoc>();
|
||||
return opaque_loc && opaque_loc.getUnderlyingTypeID() == TypeID::get<T>();
|
||||
}
|
||||
}];
|
||||
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
|
||||
@@ -11,6 +11,11 @@ set(LLVM_TARGET_DEFINITIONS BuiltinDialect.td)
|
||||
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)
|
||||
|
||||
@@ -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 @@ public:
|
||||
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,171 +88,6 @@ inline raw_ostream &operator<<(raw_ostream &os, const Location &loc) {
|
||||
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<CallSiteLoc, LocationAttr,
|
||||
detail::CallSiteLocationStorage> {
|
||||
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<Location> 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<FileLineColLoc, LocationAttr,
|
||||
detail::FileLineColLocationStorage> {
|
||||
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<FusedLoc, LocationAttr,
|
||||
detail::FusedLocationStorage> {
|
||||
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<Location> locs, Attribute metadata,
|
||||
MLIRContext *context);
|
||||
static Location get(ArrayRef<Location> locs, MLIRContext *context) {
|
||||
return get(locs, Attribute(), context);
|
||||
}
|
||||
|
||||
ArrayRef<Location> 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<NameLoc, LocationAttr,
|
||||
detail::NameLocationStorage> {
|
||||
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<UnknownLoc, LocationAttr, AttributeStorage> {
|
||||
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<OpaqueLoc, LocationAttr,
|
||||
detail::OpaqueLocationStorage> {
|
||||
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 <typename T>
|
||||
static Location get(T underlyingLocation, MLIRContext *context) {
|
||||
return get(reinterpret_cast<uintptr_t>(underlyingLocation),
|
||||
TypeID::get<T>(), UnknownLoc::get(context));
|
||||
}
|
||||
|
||||
/// Returns an instance of opaque location which contains a given pointer to
|
||||
/// an object and an additional MLIR location.
|
||||
template <typename T>
|
||||
static Location get(T underlyingLocation, Location fallbackLocation) {
|
||||
return get(reinterpret_cast<uintptr_t>(underlyingLocation),
|
||||
TypeID::get<T>(), fallbackLocation);
|
||||
}
|
||||
|
||||
/// Returns a pointer to some data structure that opaque location stores.
|
||||
template <typename T> static T getUnderlyingLocation(Location location) {
|
||||
assert(isa<T>(location));
|
||||
return reinterpret_cast<T>(
|
||||
location.cast<mlir::OpaqueLoc>().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 <typename T>
|
||||
static T getUnderlyingLocationOrNull(Location location) {
|
||||
return isa<T>(location)
|
||||
? reinterpret_cast<T>(
|
||||
location.cast<mlir::OpaqueLoc>().getUnderlyingLocation())
|
||||
: T(nullptr);
|
||||
}
|
||||
|
||||
/// Checks whether provided location is opaque location and contains a pointer
|
||||
/// to an object of particular type.
|
||||
template <typename T> static bool isa(Location location) {
|
||||
auto opaque_loc = location.dyn_cast<OpaqueLoc>();
|
||||
return opaque_loc && opaque_loc.getUnderlyingTypeID() == TypeID::get<T>();
|
||||
}
|
||||
|
||||
/// Returns a pointer to the corresponding object.
|
||||
uintptr_t getUnderlyingLocation() const;
|
||||
|
||||
/// Returns a TypeID that represents the underlying objects c++ type.
|
||||
TypeID getUnderlyingTypeID() const;
|
||||
|
||||
/// Returns a fallback location.
|
||||
Location getFallbackLocation() const;
|
||||
|
||||
private:
|
||||
static Location get(uintptr_t underlyingLocation, TypeID typeID,
|
||||
Location fallbackLocation);
|
||||
};
|
||||
|
||||
// Make Location hashable.
|
||||
inline ::llvm::hash_code hash_value(Location arg) {
|
||||
return hash_value(arg.impl);
|
||||
@@ -266,6 +95,32 @@ inline ::llvm::hash_code hash_value(Location arg) {
|
||||
|
||||
} // end namespace mlir
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Tablegen Attribute Declarations
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define GET_ATTRDEF_CLASSES
|
||||
#include "mlir/IR/BuiltinLocationAttributes.h.inc"
|
||||
|
||||
namespace mlir {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OpaqueLoc
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Returns an instance of opaque location which contains a given pointer to
|
||||
/// an object. The corresponding MLIR location is set to UnknownLoc.
|
||||
template <typename T>
|
||||
inline Location OpaqueLoc::get(T underlyingLocation, MLIRContext *context) {
|
||||
return get(reinterpret_cast<uintptr_t>(underlyingLocation), TypeID::get<T>(),
|
||||
UnknownLoc::get(context));
|
||||
}
|
||||
} // namespace mlir
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LLVM Utilities
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// Type hash just like pointers.
|
||||
|
||||
@@ -113,16 +113,16 @@ void mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags) {
|
||||
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) {
|
||||
|
||||
@@ -81,9 +81,8 @@ QuantizedConstRewrite::matchAndRewrite(QuantizeCastOp qbarrier,
|
||||
|
||||
// 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<ConstantOp>(fusedLoc, newConstValueType, newConstValue);
|
||||
rewriter.replaceOpWithNewOp<StorageCastOp>(qbarrier, qbarrier.getType(),
|
||||
|
||||
@@ -35,6 +35,7 @@ add_mlir_library(MLIRIR
|
||||
DEPENDS
|
||||
MLIRBuiltinAttributesIncGen
|
||||
MLIRBuiltinDialectIncGen
|
||||
MLIRBuiltinLocationAttributesIncGen
|
||||
MLIRBuiltinOpsIncGen
|
||||
MLIRBuiltinTypesIncGen
|
||||
MLIRCallInterfacesIncGen
|
||||
|
||||
@@ -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 @@ bool LocationAttr::classof(Attribute attr) {
|
||||
// CallSiteLoc
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Location CallSiteLoc::get(Location callee, Location caller) {
|
||||
return Base::get(callee->getContext(), callee, caller);
|
||||
}
|
||||
|
||||
Location CallSiteLoc::get(Location name, ArrayRef<Location> frames) {
|
||||
CallSiteLoc CallSiteLoc::get(Location name, ArrayRef<Location> 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 @@ Location CallSiteLoc::get(Location name, ArrayRef<Location> frames) {
|
||||
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 @@ Location FusedLoc::get(ArrayRef<Location> locs, Attribute metadata,
|
||||
return locs.front();
|
||||
return Base::get(context, locs, metadata);
|
||||
}
|
||||
|
||||
ArrayRef<Location> FusedLoc::getLocations() const {
|
||||
return getImpl()->getLocations();
|
||||
}
|
||||
|
||||
Attribute FusedLoc::getMetadata() const { return getImpl()->metadata; }
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// NameLoc
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Location NameLoc::get(Identifier name, Location child) {
|
||||
assert(!child.isa<NameLoc>() &&
|
||||
"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;
|
||||
}
|
||||
|
||||
@@ -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<Location, Location>;
|
||||
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>())
|
||||
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<Identifier, unsigned, unsigned>;
|
||||
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>())
|
||||
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, Location> {
|
||||
FusedLocationStorage(unsigned numLocs, Attribute metadata)
|
||||
: numLocs(numLocs), metadata(metadata) {}
|
||||
|
||||
ArrayRef<Location> getLocations() const {
|
||||
return ArrayRef<Location>(getTrailingObjects<Location>(), numLocs);
|
||||
}
|
||||
|
||||
/// The hash key used for uniquing.
|
||||
using KeyTy = std::pair<ArrayRef<Location>, 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<Location> locs = key.first;
|
||||
|
||||
auto byteSize = totalSizeToAlloc<Location>(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<Location>());
|
||||
return result;
|
||||
}
|
||||
|
||||
// This stuff is used by the TrailingObjects template.
|
||||
friend llvm::TrailingObjects<FusedLocationStorage, Location>;
|
||||
size_t numTrailingObjects(OverloadToken<Location>) 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<Identifier, Location>;
|
||||
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>())
|
||||
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<uintptr_t, TypeID, Location>;
|
||||
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>())
|
||||
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_
|
||||
@@ -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 @@ UnitAttr UnitAttr::get(MLIRContext *context) {
|
||||
return context->getImpl().unitAttr;
|
||||
}
|
||||
|
||||
Location UnknownLoc::get(MLIRContext *context) {
|
||||
UnknownLoc UnknownLoc::get(MLIRContext *context) {
|
||||
return context->getImpl().unknownLocAttr;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ Location Lexer::getEncodedSourceLocation(llvm::SMLoc loc) {
|
||||
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.
|
||||
|
||||
@@ -119,7 +119,7 @@ ParseResult Parser::parseNameOrFileLineColLocation(LocationAttr &loc) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -2088,8 +2088,8 @@ LogicalResult mlir::parseSourceFile(const llvm::SourceMgr &sourceMgr,
|
||||
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;
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ class Importer {
|
||||
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 @@ Location Importer::processDebugLoc(const llvm::DebugLoc &loc,
|
||||
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 @@ mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
|
||||
MLIRContext *context) {
|
||||
context->loadDialect<LLVMDialect>();
|
||||
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()) {
|
||||
|
||||
@@ -95,7 +95,8 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
|
||||
return;
|
||||
|
||||
FileLineColLoc fileLoc = extractFileLoc(func.getLoc());
|
||||
auto *file = translateFile(fileLoc ? fileLoc.getFilename() : "<unknown>");
|
||||
auto *file =
|
||||
translateFile(fileLoc ? fileLoc.getFilename().strref() : "<unknown>");
|
||||
unsigned line = fileLoc ? fileLoc.getLine() : 0;
|
||||
|
||||
// TODO: This is the bare essentials for now. We will likely end
|
||||
|
||||
@@ -175,7 +175,7 @@ void Serializer::processDebugInfo() {
|
||||
if (!emitDebugInfo)
|
||||
return;
|
||||
auto fileLoc = module.getLoc().dyn_cast<FileLineColLoc>();
|
||||
auto fileName = fileLoc ? fileLoc.getFilename() : "<unknown>";
|
||||
auto fileName = fileLoc ? fileLoc.getFilename().strref() : "<unknown>";
|
||||
fileID = getNextID();
|
||||
SmallVector<uint32_t, 16> operands;
|
||||
operands.push_back(fileID);
|
||||
|
||||
@@ -57,7 +57,7 @@ static OwningModuleRef deserializeModule(const llvm::MemoryBuffer *input,
|
||||
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 @@ static LogicalResult roundTripModule(ModuleOp srcModule, bool emitDebugInfo,
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user