What's false unwind edges?


The previous design was described in terms of the "pure" MIR control-flow graph. However, using the raw graph has some undesirable properties around infinite loops. In such cases, the graph has no exit, which undermines the traditional definition of reverse analyses like liveness. To address this, when we build the control-flow graph for our functions, we will augment it with additional edges -- in particular, for every infinite loop ( loop { } ), we will add false "unwind" edges. This ensures that the control-flow graph has a final exit node (the success of the RETURN and RESUME nodes) that postdominates all other nodes in the graph.

Like the title, what's false unwind edges? what's unwind?
And what's the success of the RETURN and RESUME nodes?

1 Like

I think this quote means that for purpose of analysis, every loop {} is converted internally to something like loop { if false { panic!() } }, i.e. with unreachable but formally existing exit.


Most liveliness algorithms work by starting at a return statement and working backwards in the control-flow graph to see which variables are alive/used at each node. This breaks down when you've got infinite loops though, because execution will never leave the loop (i.e. there is no "return" statement after it) and therefore nothing inside it will ever be considered alive.

It sounds like they are using "false unwinds" as a dummy node to ensure the loop gets checked for liveliness.


So what's the success of the RETURN and RESUME nodes?

Like this?

BLOCK A-------------------------------------------------------> BLOCK C
|                                                                  |
|                                                                  |
|                                                                  |
|                                                                  |
|                                                                  |
v                                                                  |
BLOCK B(contain a infinite loop)                                 |
 \                                                                |
  \                                                               |
   \                                                              v
    \                                                    RETURN BLOCK
     \                                                            |
      \                                                           |
       \                                                          |
        \                                                         v
         \ ---this is false unwind edge-----------------------> EXIT

what's a RESUME node?
Ahh, is it about async?

Resume is used when unwinding the stack to indicate that all necessary Drop impls have run and unwinding of the stack must continue.

Cound you show some source code which corresponds to RESUME?

Sorry, I mean what code from user will generate RESUME nodes in MIR?

It's still compiler code……

Anyway, thanks.

I mean ... how does code (which will be transformed into a RESUME node in MIR) look like?
I need an example because I can't understand the compiler source code...

RESUME node represents panic unwinding sequence. So any code that may panic will generates it. 1 + 1 in debug build can be an example.

Got it. But why 1 + 1 may panic?

Integer overflow panics on debug build. Obviously 1 + 1 never overflow, but recognizing it requires some level of compiler optimization but the debug build doesn't do most of them.

Edit: I found the 1 + 1 is optimized out by the MIR optimizer which still is enabled on debug build. So you need to pass rustc flag -Zmir-opt-level=0 to see the panic code.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.