This is an archive of the discontinued LLVM Phabricator instance.

[mlir][NFC] Make InsertionGuard properly move constructible
ClosedPublic

Authored by zero9178 on Oct 28 2021, 12:44 PM.

Details

Summary

InsertionGuards move constructor is currently the compiler synthesized implementation which is very bug prone. A move constructed InsertionGuard will get the same builder and insertion point as the one it is constructed from, leading to insertion point being restored twice. This can even happen in non obvious situations on some compilers, such as when returning a move constructible struct from a function (https://godbolt.org/z/4j7M98Khq notice the call to ~Test twice, once in test(), the other in main).

This patch fixes the issue by properly implementing the move constructor. An InsertionGuard that was used to move construct another InsertionGuard is simply inactive and will not restore the insertion point.

I chose to explicitly delete the move assign operator as its semantics are not clear cut. If one were to strictly follow the rule of 5, you'd have to restore the insertion point before then taking ownership of the others guards fields. I believe this to rather confusing/and or surprising however. One may still get such semantics using llvm::Optional or std::optional and the emplace method if you really want it.

Diff Detail

Event Timeline

zero9178 created this revision.Oct 28 2021, 12:44 PM
zero9178 requested review of this revision.Oct 28 2021, 12:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 28 2021, 12:44 PM
lattner accepted this revision.Oct 28 2021, 2:59 PM

Makes sense to me. Is there a reason that we need any move ctor? Why not just disable it?

This revision is now accepted and ready to land.Oct 28 2021, 2:59 PM

Makes sense to me. Is there a reason that we need any move ctor? Why not just disable it?

Yeah, it what situation are you moving the guard?

Makes sense to me. Is there a reason that we need any move ctor? Why not just disable it?

Without a move constructor one is unable to return an insertion guard from a function and generally makes it harder to compose inside of other classes including things like Optional. None of those things were previously impossible to be fair, but needlessly cumbersome having to always do inplace construction or wrapping the guard in a uniue_ptr.

Huh ok, that makes sense to me. Composition-ality is good.

LG

mlir/include/mlir/IR/Builders.h
297

Can you document it? Something like:

/// Implement the move constructor so that the builder is cleared from `other`
/// to avoid restoring the insertion point at the time of the move.
zero9178 marked an inline comment as done.Oct 28 2021, 11:57 PM
zero9178 added inline comments.
mlir/include/mlir/IR/Builders.h
297

Addressed in the final commit