[Mlir-commits] [mlir] a5b584d - [mlir][lsp] Add parser support for tracking alias definitions and uses
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Aug 24 19:02:51 PDT 2023
Author: Mogball
Date: 2023-08-25T02:02:46Z
New Revision: a5b584d8b4a569c38b0740f226336da2a67c3824
URL: https://github.com/llvm/llvm-project/commit/a5b584d8b4a569c38b0740f226336da2a67c3824
DIFF: https://github.com/llvm/llvm-project/commit/a5b584d8b4a569c38b0740f226336da2a67c3824.diff
LOG: [mlir][lsp] Add parser support for tracking alias definitions and uses
This adds fields to AsmParserState to track attribute and type alias
definitions and uses and teachers the parser to inform the
AsmParserState about them. This will be used to add LSP support for goto
definition and find references for aliases.
Attribute aliases are tolerant to use before def, because certain
location aliases may be deferred.
Reviewed By: rriddle
Differential Revision: https://reviews.llvm.org/D158781
Added:
Modified:
mlir/include/mlir/AsmParser/AsmParserState.h
mlir/lib/AsmParser/AsmParserState.cpp
mlir/lib/AsmParser/DialectSymbolParser.cpp
mlir/lib/AsmParser/Parser.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/AsmParser/AsmParserState.h b/mlir/include/mlir/AsmParser/AsmParserState.h
index d2e9e5428aebae..3d22e2a34b5b4a 100644
--- a/mlir/include/mlir/AsmParser/AsmParserState.h
+++ b/mlir/include/mlir/AsmParser/AsmParserState.h
@@ -12,6 +12,7 @@
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SMLoc.h"
#include <cstddef>
@@ -94,6 +95,32 @@ class AsmParserState {
SmallVector<SMDefinition> arguments;
};
+ /// This class represents the information for an attribute alias definition
+ /// within the input file.
+ struct AttributeAliasDefinition {
+ AttributeAliasDefinition(StringRef name, SMRange loc = {})
+ : name(name), definition(loc) {}
+
+ /// The name of the attribute alias.
+ StringRef name;
+
+ /// The source location for the alias.
+ SMDefinition definition;
+ };
+
+ /// This class represents the information for type definition within the input
+ /// file.
+ struct TypeAliasDefinition {
+ TypeAliasDefinition(StringRef name, SMRange loc)
+ : name(name), definition(loc) {}
+
+ /// The name of the attribute alias.
+ StringRef name;
+
+ /// The source location for the alias.
+ SMDefinition definition;
+ };
+
AsmParserState();
~AsmParserState();
AsmParserState &operator=(AsmParserState &&other);
@@ -154,10 +181,14 @@ class AsmParserState {
/// Add a definition of the given entity.
void addDefinition(Block *block, SMLoc location);
void addDefinition(BlockArgument blockArg, SMLoc location);
+ void addAttrAliasDefinition(StringRef name, SMRange location);
+ void addTypeAliasDefinition(StringRef name, SMRange location);
/// Add a source uses of the given value.
void addUses(Value value, ArrayRef<SMLoc> locations);
void addUses(Block *block, ArrayRef<SMLoc> locations);
+ void addAttrAliasUses(StringRef name, SMRange locations);
+ void addTypeAliasUses(StringRef name, SMRange locations);
/// Add source uses for all the references nested under `refAttr`. The
/// provided `locations` should match 1-1 with the number of references in
diff --git a/mlir/lib/AsmParser/AsmParserState.cpp b/mlir/lib/AsmParser/AsmParserState.cpp
index e61aba5a7fe7cc..38f427f97ab0e5 100644
--- a/mlir/lib/AsmParser/AsmParserState.cpp
+++ b/mlir/lib/AsmParser/AsmParserState.cpp
@@ -47,6 +47,12 @@ struct AsmParserState::Impl {
SmallVector<std::unique_ptr<BlockDefinition>> blocks;
DenseMap<Block *, unsigned> blocksToIdx;
+ /// A mapping from aliases in the input source file to their parser state.
+ SmallVector<std::unique_ptr<AttributeAliasDefinition>> attrAliases;
+ SmallVector<std::unique_ptr<TypeAliasDefinition>> typeAliases;
+ llvm::StringMap<unsigned> attrAliasToIdx;
+ llvm::StringMap<unsigned> typeAliasToIdx;
+
/// A set of value definitions that are placeholders for forward references.
/// This map should be empty if the parser finishes successfully.
DenseMap<Value, SmallVector<SMLoc>> placeholderValueUses;
@@ -271,6 +277,26 @@ void AsmParserState::addDefinition(BlockArgument blockArg, SMLoc location) {
def.arguments[argIdx] = SMDefinition(convertIdLocToRange(location));
}
+void AsmParserState::addAttrAliasDefinition(StringRef name, SMRange location) {
+ auto [it, inserted] =
+ impl->attrAliasToIdx.try_emplace(name, impl->attrAliases.size());
+ // Location aliases may be referenced before they are defined.
+ if (inserted) {
+ impl->attrAliases.push_back(
+ std::make_unique<AttributeAliasDefinition>(name, location));
+ } else {
+ impl->attrAliases[it->second]->definition.loc = location;
+ }
+}
+
+void AsmParserState::addTypeAliasDefinition(StringRef name, SMRange location) {
+ auto [it, inserted] =
+ impl->typeAliasToIdx.try_emplace(name, impl->typeAliases.size());
+ assert(inserted && "unexpected attribute alias redefinition");
+ impl->typeAliases.push_back(
+ std::make_unique<TypeAliasDefinition>(name, location));
+}
+
void AsmParserState::addUses(Value value, ArrayRef<SMLoc> locations) {
// Handle the case where the value is an operation result.
if (OpResult result = dyn_cast<OpResult>(value)) {
@@ -335,6 +361,27 @@ void AsmParserState::addUses(SymbolRefAttr refAttr,
locations.end());
}
+void AsmParserState::addAttrAliasUses(StringRef name, SMRange location) {
+ auto it = impl->attrAliasToIdx.find(name);
+ // Location aliases may be referenced before they are defined.
+ if (it == impl->attrAliasToIdx.end()) {
+ it = impl->attrAliasToIdx.try_emplace(name, impl->attrAliases.size()).first;
+ impl->attrAliases.push_back(
+ std::make_unique<AttributeAliasDefinition>(name));
+ }
+ AttributeAliasDefinition &def = *impl->attrAliases[it->second];
+ def.definition.uses.push_back(location);
+}
+
+void AsmParserState::addTypeAliasUses(StringRef name, SMRange location) {
+ auto it = impl->typeAliasToIdx.find(name);
+ // Location aliases may be referenced before they are defined.
+ assert(it != impl->typeAliasToIdx.end() &&
+ "expected valid type alias definition");
+ TypeAliasDefinition &def = *impl->typeAliases[it->second];
+ def.definition.uses.push_back(location);
+}
+
void AsmParserState::refineDefinition(Value oldValue, Value newValue) {
auto it = impl->placeholderValueUses.find(oldValue);
assert(it != impl->placeholderValueUses.end() &&
diff --git a/mlir/lib/AsmParser/DialectSymbolParser.cpp b/mlir/lib/AsmParser/DialectSymbolParser.cpp
index 27981451502d22..2b1b114b90e86a 100644
--- a/mlir/lib/AsmParser/DialectSymbolParser.cpp
+++ b/mlir/lib/AsmParser/DialectSymbolParser.cpp
@@ -157,7 +157,8 @@ ParseResult Parser::parseDialectSymbolBody(StringRef &body,
/// Parse an extended dialect symbol.
template <typename Symbol, typename SymbolAliasMap, typename CreateFn>
-static Symbol parseExtendedSymbol(Parser &p, SymbolAliasMap &aliases,
+static Symbol parseExtendedSymbol(Parser &p, AsmParserState *asmState,
+ SymbolAliasMap &aliases,
CreateFn &&createSymbol) {
Token tok = p.getToken();
@@ -167,6 +168,7 @@ static Symbol parseExtendedSymbol(Parser &p, SymbolAliasMap &aliases,
return p.codeCompleteDialectSymbol(aliases);
// Parse the dialect namespace.
+ SMRange range = p.getToken().getLocRange();
SMLoc loc = p.getToken().getLoc();
p.consumeToken();
@@ -189,6 +191,12 @@ static Symbol parseExtendedSymbol(Parser &p, SymbolAliasMap &aliases,
return (p.emitWrongTokenError("undefined symbol alias id '" + identifier +
"'"),
nullptr);
+ if (asmState) {
+ if constexpr (std::is_same_v<Symbol, Type>)
+ asmState->addTypeAliasUses(identifier, range);
+ else
+ asmState->addAttrAliasUses(identifier, range);
+ }
return aliasIt->second;
}
@@ -232,7 +240,7 @@ static Symbol parseExtendedSymbol(Parser &p, SymbolAliasMap &aliases,
Attribute Parser::parseExtendedAttr(Type type) {
MLIRContext *ctx = getContext();
Attribute attr = parseExtendedSymbol<Attribute>(
- *this, state.symbols.attributeAliasDefinitions,
+ *this, state.asmState, state.symbols.attributeAliasDefinitions,
[&](StringRef dialectName, StringRef symbolData, SMLoc loc) -> Attribute {
// Parse an optional trailing colon type.
Type attrType = type;
@@ -279,7 +287,7 @@ Attribute Parser::parseExtendedAttr(Type type) {
Type Parser::parseExtendedType() {
MLIRContext *ctx = getContext();
return parseExtendedSymbol<Type>(
- *this, state.symbols.typeAliasDefinitions,
+ *this, state.asmState, state.symbols.typeAliasDefinitions,
[&](StringRef dialectName, StringRef symbolData, SMLoc loc) -> Type {
// If we found a registered dialect, then ask it to parse the type.
if (auto *dialect = ctx->getOrLoadDialect(dialectName)) {
diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp
index 3b562e013ccbbb..6b075c05c4d529 100644
--- a/mlir/lib/AsmParser/Parser.cpp
+++ b/mlir/lib/AsmParser/Parser.cpp
@@ -2020,6 +2020,8 @@ ParseResult OperationParser::parseLocationAlias(LocationAttr &loc) {
<< "expected location, but found dialect attribute: '#" << identifier
<< "'";
}
+ if (state.asmState)
+ state.asmState->addAttrAliasUses(identifier, tok.getLocRange());
// If this alias can be resolved, do it now.
Attribute attr = state.symbols.attributeAliasDefinitions.lookup(identifier);
@@ -2527,6 +2529,7 @@ ParseResult TopLevelOperationParser::parseAttributeAliasDef() {
return emitError("attribute names with a '.' are reserved for "
"dialect-defined names");
+ SMRange location = getToken().getLocRange();
consumeToken(Token::hash_identifier);
// Parse the '='.
@@ -2538,6 +2541,9 @@ ParseResult TopLevelOperationParser::parseAttributeAliasDef() {
if (!attr)
return failure();
+ // Register this alias with the parser state.
+ if (state.asmState)
+ state.asmState->addAttrAliasDefinition(aliasName, location);
state.symbols.attributeAliasDefinitions[aliasName] = attr;
return success();
}
@@ -2554,6 +2560,8 @@ ParseResult TopLevelOperationParser::parseTypeAliasDef() {
if (aliasName.contains('.'))
return emitError("type names with a '.' are reserved for "
"dialect-defined names");
+
+ SMRange location = getToken().getLocRange();
consumeToken(Token::exclamation_identifier);
// Parse the '='.
@@ -2566,6 +2574,8 @@ ParseResult TopLevelOperationParser::parseTypeAliasDef() {
return failure();
// Register this alias with the parser state.
+ if (state.asmState)
+ state.asmState->addTypeAliasDefinition(aliasName, location);
state.symbols.typeAliasDefinitions.try_emplace(aliasName, aliasedType);
return success();
}
More information about the Mlir-commits
mailing list