Skip to content

Flow graph successors representation for BBJ_EHFINALLYRET #84278

@BruceForstall

Description

@BruceForstall

The try of a try / finally clause can contain a set of leave IL specifying to where the code should continue after the finally is invoked. The JIT transforms this into IR like:

// try
 ... code ...
BBJ_CALLFINALLY / bbJumpDest = the finally funclet
BBJ_ALWAYS / bbJumpDest = the "continuation" address specified by the `leave`
...
// finally
 ... code ...
BBJ_EHFINALLYRET

Note that there can be multiple leave IL that require invoking the same finally, and thus multiple BBJ_CALLFINALLY targeting the same finally. Each of the corresponding BBJ_ALWAYS (continuation) targets can be different, however.

Note also that if the finally is known to never return (due to an unconditional throw or infinite loop), the BBJ_CALLFINALLY will not have a BBJ_ALWAYS and the finally will not have a BBJ_EHFINALLYRET.

The "flowgraph successors" of the BBJ_EHFINALLYRET block are all the BBJ_ALWAYS blocks corresponding to the BBJ_CALLFINALLY blocks that target the finally.

Currently, the JIT does not directly represent the BasicBlock successors of a BBJ_EHFINALLYRET block. Finding those successors, as is done with the versions of GetSucc/NumSucc that take a Compiler*, is very expensive.

Can we directly represent the BBJ_EHFINALLYRET successors in the IR? E.g., as an array of BasicBlock*, the same way BBJ_SWITCH successors are implemented?

This would make forward GetSucc/NumSucc flowgraph traversals much cheaper.

Note that the IR is asymmetric here: the BBJ_ALWAYS pair of BBJ_CALLFINALLY has the BBJ_EHFINALLYRET in its predecessor list.

@AndyAyersMS @dotnet/jit-contrib Comments?

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions