AmrDeveloper wrote:

> We should create a design document describing the EH codegen and lowering 
> process. When I made my suggestions on #172713 I may have been starting from 
> the wrong place in the CIR pipeline, but the way we currently have things 
> ordered isn't well-suited to our needs.
> 
> Currently, we have this order:
> 
> 1. High-level CIR CodeGen
> 2. CIR canonicalize pass
> 3. (optionally) CIR simplify pass
> 4. CXXABI lowering pass
> 5. Lowering prepare pass
> 6. (command-line specified passes)
> 7. Hoist allocas pass
> 8. CIR flatten cfg pass
> 9. Goto solver pass
> 
> That's problematic for EH because the C++ ABI details of EH handling don't 
> appear until the flatten cfg pass.
> 
> Should we be flattening the EH call graph during CXXABI lowering? Or should 
> the CXXABI lowering be deferred until after the CFG flattening. The 
> ABI-independent representation I suggested isn't necessary if we do the 
> flattening as part of the CXXABI lowering. I'm not sure that's practical in 
> all cases, but I'm also not sure it isn't.

That makes sense.

> I'm not sure that's practical in all cases, but I'm also not sure it isn't

I was thinking of creating a POC for one approach, and then we can decide, 
maybe we can also create a mix between the new design and the old one, for 
example, I really like the syntax of switch flat like dispatch, it's very clean 
in case of multiple catchers, for example with the current design

```
int bar() {
  int ret = 0;
  try {
    foo();
  } catch (int n) {
    ret = n;
  } catch (float n) {
    ret = 2;
  } catch (double n) {
    ret = 3;
  } catch (...) {
    ret = 4;
  }
  return ret;
}
```

The flatten CIR will be like this

```
  ^bb4:  // pred: ^bb2
    %exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi, @_ZTIf, 
@_ZTId] loc(#loc1)
    cir.br ^bb5(%exception_ptr, %type_id : !cir.ptr<!void>, !u32i) loc(#loc1)
  ^bb5(%6: !cir.ptr<!void> loc("main.cpp":5:3), %7: !u32i loc("main.cpp":5:3)): 
 // pred: ^bb4
    %8 = cir.eh.typeid @_ZTIi loc(#loc1)
    %9 = cir.cmp(eq, %7, %8) : !u32i, !cir.bool loc(#loc1)
    cir.brcond %9 ^bb6(%6 : !cir.ptr<!void>), ^bb7(%6, %7 : !cir.ptr<!void>, 
!u32i) loc(#loc1)
  ^bb6(%10: !cir.ptr<!void> loc(unknown)):  // pred: ^bb5
    // Catch param begin & end, assign const value to ret 
    cir.br ^bb12 loc(#loc17)
  ^bb7(%14: !cir.ptr<!void> loc("main.cpp":5:3), %15: !u32i 
loc("main.cpp":5:3)):  // pred: ^bb5
    %16 = cir.eh.typeid @_ZTIf loc(#loc1)
    %17 = cir.cmp(eq, %15, %16) : !u32i, !cir.bool loc(#loc1)
    cir.brcond %17 ^bb8(%14 : !cir.ptr<!void>), ^bb9(%14, %15 : 
!cir.ptr<!void>, !u32i) loc(#loc1)
  ^bb8(%18: !cir.ptr<!void> loc(unknown)):  // pred: ^bb7
    // Catch param begin & end, assign const value to ret 
    cir.br ^bb12 loc(#loc17)
  ^bb9(%22: !cir.ptr<!void> loc("main.cpp":5:3), %23: !u32i 
loc("main.cpp":5:3)):  // pred: ^bb7
    %24 = cir.eh.typeid @_ZTId loc(#loc1)
    %25 = cir.cmp(eq, %23, %24) : !u32i, !cir.bool loc(#loc1)
    cir.brcond %25 ^bb10(%22 : !cir.ptr<!void>), ^bb11(%22 : !cir.ptr<!void>) 
loc(#loc1)
  ^bb10(%26: !cir.ptr<!void> loc(unknown)):  // pred: ^bb9
    // Catch param begin & end, assign const value to ret 
  ^bb11(%30: !cir.ptr<!void> loc("main.cpp":5:3)):  // pred: ^bb9
    // Catch param begin & end, assign const value to ret 
```

It's a chain of branch jumps, but with the switch-like syntax, it will be 
clearer

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

Reply via email to