-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[clang-tidy] Add MLIR check for old op builder usage. #149148
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
Changes from 6 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
b404f53
[clang-tidy] Add MLIR check for old op builder usage.
jpienaar 34b2a3a
Move into LLVM module as this seems better spot given lack of other p…
jpienaar dc85637
Fix formatting
jpienaar a74232f
Address review comments
jpienaar 4fe574a
Address missed review comments
jpienaar a25b8af
Fix wrong type
jpienaar 9a86c0f
Address clang-tidy warnings except in mlir_op_builder.cpp which is fo…
jpienaar 46ca80b
Update clang-tools-extra/clang-tidy/llvm/MLIROpBuilderCheck.cpp
jpienaar 01f5fbb
Renamings & extra tests
jpienaar 4d104f4
Update clang-tools-extra/docs/clang-tidy/checks/llvm/use-new-mlir-op-…
jpienaar e4f78d0
Switch to EditGenerator so that macros are at least warned about
jpienaar 9e3f973
Use formatv to make easier to see concat
jpienaar 30609a3
Merge branch 'main' into clangtidy-mlir
jpienaar de7c822
Update clang-tools-extra/clang-tidy/llvm/MLIROpBuilderCheck.cpp
jpienaar cd50bdb
Update to UseNewMLIROpBuilderCheck more uniformly
jpienaar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
clang-tools-extra/clang-tidy/llvm/MLIROpBuilderCheck.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
//===--- MLIROpBuilderCheck.cpp - clang-tidy ------------------------------===// | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "MLIROpBuilderCheck.h" | ||
#include "clang/ASTMatchers/ASTMatchers.h" | ||
#include "clang/Basic/LLVM.h" | ||
#include "clang/Lex/Lexer.h" | ||
#include "clang/Tooling/Transformer/RangeSelector.h" | ||
#include "clang/Tooling/Transformer/RewriteRule.h" | ||
#include "clang/Tooling/Transformer/SourceCode.h" | ||
#include "clang/Tooling/Transformer/Stencil.h" | ||
#include "llvm/Support/Error.h" | ||
|
||
namespace clang::tidy::llvm_check { | ||
namespace { | ||
|
||
using namespace ::clang::ast_matchers; // NOLINT: Too many names. | ||
using namespace ::clang::transformer; // NOLINT: Too many names. | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
class TypeAsWrittenStencil : public StencilInterface { | ||
public: | ||
explicit TypeAsWrittenStencil(std::string S) : id(std::move(S)) {} | ||
std::string toString() const override { | ||
return (llvm::Twine("TypeAsWritten(\"") + id + "\")").str(); | ||
} | ||
|
||
llvm::Error eval(const MatchFinder::MatchResult &match, | ||
std::string *result) const override { | ||
llvm::Expected<CharSourceRange> n = node(id)(match); | ||
if (!n) | ||
return n.takeError(); | ||
SourceRange srcRange = n->getAsRange(); | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (srcRange.isInvalid()) { | ||
return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument, | ||
"srcRange is invalid"); | ||
} | ||
const CharSourceRange range = n->getTokenRange(srcRange); | ||
auto nextToken = [&](std::optional<Token> token) { | ||
if (!token) | ||
return token; | ||
return clang::Lexer::findNextToken(token->getLocation(), | ||
*match.SourceManager, | ||
match.Context->getLangOpts()); | ||
}; | ||
std::optional<Token> lessToken = clang::Lexer::findNextToken( | ||
range.getBegin(), *match.SourceManager, match.Context->getLangOpts()); | ||
while (lessToken && lessToken->getKind() != clang::tok::less) { | ||
lessToken = nextToken(lessToken); | ||
} | ||
if (!lessToken) { | ||
return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument, | ||
"missing '<' token"); | ||
} | ||
std::optional<Token> endToken = nextToken(lessToken); | ||
for (std::optional<Token> greaterToken = nextToken(endToken); | ||
greaterToken && greaterToken->getKind() != clang::tok::greater; | ||
greaterToken = nextToken(greaterToken)) { | ||
endToken = greaterToken; | ||
} | ||
if (!endToken) { | ||
return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument, | ||
"missing '>' token"); | ||
} | ||
*result += clang::tooling::getText( | ||
CharSourceRange::getTokenRange(lessToken->getEndLoc(), | ||
endToken->getLastLoc()), | ||
*match.Context); | ||
return llvm::Error::success(); | ||
} | ||
std::string id; | ||
}; | ||
|
||
Stencil typeAsWritten(StringRef Id) { | ||
// Using this instead of `describe` so that we get the exact same spelling. | ||
return std::make_shared<TypeAsWrittenStencil>(std::string(Id)); | ||
} | ||
|
||
RewriteRuleWith<std::string> MlirOpBuilderCheckRule() { | ||
return makeRule( | ||
cxxMemberCallExpr( | ||
on(expr(hasType( | ||
cxxRecordDecl(isSameOrDerivedFrom("::mlir::OpBuilder")))) | ||
.bind("builder")), | ||
callee(cxxMethodDecl(hasTemplateArgument(0, templateArgument()))), | ||
callee(cxxMethodDecl(hasName("create")))) | ||
.bind("call"), | ||
changeTo(cat(typeAsWritten("call"), "::create(", node("builder"), ", ", | ||
callArgs("call"), ")")), | ||
cat("Use OpType::create(builder, ...) instead of " | ||
"builder.create<OpType>(...)")); | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} // namespace | ||
|
||
MlirOpBuilderCheck::MlirOpBuilderCheck(StringRef Name, | ||
ClangTidyContext *Context) | ||
: TransformerClangTidyCheck(MlirOpBuilderCheckRule(), Name, Context) {} | ||
|
||
} // namespace clang::tidy::llvm_check |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//===--- MLIROpBuilderCheck.h - clang-tidy ----------------------*- 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_MLIROPBUILDERCHECK_H | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_MLIROPBUILDERCHECK_H | ||
|
||
#include "../utils/TransformerClangTidyCheck.h" | ||
|
||
namespace clang::tidy::llvm_check { | ||
|
||
/// Checks for uses of MLIR's `OpBuilder::create<T>` and suggests using | ||
/// `T::create` instead. | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
class MlirOpBuilderCheck : public utils::TransformerClangTidyCheck { | ||
public: | ||
MlirOpBuilderCheck(StringRef Name, ClangTidyContext *Context); | ||
|
||
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { | ||
return getLangOpts().CPlusPlus; | ||
} | ||
}; | ||
|
||
} // namespace clang::tidy::llvm_check | ||
|
||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_MLIROPBUILDERCHECK_H |
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
clang-tools-extra/docs/clang-tidy/checks/llvm/mlir-op-builder.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.. title:: clang-tidy - llvm-mlir-op-builder | ||
|
||
llvm-mlir-op-builder | ||
==================== | ||
|
||
Flags usage of old form of invoking create on MLIR's ``OpBuilder`` and suggests | ||
new form. | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Example | ||
------- | ||
|
||
.. code-block:: c++ | ||
|
||
builder.create<FooOp>(builder.getUnknownLoc(), "baz"); | ||
|
||
|
||
Transforms to: | ||
|
||
.. code-block:: c++ | ||
|
||
FooOp::create(builder, builder.getUnknownLoc(), "baz"); |
51 changes: 51 additions & 0 deletions
51
clang-tools-extra/test/clang-tidy/checkers/llvm/mlir_op_builder.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// RUN: %check_clang_tidy --match-partial-fixes %s llvm-mlir-op-builder %t | ||
|
||
namespace mlir { | ||
class Location {}; | ||
class OpBuilder { | ||
public: | ||
template <typename OpTy, typename... Args> | ||
OpTy create(Location location, Args &&...args) { | ||
return OpTy(args...); | ||
} | ||
Location getUnknownLoc() { return Location(); } | ||
}; | ||
class ImplicitLocOpBuilder : public OpBuilder { | ||
public: | ||
template <typename OpTy, typename... Args> | ||
OpTy create(Args &&...args) { | ||
return OpTy(args...); | ||
} | ||
}; | ||
struct ModuleOp { | ||
ModuleOp() {} | ||
static ModuleOp create(OpBuilder &builder, Location location) { | ||
return ModuleOp(); | ||
} | ||
}; | ||
struct NamedOp { | ||
NamedOp(const char* name) {} | ||
static NamedOp create(OpBuilder &builder, Location location, const char* name) { | ||
return NamedOp(name); | ||
} | ||
}; | ||
} // namespace mlir | ||
|
||
void f() { | ||
jpienaar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
mlir::OpBuilder builder; | ||
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: Use OpType::create(builder, ...) instead of builder.create<OpType>(...) [llvm-mlir-op-builder] | ||
// CHECK-FIXES: mlir:: ModuleOp::create(builder, builder.getUnknownLoc()) | ||
builder.create<mlir:: ModuleOp>(builder.getUnknownLoc()); | ||
|
||
using mlir::NamedOp; | ||
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: Use OpType::create(builder, ...) instead of builder.create<OpType>(...) [llvm-mlir-op-builder] | ||
// CHECK-FIXES: NamedOp::create(builder, builder.getUnknownLoc(), "baz") | ||
builder.create<NamedOp>(builder.getUnknownLoc(), "baz"); | ||
|
||
mlir::ImplicitLocOpBuilder ib; | ||
// Note: extra space in the case where there is no other arguments. Could be | ||
// improved, but also clang-format will do that just post. | ||
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: Use OpType::create(builder, ...) instead of builder.create<OpType>(...) [llvm-mlir-op-builder] | ||
// CHECK-FIXES: mlir::ModuleOp::create(ib ) | ||
ib.create<mlir::ModuleOp>(); | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.