erichkeane wrote:

> > Can we get a C++ test for this? I'm having a hard time figuring out what 
> > this looks like/what the lifetime of these cleanups are.
> 
> I won't be able to give you a C++ test until the third PR in this series. 
> Here's a preview though:
> 
> ```
> struct S {
>   S();
>   ~S();
>   explicit operator bool();
> };
> 
> void while_cond_var() {
>   while (S s{})
>     doSomething();
> }
> 
> // CIR-LABEL: cir.func {{.*}} @_Z14while_cond_vari
> // CIR:   %[[FLAG:.*]] = cir.alloca {{.*}}"cond.cleanup.isactive"{{.*}} : 
> !cir.ptr<!cir.bool>
> // CIR:   cir.scope {
> // CIR:     %[[S:.*]] = cir.alloca {{.*}}"s"{{.*}} : !cir.ptr<!rec_S>
> // CIR:     cir.while {
> // CIR:       %[[FALSE:.*]] = cir.const #false
> // CIR:       cir.store %[[FALSE]], %[[FLAG]]
> // CIR:       cir.call @_ZN1SC1Ev(%[[S]])
> // CIR:       %[[TRUE:.*]] = cir.const #true
> // CIR:       cir.store %[[TRUE]], %[[FLAG]]
> // CIR:       %[[COND:.*]] = cir.call @_ZN1ScvbEv(%[[S]])
> // CIR:       cir.condition(%[[COND]])
> // CIR:     } do {
> // CIR:     } cleanup all {
> // CIR:       %[[ACTIVE:.*]] = cir.load {{.*}}%[[FLAG]]
> // CIR:       cir.if %[[ACTIVE]] {
> // CIR:         cir.call @_ZN1SD1Ev(%[[S]]) nothrow
> // CIR:       }
> // CIR:       cir.yield
> // CIR:     }
> // CIR:   }
> ```
> 
> We create the alloca for the condition variable in the scope outside the loop 
> (as we have before this change). In theory, we could get rid of that scope 
> and let the alloca go to the next higher scope or the entry block, but it has 
> to be outside the loop operation. It has nothing to do with the actual scope 
> of the variable.
> 
> If we were generating lifetime markers (as we will soon after this series of 
> PRs land), the lifetime_begin would go in the condition region (above FALSE, 
> I think), and the lifetime_end would go in the cleanup.
> 
> The use of the "cond.cleanup.isactive" flag here is an unfortunate artifact 
> of not having a proper place to insert the cleanup scope. We're treating the 
> entire condition and body region as the scope of the cleanup. Any exception 
> thrown by the ctor would unwind to the cleanup, so we need to do something to 
> avoid calling the dtor if the object was never constructed. We might be able 
> to fix that in flattening or with a post-codegen optimization, but at least 
> for the first working implementation I thought this was the way to go.

Thanks, this is really helpful!

https://github.com/llvm/llvm-project/pull/210212
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to