Avoid copies in getChecked (#147721)

Following-up on #68067 ; adding std::move to getChecked method as well.
This commit is contained in:
Alexandru Lorinti 2025-07-29 18:13:03 +03:00 committed by GitHub
parent 73245b06b3
commit 8e7b02fc0c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 44 additions and 7 deletions

View file

@ -200,7 +200,7 @@ public:
// If the construction invariants fail then we return a null attribute.
if (failed(ConcreteT::verifyInvariants(emitErrorFn, args...)))
return ConcreteT();
return UniquerT::template get<ConcreteT>(ctx, args...);
return UniquerT::template get<ConcreteT>(ctx, std::forward<Args>(args)...);
}
/// Get an instance of the concrete type from a void pointer.

View file

@ -347,6 +347,7 @@ def TestCopyCount : Test_Attr<"TestCopyCount"> {
let mnemonic = "copy_count";
let parameters = (ins TestParamCopyCount:$copy_count);
let assemblyFormat = "`<` $copy_count `>`";
let genVerifyDecl = 1;
}
def TestConditionalAliasAttr : Test_Attr<"TestConditionalAlias"> {

View file

@ -213,6 +213,16 @@ static void printTrueFalse(AsmPrinter &p, std::optional<int> result) {
p << (*result ? "true" : "false");
}
//===----------------------------------------------------------------------===//
// TestCopyCountAttr Implementation
//===----------------------------------------------------------------------===//
LogicalResult TestCopyCountAttr::verify(
llvm::function_ref<::mlir::InFlightDiagnostic()> /*emitError*/,
CopyCount /*copy_count*/) {
return success();
}
//===----------------------------------------------------------------------===//
// CopyCountAttr Implementation
//===----------------------------------------------------------------------===//

View file

@ -115,6 +115,11 @@ def B_CompoundAttrA : TestAttr<"CompoundA"> {
// DEF: return new (allocator.allocate<CompoundAAttrStorage>())
// DEF-SAME: CompoundAAttrStorage(std::move(widthOfSomething), std::move(exampleTdType), std::move(apFloat), std::move(dims), std::move(inner));
// DEF: CompoundAAttr CompoundAAttr::getChecked(
// DEF-SAME: int widthOfSomething, ::test::SimpleTypeA exampleTdType, ::llvm::APFloat apFloat, ::llvm::ArrayRef<int> dims, ::mlir::Type inner
// DEF-SAME: )
// DEF-NEXT: return Base::getChecked(emitError, context, std::move(widthOfSomething), std::move(exampleTdType), std::move(apFloat), std::move(dims), std::move(inner));
// DEF: ::mlir::Type CompoundAAttr::getInner() const {
// DEF-NEXT: return getImpl()->inner;
}

View file

@ -495,7 +495,7 @@ void DefGen::emitCheckedBuilder() {
MethodBody &body = m->body().indent();
auto scope = body.scope("return Base::getChecked(emitError, context", ");");
for (const auto &param : params)
body << ", " << param.getName();
body << ", std::move(" << param.getName() << ")";
}
static SmallVector<MethodParameter>

View file

@ -477,8 +477,9 @@ TEST(SubElementTest, Nested) {
{strAttr, trueAttr, falseAttr, boolArrayAttr, dictAttr}));
}
// Test how many times we call copy-ctor when building an attribute.
TEST(CopyCountAttr, CopyCount) {
// Test how many times we call copy-ctor when building an attribute with the
// 'get' method.
TEST(CopyCountAttr, CopyCountGet) {
MLIRContext context;
context.loadDialect<test::TestDialect>();
@ -489,15 +490,35 @@ TEST(CopyCountAttr, CopyCount) {
test::CopyCount::counter = 0;
test::TestCopyCountAttr::get(&context, std::move(copyCount));
#ifndef NDEBUG
// One verification enabled only in assert-mode requires a copy.
EXPECT_EQ(counter1, 1);
EXPECT_EQ(test::CopyCount::counter, 1);
// One verification enabled only in assert-mode requires two copies: one for
// calling 'verifyInvariants' and one for calling 'verify' inside
// 'verifyInvariants'.
EXPECT_EQ(counter1, 2);
EXPECT_EQ(test::CopyCount::counter, 2);
#else
EXPECT_EQ(counter1, 0);
EXPECT_EQ(test::CopyCount::counter, 0);
#endif
}
// Test how many times we call copy-ctor when building an attribute with the
// 'getChecked' method.
TEST(CopyCountAttr, CopyCountGetChecked) {
MLIRContext context;
context.loadDialect<test::TestDialect>();
test::CopyCount::counter = 0;
test::CopyCount copyCount("hello");
auto loc = UnknownLoc::get(&context);
test::TestCopyCountAttr::getChecked(loc, &context, std::move(copyCount));
int counter1 = test::CopyCount::counter;
test::CopyCount::counter = 0;
test::TestCopyCountAttr::getChecked(loc, &context, std::move(copyCount));
// The verifiers require two copies: one for calling 'verifyInvariants' and
// one for calling 'verify' inside 'verifyInvariants'.
EXPECT_EQ(counter1, 2);
EXPECT_EQ(test::CopyCount::counter, 2);
}
// Test stripped printing using test dialect attribute.
TEST(CopyCountAttr, PrintStripped) {
MLIRContext context;