mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 01:16:06 +00:00
[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
This commit is contained in:
parent
658a503937
commit
aef89c8b41
@ -181,7 +181,7 @@ public:
|
||||
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>
|
||||
|
@ -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);
|
||||
|
@ -389,7 +389,8 @@ protected:
|
||||
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 @@ public:
|
||||
/// 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 @@ private:
|
||||
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 @@ private:
|
||||
|
||||
/// 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 @@ private:
|
||||
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 @@ private:
|
||||
/// 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 << ')';
|
||||
}
|
||||
|
||||
|
@ -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>,
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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)>
|
||||
|
||||
|
@ -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])} : () -> ()
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user