If I understand what you're saying, you're suggesting that a single self-tail-recursive function can be rewritten using an exception thrown and caught within the function.
That's something, but what about a set of mutually tail-recursive functions? Of course one can always use a trampoline, but then you have to pay the cost of consing thunks. It would still be worthwhile to have true tail-call instructions in the bytecode.
My understanding is that Graal's compilation units are basically an amalgamation of all of the hot code in an area; function boundaries don't really come into it in the same way they do in C. If you're reliably tail recursing, that's going to be in the same compilation unit. This image might make it clearer:
Truffle frames are just Java objects, so when the exception returns us to the root of the method, we can create a new frame to run an entirely different method.
We aren't looking to modify Java, so we aren't the people to ask for a tail-call instruction in the bytecode.