[Mlir-commits] [mlir] aef89c8 - [mlir] Cleanup lingering problems surrounding attribute/type aliases
River Riddle
llvmlistbot at llvm.org
Wed Nov 30 17:03:17 PST 2022
Author: River Riddle
Date: 2022-11-30T17:02:54-08:00
New Revision: aef89c8b41847c7235e00fbf8b2a2f10cb1aad25
URL: https://github.com/llvm/llvm-project/commit/aef89c8b41847c7235e00fbf8b2a2f10cb1aad25
DIFF: https://github.com/llvm/llvm-project/commit/aef89c8b41847c7235e00fbf8b2a2f10cb1aad25.diff
LOG: [mlir] Cleanup lingering problems surrounding attribute/type aliases
This commit refactors attribute/type alias generation to be similar to how
we do it for operations, i.e. we generate aliases determined on what is
actually necessary when printing the IR (using a dummy printer for alias
collection). This allows for generating aliases only when necessary, and
also allows for proper propagation of when a nested alias can be deferred.
This also necessitated a fix for location parsing to actually parse aliases
instead of ignoring them.
Fixes #59041
Differential Revision: https://reviews.llvm.org/D138886
Added:
Modified:
mlir/include/mlir/IR/OpImplementation.h
mlir/lib/AsmParser/LocationParser.cpp
mlir/lib/IR/AsmPrinter.cpp
mlir/test/Dialect/DLTI/roundtrip.mlir
mlir/test/Dialect/SparseTensor/sparse_vector_chain.mlir
mlir/test/Dialect/SparseTensor/sparse_vector_index.mlir
mlir/test/IR/pretty-locations.mlir
mlir/test/IR/print-attr-type-aliases.mlir
mlir/test/Target/LLVMIR/Import/debug-info.ll
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index c6e5abd904fe9..e517794dd1bd1 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -181,7 +181,7 @@ class AsmPrinter {
virtual void printSymbolName(StringRef symbolRef);
/// Print a handle to the given dialect resource.
- void printResourceHandle(const AsmDialectResourceHandle &resource);
+ virtual void printResourceHandle(const AsmDialectResourceHandle &resource);
/// Print an optional arrow followed by a type list.
template <typename TypeRange>
diff --git a/mlir/lib/AsmParser/LocationParser.cpp b/mlir/lib/AsmParser/LocationParser.cpp
index cf1e8afaab281..02cb3ed22c9bb 100644
--- a/mlir/lib/AsmParser/LocationParser.cpp
+++ b/mlir/lib/AsmParser/LocationParser.cpp
@@ -149,6 +149,16 @@ ParseResult Parser::parseNameOrFileLineColLocation(LocationAttr &loc) {
}
ParseResult Parser::parseLocationInstance(LocationAttr &loc) {
+ // Handle aliases.
+ if (getToken().is(Token::hash_identifier)) {
+ Attribute locAttr = parseExtendedAttr(Type());
+ if (!locAttr)
+ return failure();
+ if (!(loc = dyn_cast<LocationAttr>(locAttr)))
+ return emitError("expected location attribute, but got") << locAttr;
+ return success();
+ }
+
// Handle either name or filelinecol locations.
if (getToken().is(Token::string))
return parseNameOrFileLineColLocation(loc);
diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index c06e96db32bbf..f1d5b7bab71de 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -389,7 +389,8 @@ class AsmPrinter::Impl {
bool withKeyword = false);
void printNamedAttribute(NamedAttribute attr);
void printTrailingLocation(Location loc, bool allowAlias = true);
- void printLocationInternal(LocationAttr loc, bool pretty = false);
+ void printLocationInternal(LocationAttr loc, bool pretty = false,
+ bool isTopLevel = false);
/// Print a dense elements attribute. If 'allowHex' is true, a hex string is
/// used instead of individual elements when the elements attr is large.
@@ -495,14 +496,21 @@ class AliasInitializer {
/// Visit the given attribute to see if it has an alias. `canBeDeferred` is
/// set to true if the originator of this attribute can resolve the alias
/// after parsing has completed (e.g. in the case of operation locations).
- /// Returns the maximum alias depth of the attribute.
- size_t visit(Attribute attr, bool canBeDeferred = false) {
- return visitImpl(attr, aliases, canBeDeferred);
+ /// `elideType` indicates if the type of the attribute should be skipped when
+ /// looking for nested aliases. Returns the maximum alias depth of the
+ /// attribute, and the alias index of this attribute.
+ std::pair<size_t, size_t> visit(Attribute attr, bool canBeDeferred = false,
+ bool elideType = false) {
+ return visitImpl(attr, aliases, canBeDeferred, elideType);
}
- /// Visit the given type to see if it has an alias. Returns the maximum alias
- /// depth of the type.
- size_t visit(Type type) { return visitImpl(type, aliases); }
+ /// Visit the given type to see if it has an alias. `canBeDeferred` is
+ /// set to true if the originator of this attribute can resolve the alias
+ /// after parsing has completed. Returns the maximum alias depth of the type,
+ /// and the alias index of this type.
+ std::pair<size_t, size_t> visit(Type type, bool canBeDeferred = false) {
+ return visitImpl(type, aliases, canBeDeferred);
+ }
private:
struct InProgressAliasInfo {
@@ -530,16 +538,23 @@ class AliasInitializer {
bool isType : 1;
/// If this alias can be deferred or not.
bool canBeDeferred : 1;
+ /// Indices for child aliases.
+ SmallVector<size_t> childIndices;
};
/// Visit the given attribute or type to see if it has an alias.
/// `canBeDeferred` is set to true if the originator of this value can resolve
/// the alias after parsing has completed (e.g. in the case of operation
- /// locations). Returns the maximum alias depth of the value.
- template <typename T>
- size_t visitImpl(T value,
- llvm::MapVector<const void *, InProgressAliasInfo> &aliases,
- bool canBeDeferred = false);
+ /// locations). Returns the maximum alias depth of the value, and its alias
+ /// index.
+ template <typename T, typename... PrintArgs>
+ std::pair<size_t, size_t>
+ visitImpl(T value,
+ llvm::MapVector<const void *, InProgressAliasInfo> &aliases,
+ bool canBeDeferred, PrintArgs &&...printArgs);
+
+ /// Mark the given alias as non-deferrable.
+ void markAliasNonDeferrable(size_t aliasIndex);
/// Try to generate an alias for the provided symbol. If an alias is
/// generated, the provided alias mapping and reverse mapping are updated.
@@ -722,7 +737,7 @@ class DummyAliasOperationPrinter : private OpAsmPrinter {
/// The following are hooks of `OpAsmPrinter` that are not necessary for
/// determining potential aliases.
- void printFloat(const APFloat &value) override {}
+ void printFloat(const APFloat &) override {}
void printAffineMapOfSSAIds(AffineMapAttr, ValueRange) override {}
void printAffineExprOfSSAIds(AffineExpr, ValueRange, ValueRange) override {}
void printNewline() override {}
@@ -736,6 +751,7 @@ class DummyAliasOperationPrinter : private OpAsmPrinter {
os << "%";
}
void printKeywordOrString(StringRef) override {}
+ void printResourceHandle(const AsmDialectResourceHandle &) override {}
void printSymbolName(StringRef) override {}
void printSuccessor(Block *) override {}
void printSuccessorAndUseList(Block *, ValueRange) override {}
@@ -750,6 +766,149 @@ class DummyAliasOperationPrinter : private OpAsmPrinter {
/// A dummy output stream.
mutable llvm::raw_null_ostream os;
};
+
+class DummyAliasDialectAsmPrinter : public DialectAsmPrinter {
+public:
+ explicit DummyAliasDialectAsmPrinter(AliasInitializer &initializer,
+ bool canBeDeferred,
+ SmallVectorImpl<size_t> &childIndices)
+ : initializer(initializer), canBeDeferred(canBeDeferred),
+ childIndices(childIndices) {}
+
+ /// Print the given attribute/type, visiting any nested aliases that would be
+ /// generated as part of printing. Returns the maximum alias depth found while
+ /// printing the given value.
+ template <typename T, typename... PrintArgs>
+ size_t printAndVisitNestedAliases(T value, PrintArgs &&...printArgs) {
+ printAndVisitNestedAliasesImpl(value, printArgs...);
+ return maxAliasDepth;
+ }
+
+private:
+ /// Print the given attribute/type, visiting any nested aliases that would be
+ /// generated as part of printing.
+ void printAndVisitNestedAliasesImpl(Attribute attr, bool elideType) {
+ if (!isa<BuiltinDialect>(attr.getDialect()))
+ return attr.getDialect().printAttribute(attr, *this);
+
+ // Process the builtin attributes.
+ if (attr.isa<AffineMapAttr, DenseArrayAttr, FloatAttr, IntegerAttr,
+ IntegerSetAttr, UnitAttr>())
+ return;
+ if (auto dictAttr = dyn_cast<DictionaryAttr>(attr)) {
+ for (const NamedAttribute &nestedAttr : dictAttr.getValue()) {
+ printAttribute(nestedAttr.getName());
+ printAttribute(nestedAttr.getValue());
+ }
+ } else if (auto arrayAttr = dyn_cast<ArrayAttr>(attr)) {
+ for (Attribute nestedAttr : arrayAttr.getValue())
+ printAttribute(nestedAttr);
+ } else if (auto typeAttr = dyn_cast<TypeAttr>(attr)) {
+ printType(typeAttr.getValue());
+ } else if (auto locAttr = dyn_cast<OpaqueLoc>(attr)) {
+ printAttribute(locAttr.getFallbackLocation());
+ } else if (auto locAttr = dyn_cast<NameLoc>(attr)) {
+ if (!isa<UnknownLoc>(locAttr.getChildLoc()))
+ printAttribute(locAttr.getChildLoc());
+ } else if (auto locAttr = dyn_cast<CallSiteLoc>(attr)) {
+ printAttribute(locAttr.getCallee());
+ printAttribute(locAttr.getCaller());
+ } else if (auto locAttr = dyn_cast<FusedLoc>(attr)) {
+ if (Attribute metadata = locAttr.getMetadata())
+ printAttribute(metadata);
+ for (Location nestedLoc : locAttr.getLocations())
+ printAttribute(nestedLoc);
+ }
+
+ // Don't print the type if we must elide it, or if it is a None type.
+ if (!elideType) {
+ if (auto typedAttr = attr.dyn_cast<TypedAttr>()) {
+ Type attrType = typedAttr.getType();
+ if (!attrType.isa<NoneType>())
+ printType(attrType);
+ }
+ }
+ }
+ void printAndVisitNestedAliasesImpl(Type type) {
+ if (!isa<BuiltinDialect>(type.getDialect()))
+ return type.getDialect().printType(type, *this);
+
+ // Only visit the layout of memref if it isn't the identity.
+ if (auto memrefTy = type.dyn_cast<MemRefType>()) {
+ printType(memrefTy.getElementType());
+ MemRefLayoutAttrInterface layout = memrefTy.getLayout();
+ if (!layout.isa<AffineMapAttr>() || !layout.isIdentity())
+ printAttribute(memrefTy.getLayout());
+ if (memrefTy.getMemorySpace())
+ printAttribute(memrefTy.getMemorySpace());
+ return;
+ }
+
+ // For most builtin types, we can simply walk the sub elements.
+ if (auto subElementInterface = dyn_cast<SubElementTypeInterface>(type)) {
+ auto visitFn = [&](auto element) {
+ if (element)
+ (void)printAlias(element);
+ };
+ subElementInterface.walkImmediateSubElements(visitFn, visitFn);
+ }
+ }
+
+ /// Consider the given type to be printed for an alias.
+ void printType(Type type) override {
+ recordAliasResult(initializer.visit(type, canBeDeferred));
+ }
+
+ /// Consider the given attribute to be printed for an alias.
+ void printAttribute(Attribute attr) override {
+ recordAliasResult(initializer.visit(attr, canBeDeferred));
+ }
+ void printAttributeWithoutType(Attribute attr) override {
+ recordAliasResult(
+ initializer.visit(attr, canBeDeferred, /*elideType=*/true));
+ }
+ LogicalResult printAlias(Attribute attr) override {
+ printAttribute(attr);
+ return success();
+ }
+ LogicalResult printAlias(Type type) override {
+ printType(type);
+ return success();
+ }
+
+ /// Record the alias result of a child element.
+ void recordAliasResult(std::pair<size_t, size_t> aliasDepthAndIndex) {
+ childIndices.push_back(aliasDepthAndIndex.second);
+ if (aliasDepthAndIndex.first > maxAliasDepth)
+ maxAliasDepth = aliasDepthAndIndex.first;
+ }
+
+ /// Return a null stream as the output stream, this will ignore any data fed
+ /// to it.
+ raw_ostream &getStream() const override { return os; }
+
+ /// The following are hooks of `DialectAsmPrinter` that are not necessary for
+ /// determining potential aliases.
+ void printFloat(const APFloat &) override {}
+ void printKeywordOrString(StringRef) override {}
+ void printSymbolName(StringRef) override {}
+ void printResourceHandle(const AsmDialectResourceHandle &) override {}
+
+ /// The initializer to use when identifying aliases.
+ AliasInitializer &initializer;
+
+ /// If the aliases visited by this printer can be deferred.
+ bool canBeDeferred;
+
+ /// The indices of child aliases.
+ SmallVectorImpl<size_t> &childIndices;
+
+ /// The maximum alias depth found by the printer.
+ size_t maxAliasDepth = 0;
+
+ /// A dummy output stream.
+ mutable llvm::raw_null_ostream os;
+};
} // namespace
/// Sanitize the given name such that it can be used as a valid identifier. If
@@ -836,48 +995,48 @@ void AliasInitializer::initialize(
initializeAliases(aliases, attrTypeToAlias);
}
-template <typename T>
-size_t AliasInitializer::visitImpl(
+template <typename T, typename... PrintArgs>
+std::pair<size_t, size_t> AliasInitializer::visitImpl(
T value, llvm::MapVector<const void *, InProgressAliasInfo> &aliases,
- bool canBeDeferred) {
+ bool canBeDeferred, PrintArgs &&...printArgs) {
auto [it, inserted] =
aliases.insert({value.getAsOpaquePointer(), InProgressAliasInfo()});
+ size_t aliasIndex = std::distance(aliases.begin(), it);
if (!inserted) {
// Make sure that the alias isn't deferred if we don't permit it.
if (!canBeDeferred)
- it->second.canBeDeferred = false;
- return it->second.aliasDepth;
+ markAliasNonDeferrable(aliasIndex);
+ return {static_cast<size_t>(it->second.aliasDepth), aliasIndex};
}
- // Try to generate an alias for this attribute.
+ // Try to generate an alias for this value.
generateAlias(value, it->second, canBeDeferred);
- size_t aliasIndex = std::distance(aliases.begin(), it);
- // Check for any sub elements.
- using SubElementInterfaceT =
- std::conditional_t<std::is_same_v<T, Type>, SubElementTypeInterface,
- SubElementAttrInterface>;
- if (auto subElementInterface = dyn_cast<SubElementInterfaceT>(value)) {
- size_t maxAliasDepth = 0;
- auto visitSubElement = [&](auto element) {
- if (!element)
- return;
- if (size_t depth = visit(element))
- maxAliasDepth = std::max(maxAliasDepth, depth + 1);
- };
- subElementInterface.walkImmediateSubElements(visitSubElement,
- visitSubElement);
+ // Print the value, capturing any nested elements that require aliases.
+ SmallVector<size_t> childAliases;
+ DummyAliasDialectAsmPrinter printer(*this, canBeDeferred, childAliases);
+ size_t maxAliasDepth =
+ printer.printAndVisitNestedAliases(value, printArgs...);
- // Make sure to recompute `it` in case the map was reallocated.
- it = std::next(aliases.begin(), aliasIndex);
+ // Make sure to recompute `it` in case the map was reallocated.
+ it = std::next(aliases.begin(), aliasIndex);
- // If we had sub elements, update to account for the depth.
- if (maxAliasDepth)
- it->second.aliasDepth = maxAliasDepth;
- }
+ // If we had sub elements, update to account for the depth.
+ it->second.childIndices = std::move(childAliases);
+ if (maxAliasDepth)
+ it->second.aliasDepth = maxAliasDepth + 1;
// Propagate the alias depth of the value.
- return it->second.aliasDepth;
+ return {(size_t)it->second.aliasDepth, aliasIndex};
+}
+
+void AliasInitializer::markAliasNonDeferrable(size_t aliasIndex) {
+ auto it = std::next(aliases.begin(), aliasIndex);
+ it->second.canBeDeferred = false;
+
+ // Propagate the non-deferrable flag to any child aliases.
+ for (size_t childIndex : it->second.childIndices)
+ markAliasNonDeferrable(childIndex);
}
template <typename T>
@@ -1681,7 +1840,12 @@ void AsmPrinter::Impl::printTrailingLocation(Location loc, bool allowAlias) {
printLocation(loc, /*allowAlias=*/allowAlias);
}
-void AsmPrinter::Impl::printLocationInternal(LocationAttr loc, bool pretty) {
+void AsmPrinter::Impl::printLocationInternal(LocationAttr loc, bool pretty,
+ bool isTopLevel) {
+ // If this isn't a top-level location, check for an alias.
+ if (!isTopLevel && succeeded(state.getAliasState().getAlias(loc, os)))
+ return;
+
TypeSwitch<LocationAttr>(loc)
.Case<OpaqueLoc>([&](OpaqueLoc loc) {
printLocationInternal(loc.getFallbackLocation(), pretty);
@@ -1802,11 +1966,11 @@ static void printFloatValue(const APFloat &apValue, raw_ostream &os) {
void AsmPrinter::Impl::printLocation(LocationAttr loc, bool allowAlias) {
if (printerFlags.shouldPrintDebugInfoPrettyForm())
- return printLocationInternal(loc, /*pretty=*/true);
+ return printLocationInternal(loc, /*pretty=*/true, /*isTopLevel=*/true);
os << "loc(";
if (!allowAlias || failed(printAlias(loc)))
- printLocationInternal(loc);
+ printLocationInternal(loc, /*pretty=*/false, /*isTopLevel=*/true);
os << ')';
}
diff --git a/mlir/test/Dialect/DLTI/roundtrip.mlir b/mlir/test/Dialect/DLTI/roundtrip.mlir
index ec66bae1a066b..613dc354d895d 100644
--- a/mlir/test/Dialect/DLTI/roundtrip.mlir
+++ b/mlir/test/Dialect/DLTI/roundtrip.mlir
@@ -2,10 +2,12 @@
// Round-tripping the syntax.
+// CHECK: #[[MAP:.*]] = affine_map<(d0) -> (d0)>
+
"test.unknown_op"() {
// CHECK: #dlti.dl_entry<"test.identifier", 42 : i64>
test.unknown_attr_1 = #dlti.dl_entry<"test.identifier", 42 : i64>,
- // CHECK: #dlti.dl_entry<"test.identifier", affine_map<(d0) -> (d0)>>
+ // CHECK: #dlti.dl_entry<"test.identifier", #[[MAP]]>
test.unknown_attr_2 = #dlti.dl_entry<"test.identifier", affine_map<(d0) -> (d0)>>,
// CHECK: #dlti.dl_entry<i32, 32 : index>
test.unknown_attr_3 = #dlti.dl_entry<i32, 32 : index>,
diff --git a/mlir/test/Dialect/SparseTensor/sparse_vector_chain.mlir b/mlir/test/Dialect/SparseTensor/sparse_vector_chain.mlir
index 612927c471920..824fd40448d20 100644
--- a/mlir/test/Dialect/SparseTensor/sparse_vector_chain.mlir
+++ b/mlir/test/Dialect/SparseTensor/sparse_vector_chain.mlir
@@ -84,7 +84,7 @@
// CHECK: } attributes {"Emitted from" = "linalg.generic"}
// CHECK: %[[VAL_59:.*]] = vector.insertelement %[[VAL_60:.*]]#2, %[[VAL_4]]{{\[}}%[[VAL_6]] : index] : vector<8xf64>
// CHECK: %[[VAL_61:.*]] = scf.for %[[VAL_62:.*]] = %[[VAL_60]]#0 to %[[VAL_21]] step %[[VAL_3]] iter_args(%[[VAL_63:.*]] = %[[VAL_59]]) -> (vector<8xf64>) {
-// CHECK: %[[VAL_64:.*]] = affine.min #map2(%[[VAL_21]], %[[VAL_62]]){{\[}}%[[VAL_3]]]
+// CHECK: %[[VAL_64:.*]] = affine.min #map(%[[VAL_21]], %[[VAL_62]]){{\[}}%[[VAL_3]]]
// CHECK: %[[VAL_65:.*]] = vector.create_mask %[[VAL_64]] : vector<8xi1>
// CHECK: %[[VAL_66:.*]] = vector.maskedload %[[VAL_10]]{{\[}}%[[VAL_62]]], %[[VAL_65]], %[[VAL_4]] : memref<?xf64>, vector<8xi1>, vector<8xf64> into vector<8xf64>
// CHECK: %[[VAL_67:.*]] = arith.addf %[[VAL_63]], %[[VAL_66]] : vector<8xf64>
@@ -92,7 +92,7 @@
// CHECK: scf.yield %[[VAL_68]] : vector<8xf64>
// CHECK: } {"Emitted from" = "linalg.generic"}
// CHECK: %[[VAL_69:.*]] = scf.for %[[VAL_70:.*]] = %[[VAL_60]]#1 to %[[VAL_23]] step %[[VAL_3]] iter_args(%[[VAL_71:.*]] = %[[VAL_61]]) -> (vector<8xf64>) {
-// CHECK: %[[VAL_73:.*]] = affine.min #map2(%[[VAL_23]], %[[VAL_70]]){{\[}}%[[VAL_3]]]
+// CHECK: %[[VAL_73:.*]] = affine.min #map(%[[VAL_23]], %[[VAL_70]]){{\[}}%[[VAL_3]]]
// CHECK: %[[VAL_74:.*]] = vector.create_mask %[[VAL_73]] : vector<8xi1>
// CHECK: %[[VAL_75:.*]] = vector.maskedload %[[VAL_13]]{{\[}}%[[VAL_70]]], %[[VAL_74]], %[[VAL_4]] : memref<?xf64>, vector<8xi1>, vector<8xf64> into vector<8xf64>
// CHECK: %[[VAL_76:.*]] = arith.addf %[[VAL_71]], %[[VAL_75]] : vector<8xf64>
diff --git a/mlir/test/Dialect/SparseTensor/sparse_vector_index.mlir b/mlir/test/Dialect/SparseTensor/sparse_vector_index.mlir
index 37d5b8049f809..7bb8254e04856 100644
--- a/mlir/test/Dialect/SparseTensor/sparse_vector_index.mlir
+++ b/mlir/test/Dialect/SparseTensor/sparse_vector_index.mlir
@@ -33,7 +33,7 @@
// CHECK: %[[VAL_12:.*]] = memref.load %[[VAL_8]]{{\[}}%[[VAL_5]]] : memref<?xindex>
// CHECK: %[[VAL_13:.*]] = memref.load %[[VAL_8]]{{\[}}%[[VAL_6]]] : memref<?xindex>
// CHECK: scf.for %[[VAL_14:.*]] = %[[VAL_12]] to %[[VAL_13]] step %[[VAL_1]] {
-// CHECK: %[[VAL_15:.*]] = affine.min #map1(%[[VAL_13]], %[[VAL_14]]){{\[}}%[[VAL_1]]]
+// CHECK: %[[VAL_15:.*]] = affine.min #map(%[[VAL_13]], %[[VAL_14]]){{\[}}%[[VAL_1]]]
// CHECK: %[[VAL_16:.*]] = vector.create_mask %[[VAL_15]] : vector<8xi1>
// CHECK: %[[VAL_17:.*]] = vector.maskedload %[[VAL_9]]{{\[}}%[[VAL_14]]], %[[VAL_16]], %[[VAL_3]] : memref<?xindex>, vector<8xi1>, vector<8xindex> into vector<8xindex>
// CHECK: %[[VAL_18:.*]] = vector.maskedload %[[VAL_10]]{{\[}}%[[VAL_14]]], %[[VAL_16]], %[[VAL_2]] : memref<?xi64>, vector<8xi1>, vector<8xi64> into vector<8xi64>
@@ -99,7 +99,7 @@ func.func @sparse_index_1d_conj(%arga: tensor<8xi64, #SparseVector>) -> tensor<8
// CHECK: scf.yield %[[VAL_27]], %[[VAL_28]] : index, index
// CHECK: } attributes {"Emitted from" = "linalg.generic"}
// CHECK: scf.for %[[VAL_29:.*]] = %[[VAL_30:.*]]#1 to %[[VAL_1]] step %[[VAL_1]] {
-// CHECK: %[[VAL_31:.*]] = affine.min #map1(%[[VAL_1]], %[[VAL_29]]){{\[}}%[[VAL_1]]]
+// CHECK: %[[VAL_31:.*]] = affine.min #map(%[[VAL_1]], %[[VAL_29]]){{\[}}%[[VAL_1]]]
// CHECK: %[[VAL_32:.*]] = vector.create_mask %[[VAL_31]] : vector<8xi1>
// CHECK: %[[VAL_33:.*]] = vector.broadcast %[[VAL_29]] : index to vector<8xindex>
// CHECK: %[[VAL_34:.*]] = arith.addi %[[VAL_33]], %[[VAL_2]] : vector<8xindex>
diff --git a/mlir/test/IR/pretty-locations.mlir b/mlir/test/IR/pretty-locations.mlir
index f3feb60ffe7c8..e9337b5bef37b 100644
--- a/mlir/test/IR/pretty-locations.mlir
+++ b/mlir/test/IR/pretty-locations.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt -allow-unregistered-dialect %s -mlir-print-debuginfo -mlir-pretty-debuginfo | FileCheck %s
+// RUN: mlir-opt -allow-unregistered-dialect %s -mlir-print-debuginfo -mlir-pretty-debuginfo -mlir-print-local-scope | FileCheck %s
#set0 = affine_set<(d0) : (1 == 0)>
diff --git a/mlir/test/IR/print-attr-type-aliases.mlir b/mlir/test/IR/print-attr-type-aliases.mlir
index b9893f23a879c..b1631b2ead397 100644
--- a/mlir/test/IR/print-attr-type-aliases.mlir
+++ b/mlir/test/IR/print-attr-type-aliases.mlir
@@ -29,8 +29,9 @@
// CHECK-DAG: tensor<32x!test_ui8_>
"test.op"() : () -> tensor<32x!test.int<unsigned, 8>>
-// CHECK-DAG: #loc2 = loc("nested")
-// CHECK-DAG: #loc3 = loc(fused<#loc2>["test.mlir":10:8])
+// CHECK-DAG: #loc = loc("nested")
+// CHECK-DAG: #loc1 = loc("test.mlir":10:8)
+// CHECK-DAG: #loc2 = loc(fused<#loc>[#loc1])
"test.op"() {alias_test = loc(fused<loc("nested")>["test.mlir":10:8])} : () -> ()
// -----
@@ -39,3 +40,10 @@
// CHECK: !tuple = tuple<
// CHECK: #loc1 = loc(fused<!tuple
"test.op"() {alias_test = loc(fused<tuple<i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32>>["test.mlir":10:8])} : () -> ()
+
+// -----
+
+// Check that we don't print aliases for things that aren't printed.
+// CHECK: #loc1 = loc(fused<memref<1xi32>
+// CHECK-NOT: #map
+"test.op"() {alias_test = loc(fused<memref<1xi32, affine_map<(d0) -> (d0)>>>["test.mlir":10:8])} : () -> ()
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index 415b40c3568e9..f7513d53511c8 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -1,6 +1,5 @@
; RUN: mlir-translate -import-llvm -mlir-print-debuginfo -split-input-file %s | FileCheck %s
-; CHECK: #[[$UNKNOWNLOC:.+]] = loc(unknown)
; CHECK-LABEL: @unknown(
define i32 @unknown(i32 %0) {
entry:
@@ -10,28 +9,35 @@ end:
%1 = phi i32 [ %2, %next ]
ret i32 %1
next:
- ; CHECK: = llvm.mul %{{.+}}, %{{.+}} : i32 loc(#[[$UNKNOWNLOC:.+]])
+ ; CHECK: = llvm.mul %{{.+}}, %{{.+}} : i32 loc(#[[UNKNOWNLOC:.+]])
%2 = mul i32 %0, %0
br label %end
}
-; // -----
+; CHECK: #[[UNKNOWNLOC:.+]] = loc(unknown)
-; CHECK: #[[$SP:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "instruction_loc"
-; CHECK: #[[$CALLEE:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "callee"
+; // -----
; CHECK-LABEL: @instruction_loc
define i32 @instruction_loc(i32 %arg1) {
- ; CHECK llvm.add {{.*}} loc(#[[FILE_LOC:.*]])
+ ; CHECK: llvm.add {{.*}} loc(#[[FILE_LOC:.*]])
%1 = add i32 %arg1, %arg1, !dbg !5
- ; CHECK llvm.mul {{.*}} loc(#[[CALLSITE_LOC:.*]])
+ ; CHECK: llvm.mul {{.*}} loc(#[[CALLSITE_LOC:.*]])
%2 = mul i32 %1, %1, !dbg !7
ret i32 %2
}
-; CHECK #[[FILE_LOC]] = loc(fused<#[[$SP]]>["debug-info.ll":1:2])
-; CHECK #[[CALLSITE_LOC]] = loc(fused<#[[$CALLEE]]>[callsite("debug-info.ll":7:4 at fused<#[[$SP]]>["debug-info.ll":2:2])])
+
+; CHECK-DAG: #[[RAW_FILE_LOC:.+]] = loc("debug-info.ll":1:2)
+; CHECK-DAG: #[[SP:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "instruction_loc"
+; CHECK-DAG: #[[CALLEE:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "callee"
+; CHECK-DAG: #[[FILE_LOC]] = loc(fused<#[[SP]]>[#[[RAW_FILE_LOC]]])
+; CHECK-DAG: #[[CALLEE_LOC:.+]] = loc("debug-info.ll":7:4)
+; CHECK-DAG: #[[RAW_CALLER_LOC:.+]] = loc("debug-info.ll":2:2)
+; CHECK-DAG: #[[CALLER_LOC:.+]] = loc(fused<#[[SP]]>[#[[RAW_CALLER_LOC]]])
+; CHECK-DAG: #[[RAW_CALLSITE_LOC:.+]] = loc(callsite(#[[CALLEE_LOC]] at #[[CALLER_LOC]]))
+; CHECK-DAG: #[[CALLSITE_LOC]] = loc(fused<#[[CALLEE]]>[#[[RAW_CALLSITE_LOC]]])
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -46,23 +52,22 @@ define i32 @instruction_loc(i32 %arg1) {
; // -----
-; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
-; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit =
-; CHECK: #[[$LB0:.+]] = #llvm.di_lexical_block<scope = #[[SP]]>
-; CHECK: #[[$LB1:.+]] = #llvm.di_lexical_block<scope = #[[SP]], file = #[[FILE]], line = 2, column = 2>
-
; CHECK-LABEL: @lexical_block
define i32 @lexical_block(i32 %arg1) {
- ; CHECK llvm.add {{.*}} loc(#[[LOC0:.*]])
+ ; CHECK: llvm.add {{.*}} loc(#[[LOC0:.*]])
%1 = add i32 %arg1, %arg1, !dbg !6
- ; CHECK llvm.mul {{.*}} loc(#[[LOC1:.*]])
+ ; CHECK: llvm.mul {{.*}} loc(#[[LOC1:.*]])
%2 = mul i32 %arg1, %arg1, !dbg !7
ret i32 %2
}
-; CHECK #[[LOC0]] = loc(fused<#[[$LB0]]>["debug-info.ll":1:2])
-; CHECK #[[LOC1]] = loc(fused<#[[$LB1]]>["debug-info.ll":1:2])
+; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
+; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit =
+; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block<scope = #[[SP]]>
+; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block<scope = #[[SP]], file = #[[FILE]], line = 2, column = 2>
+; CHECK: #[[LOC0]] = loc(fused<#[[LB0]]>[{{.*}}])
+; CHECK: #[[LOC1]] = loc(fused<#[[LB1]]>[{{.*}}])
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -77,23 +82,22 @@ define i32 @lexical_block(i32 %arg1) {
; // -----
-; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
-; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit =
-; CHECK: #[[$LB0:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], discriminator = 0>
-; CHECK: #[[$LB1:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], file = #[[FILE]], discriminator = 0>
-
; CHECK-LABEL: @lexical_block_file
define i32 @lexical_block_file(i32 %arg1) {
- ; CHECK llvm.add {{.*}} loc(#[[LOC0:.*]])
+ ; CHECK: llvm.add {{.*}} loc(#[[LOC0:.*]])
%1 = add i32 %arg1, %arg1, !dbg !6
- ; CHECK llvm.mul {{.*}} loc(#[[LOC1:.*]])
+ ; CHECK: llvm.mul {{.*}} loc(#[[LOC1:.*]])
%2 = mul i32 %arg1, %arg1, !dbg !7
ret i32 %2
}
-; CHECK #[[LOC0]] = loc(fused<#[[$LB0]]>["debug-info.ll":1:2]))
-; CHECK #[[LOC1]] = loc(fused<#[[$LB1]]>["debug-info.ll":2:2]))
+; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
+; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit =
+; CHECK: #[[LB0:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], discriminator = 0>
+; CHECK: #[[LB1:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], file = #[[FILE]], discriminator = 0>
+; CHECK: #[[LOC0]] = loc(fused<#[[LB0]]>[
+; CHECK: #[[LOC1]] = loc(fused<#[[LB1]]>[
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -206,13 +210,12 @@ define void @subprogram() !dbg !3 {
; // -----
-; CHECK: #[[$SP:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "func_loc", file = #{{.*}}, subprogramFlags = Definition>
-
; CHECK-LABEL: @func_loc
define void @func_loc() !dbg !3 {
ret void
}
-; CHECK: loc(fused<#[[$SP]]>["func_loc"])
+; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "func_loc", file = #{{.*}}, subprogramFlags = Definition>
+; CHECK: loc(fused<#[[SP]]>[
!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!0}
@@ -246,9 +249,9 @@ define void @intrinsic(i64 %0, ptr %1) {
ret void
}
-; CHECK: #[[LOC0]] = loc(fused<#[[$SP]]>["debug-info.ll":1:2])
-; CHECK: #[[LOC1]] = loc(fused<#[[$SP]]>["debug-info.ll":2:2])
-; CHECK: #[[LOC2]] = loc(fused<#[[$SP]]>["debug-info.ll":3:2])
+; CHECK: #[[LOC0]] = loc(fused<#[[$SP]]>[{{.*}}])
+; CHECK: #[[LOC1]] = loc(fused<#[[$SP]]>[{{.*}}])
+; CHECK: #[[LOC2]] = loc(fused<#[[$SP]]>[{{.*}}])
declare void @llvm.dbg.value(metadata, metadata, metadata)
declare void @llvm.dbg.addr(metadata, metadata, metadata)
More information about the Mlir-commits
mailing list