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