Skip to content
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

[CIR][CIRGen] Support a defined pure virtual destructor #825

Merged
merged 1 commit into from
Sep 11, 2024

Conversation

smeenai
Copy link
Collaborator

@smeenai smeenai commented Sep 6, 2024

This is permitted by the language, and IRGen emits traps for destructors
other than the base object destructor. Make CIRGen follow suit.

@@ -1109,7 +1109,17 @@ void CIRGenFunction::buildDestructorBody(FunctionArgList &Args) {
// in fact emit references to them from other compilations, so emit them
// as functions containing a trap instruction.
if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) {
llvm_unreachable("NYI");
builder.create<mlir::cir::TrapOp>(getLoc(Dtor->getLocation()));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the best location to use, but I'm also not sure if it matters very much.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Dtor->getBody() is available, getting the loc of that stmt would be the best effort.

Comment on lines 1113 to 1120
// cir.trap is a terminator. The corresponding IRGen code does this:
// builder.clearInsertionPoint();
// However, CIRGenFunction::generateCode performs the following check, which
// fails if we do the same thing here:
// assert(builder.getInsertionBlock() && "Should be valid");
// IRGen has no equivalent assert, but for now we create a block to have a
// valid insertion point.
// TODO(cir): Should the CIRGenFunction::generateCode assert be relaxed?
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd appreciate advice on this.

Copy link
Member

@Lancern Lancern Sep 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MLIR builder asserts the insertion point to be valid when inserting operations while LLVMIR builder does not. Thus CodeGen could clear the insertion point after emitting an terminator but CIRGen could not.

The assert statement in CIRGenFunction::generateCode ensures that the cleanup of the function-level lexical scope could be successfully generated in LexicalScope::~LexicalScope. Note that the cleanup also includes the return operation of the function. Since we currently have no means to track whether all paths to the end of a function is non-returning, the return op has to be emitted, thus the insertion point has to be kept alive by now.

The workaround is to start a new block that receives any ops generated after emitting a terminator op in the function body. This new block will be unreachable and will be elided by follow-up passes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that OG codegen (IRGen) clears insertion points is sometimes a bit brittle (used to signal some behavior that could be tracked more clearly). When emitting initializer for globals in CIR we sometimes also have no insertion point because those don't come from a regular function, and that's fine over there.

Just remove the overall question in form of comment and add a note saying that OG checks the insertion point but we do not.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good, thanks! Just missing a comment update

Comment on lines 1113 to 1120
// cir.trap is a terminator. The corresponding IRGen code does this:
// builder.clearInsertionPoint();
// However, CIRGenFunction::generateCode performs the following check, which
// fails if we do the same thing here:
// assert(builder.getInsertionBlock() && "Should be valid");
// IRGen has no equivalent assert, but for now we create a block to have a
// valid insertion point.
// TODO(cir): Should the CIRGenFunction::generateCode assert be relaxed?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that OG codegen (IRGen) clears insertion points is sometimes a bit brittle (used to signal some behavior that could be tracked more clearly). When emitting initializer for globals in CIR we sometimes also have no insertion point because those don't come from a regular function, and that's fine over there.

Just remove the overall question in form of comment and add a note saying that OG checks the insertion point but we do not.

This is permitted by the language, and IRGen emits traps for destructors
other than the base object destructor. Make CIRGen follow suit.
@smeenai smeenai force-pushed the defined-pure-virtual branch from 1c6c582 to c25189a Compare September 11, 2024 05:34
Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, there a few remaining fixed to tackle.

I'll merge this for now but you can tackle those once you are back from leave

@@ -1109,7 +1109,14 @@ void CIRGenFunction::buildDestructorBody(FunctionArgList &Args) {
// in fact emit references to them from other compilations, so emit them
// as functions containing a trap instruction.
if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) {
llvm_unreachable("NYI");
SourceLocation Loc =
Dtor->hasBody() ? Dtor->getBody()->getBeginLoc() : Dtor->getLocation();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd make slightly more sense if the trap is has the getEndLoc instead.


// The base object destructor should be emitted as normal.
// CHECK-LABEL: cir.func @_ZN1CD2Ev(%arg0: !cir.ptr<!ty_C> loc({{[^)]+}})) {{.*}} {
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_C>, !cir.ptr<!cir.ptr<!ty_C>>, ["this", init] {alignment = 8 : i64}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, the tests should use regex for the SSA values, should make them a little more resistant to overall CIR changes.

@bcardosolopes bcardosolopes merged commit 18ad5b8 into llvm:main Sep 11, 2024
6 checks passed
@smeenai
Copy link
Collaborator Author

smeenai commented Sep 16, 2024

Ack on the feedback, will address it when I can.

Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
This is permitted by the language, and IRGen emits traps for destructors
other than the base object destructor. Make CIRGen follow suit.
smeenai added a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
This is permitted by the language, and IRGen emits traps for destructors
other than the base object destructor. Make CIRGen follow suit.
smeenai added a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
This is permitted by the language, and IRGen emits traps for destructors
other than the base object destructor. Make CIRGen follow suit.
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
This is permitted by the language, and IRGen emits traps for destructors
other than the base object destructor. Make CIRGen follow suit.
lanza pushed a commit that referenced this pull request Nov 5, 2024
This is permitted by the language, and IRGen emits traps for destructors
other than the base object destructor. Make CIRGen follow suit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants