Skip to content

[mlir] Do not set lastToken in AsmParser's resetToken function and add a unit test for AsmParsers's locations #105529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions mlir/lib/AsmParser/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,14 @@ class Parser {
consumeToken();
}

/// Reset the parser to the given lexer position.
/// Reset the parser to the given lexer position. Resetting the parser/lexer
/// position does not update 'state.lastToken'. 'state.lastToken' is the
/// last parsed token, and is used to provide the scope end location for
/// OperationDefinitions. To ensure the correctness of the end location, the
/// last consumed token of an OperationDefinition needs to be the last token
/// belonging to it.
void resetToken(const char *tokPos) {
state.lex.resetPointer(tokPos);
state.lastToken = state.curToken;
state.curToken = state.lex.lexToken();
}

Expand Down
2 changes: 2 additions & 0 deletions mlir/unittests/Parser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ add_mlir_unittest(MLIRParserTests
target_include_directories(MLIRParserTests PRIVATE "${MLIR_BINARY_DIR}/test/lib/Dialect/Test")

target_link_libraries(MLIRParserTests PRIVATE
MLIRFuncDialect
MLIRLLVMDialect
MLIRIR
MLIRParser
MLIRTestDialect
Expand Down
81 changes: 81 additions & 0 deletions mlir/unittests/Parser/ParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@

#include "mlir/Parser/Parser.h"
#include "mlir/AsmParser/AsmParser.h"
#include "mlir/AsmParser/AsmParserState.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Verifier.h"
#include "llvm/Support/SourceMgr.h"

#include "gmock/gmock.h"

Expand Down Expand Up @@ -101,4 +105,81 @@ TEST(MLIRParser, ParseAttr) {
EXPECT_EQ(attr, b.getI64IntegerAttr(9));
}
}

TEST(MLIRParser, AsmParserLocations) {
std::string moduleStr = R"mlir(
func.func @foo() -> !llvm.array<2 x f32> {
%0 = llvm.mlir.undef : !llvm.array<2 x f32>
func.return %0 : !llvm.array<2 x f32>
}
)mlir";

DialectRegistry registry;
registry.insert<func::FuncDialect, LLVM::LLVMDialect>();
MLIRContext context(registry);

auto memBuffer =
llvm::MemoryBuffer::getMemBuffer(moduleStr, "AsmParserTest.mlir",
/*RequiresNullTerminator=*/false);
ASSERT_TRUE(memBuffer);

llvm::SourceMgr sourceMgr;
sourceMgr.AddNewSourceBuffer(std::move(memBuffer), llvm::SMLoc());

Block block;
AsmParserState parseState;
const LogicalResult parseResult =
parseAsmSourceFile(sourceMgr, &block, &context, &parseState);
ASSERT_TRUE(parseResult.succeeded());

auto funcOp = *block.getOps<func::FuncOp>().begin();
const AsmParserState::OperationDefinition *funcOpDefinition =
parseState.getOpDef(funcOp);
ASSERT_TRUE(funcOpDefinition);

const std::pair expectedStartFunc{2u, 1u};
const std::pair expectedEndFunc{2u, 10u};
const std::pair expectedScopeEndFunc{5u, 2u};
ASSERT_EQ(sourceMgr.getLineAndColumn(funcOpDefinition->loc.Start),
expectedStartFunc);
ASSERT_EQ(sourceMgr.getLineAndColumn(funcOpDefinition->loc.End),
expectedEndFunc);
ASSERT_EQ(funcOpDefinition->loc.Start, funcOpDefinition->scopeLoc.Start);
ASSERT_EQ(sourceMgr.getLineAndColumn(funcOpDefinition->scopeLoc.End),
expectedScopeEndFunc);

auto llvmUndef = *funcOp.getOps<LLVM::UndefOp>().begin();
const AsmParserState::OperationDefinition *llvmUndefDefinition =
parseState.getOpDef(llvmUndef);
ASSERT_TRUE(llvmUndefDefinition);

const std::pair expectedStartUndef{3u, 8u};
const std::pair expectedEndUndef{3u, 23u};
const std::pair expectedScopeEndUndef{3u, 46u};
ASSERT_EQ(sourceMgr.getLineAndColumn(llvmUndefDefinition->loc.Start),
expectedStartUndef);
ASSERT_EQ(sourceMgr.getLineAndColumn(llvmUndefDefinition->loc.End),
expectedEndUndef);
ASSERT_EQ(llvmUndefDefinition->loc.Start,
llvmUndefDefinition->scopeLoc.Start);
ASSERT_EQ(sourceMgr.getLineAndColumn(llvmUndefDefinition->scopeLoc.End),
expectedScopeEndUndef);

auto funcReturn = *funcOp.getOps<func::ReturnOp>().begin();
const AsmParserState::OperationDefinition *funcReturnDefinition =
parseState.getOpDef(funcReturn);
ASSERT_TRUE(funcReturnDefinition);

const std::pair expectedStartReturn{4u, 3u};
const std::pair expectedEndReturn{4u, 14u};
const std::pair expectedScopeEndReturn{4u, 40u};
ASSERT_EQ(sourceMgr.getLineAndColumn(funcReturnDefinition->loc.Start),
expectedStartReturn);
ASSERT_EQ(sourceMgr.getLineAndColumn(funcReturnDefinition->loc.End),
expectedEndReturn);
ASSERT_EQ(funcReturnDefinition->loc.Start,
funcReturnDefinition->scopeLoc.Start);
ASSERT_EQ(sourceMgr.getLineAndColumn(funcReturnDefinition->scopeLoc.End),
expectedScopeEndReturn);
}
} // namespace
Loading