I don't think it's sufficient for full-fledged generalized tail call elimination. You can certainly optimize a self-recursive call down to a loop, but consider a case where a function accepts another function as a pointer, and invokes that pointer in a tail call position, for example (i.e. anything written in continuation-passing style).