-
Notifications
You must be signed in to change notification settings - Fork 156
[CIR][CodeGen] Introduce CIR CXXSpecialMember attribute #1711
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding more of the building blocks here. In the future it'd be nice to have a representation for struct/class more closer to C++ and it will probably be easier to extract this type of information, but to prevent over engineering early, it feels right to incrementally add pieces that can enable us to better analyze C++ code and make transformations easier to write.
Can you look into changing LifetimeChecker.cpp to use this attribute instead of the current AST approach?
(@andykaylor @erichkeane @dkolsen-pgi in case you have any extra thoughts here) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also want to set this attribute on cir.func definitions/declarations?
68ff6ef
to
8c7235c
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
A few updates:
|
77c8851
to
d4c51f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 comment, else seems reasonable, I'm happy when the others are.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update, one more round of suggestions
ab65415
to
c1f8a62
Compare
c1f8a62
to
f6aaa4d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates, one more round!
The `default` kind is used if the constructor is a default constructor. | ||
The `copy` kind is used if the constructor is a copy constructor. | ||
}]; | ||
let parameters = (ins "mlir::Type":$type, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need type
here?
If we want to tag that this is member function from specific class it might make more sense to be more generic and have attribute MemberFunctionOf
that is not just tied to ctors/dtor.
Consequently these ctor/dtor attributes will be just enum attribute and unit attribute respectively.
@bcardosolopes what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need type here?
The idea is to have the type around for grabbing any extra information we might need about the class (versus making assumptions on the type of the function this
/first param). We don't have a use case for it just yet tho! That's usually a somewhat blocker for me, but I'm fine with keeping this one around.
If we want to tag that this is member function from specific class it might make more sense to be more generic and have attribute MemberFunctionOf that is not just tied to ctors/dtor.
That's the idea moving forward, but starting off with ctor/dtor and go incrementally.
what do you think?
I like the idea of a member_function_of<type, ctor<copy>>
.
@@ -2798,6 +2813,15 @@ void cir::FuncOp::print(OpAsmPrinter &p) { | |||
p.printAttribute(annotations); | |||
} | |||
|
|||
if (getCxxSpecialMember()) { | |||
p << " cxx_special_member<"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to wrap it in cxx_special_member
? It is apparent from cir.cxx_ctor/dtor
that this is the special member function.
a5f2b05
to
c40a840
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience, more comments!
The `default` kind is used if the constructor is a default constructor. | ||
The `copy` kind is used if the constructor is a copy constructor. | ||
}]; | ||
let parameters = (ins "mlir::Type":$type, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need type here?
The idea is to have the type around for grabbing any extra information we might need about the class (versus making assumptions on the type of the function this
/first param). We don't have a use case for it just yet tho! That's usually a somewhat blocker for me, but I'm fine with keeping this one around.
If we want to tag that this is member function from specific class it might make more sense to be more generic and have attribute MemberFunctionOf that is not just tied to ctors/dtor.
That's the idea moving forward, but starting off with ctor/dtor and go incrementally.
what do you think?
I like the idea of a member_function_of<type, ctor<copy>>
.
@@ -2618,6 +2620,37 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) { | |||
state.addAttribute(annotationsNameAttr, annotations); | |||
} | |||
|
|||
// Parse CXXSpecialMember attribute | |||
if (mlir::succeeded(parser.parseOptionalKeyword("cxx_ctor"))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still sounds simple enough that we shouldn't need these to be hand written, what specific problems are you hitting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can update this once the syntax of the attribute is approved. I am also happy with member_function_of<type, ctor<copy>>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I'll defer this to @xlauko cause I'm going to be out until next week. One important part here is not to have a custom parser/printer because this is simple enough that it doesn't need one (see more examples in the LLVM dialect for inspiration).
// CIR-NEXT: cir.func private @_ZN1EntEv(!cir.ptr<!rec_E>) -> !rec_E | ||
// CIR-NEXT: cir.func private @_ZN1ED1Ev(!cir.ptr<!rec_E>) extra(#fn_attr) | ||
// CIR-NEXT: cir.func private @_ZN1ED1Ev(!cir.ptr<!rec_E>) cxx_dtor<!rec_E> extra(#fn_attr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like we could also drop "cxx": dtor<!rec_E>
is probably good enough? No need to change this right now, let's converge on the syntax first (see other comment).
I think this one is self-explanatory, so I will not write much 🙂
Adding this attribute helps in optimizations like #1653, and using the attribute it's easy to create operations like
cir.std.vector.ctor
/cir.std.vector.dtor
by just modifyingIdiomRecognizer
a bit. I believe it will also be useful for future optimizations. Finally, I updated quite a number of tests so they now reflect this attribute.Please, let me know if you see any issues.