ANF is good for codegen but bad for optimization as normalization can take O(n) time for each redex. CPS avoids the ANF conversion bottlenecks. Hoisted join points in ANF are just continuations. ANF is a (generalized) monadic IR after normalization.
A cps term that encodes cbv and left-to-right evaluation is syntactically in RPN and can be scanned by a PDA. An inverse to the one-pass CBV CPS transform is given for such terms. Transformation of DS and CPS terms into monadic form (in
Cont)/ANF first makes the conversion to CPS/DS simpler. Tailcalls can be encoded in monadic form by making tail application be a terminal expression.
Adding join points as a construct to an IR eliminates the need for CPS.
A tower of interpreters is really a tower of CESK machines.