Ignore my previous answer. It would be correct if basic blocks were statements in a procedural language (this is exactly what early-return looks like). You said this was a functional language, so I had another look at this and realized these are values. All of the basic blocks are values, and all of that is a single value. There is probably not a single explicit control flow statement in source code for this CFG. It's just an expression that looks something like that:
(and (or // bb 0-5 shambler-standing-explode-line-of-motion-check() // bb 0. If true, short-circuit 1-5 (and // bb 1-5 is-rogue-mode?() // bb 1 is-player?() // bb 2 (or player-is-prone?() // bb 3 player-is-supine?() // bb 4 ) player-in-prone-hiding-region?() // bb 5 ) ) (> melee-fact-get-time-since(player, shambler-explode) 5) // bb 6 (> melee-fact-get-time-since(arg_2, time-since-in-finisher-fail) 2) // bb 7 ) There are two interesting things here. Firstly, a compiler was smart enough to do early return as soon as answer is known, even for deeply nested bb 4 (which is not that surprising given than and and or are short circuiting in Racket so if bb 4 returned false then bb 5-7 must be short circuited anyway). Secondly, all of those early returns use same r4 register for condition, and all of them use negative branch for early return (so that r4 value is reused as return value). I bet top-level or would've had similar early returns with positive branches.
Previous incorrect answer follows.
It is not reducible to just if/else as control flow structure items (without doing shenanigans like injecting extra variables to aid control flow). It also employs early-returns; vertices going to return node do break nested structure. If you remove them you are left with a fairly easy CFG which can be represented by if/elses.