atbowler@watmath.UUCP (Alan T. Bowler [SDG]) (04/15/86)
In article <708@bentley.UUCP> kwh@bentley.UUCP (KW Heuer) writes: >A good optimizer should compile tail-recursion into a jump anyway. (But >there are few good optimizers by that standard.) > There is a problem if you want to support a "nargs" function with this. If an implementation tries stores the nargs value in some fixed position in the call sequence then it cannot optimize tail recursion into a branch to this or some other function. (If your compiler wants to optimize tail recursion then why not end calls as well.) On a lot of hardware models it is quite feasible to put a nargs constant a part of the call sequence (as was done in pre-version 6 Unix). If this is possible it seems the most useful place to keep it since it involves essentially no overhead unless the called program chooses to use it. Tail recursion and end call optimization results in the "wrong" nargs value being found. (i.e. that associated with the original call to the function and not the call that was optimized out). There are 2 ways arround this 1) always pass the nargs value as an explicit hidden argument which raises the overhead for all function calls. (i.e. an expensive choice to make). 2) delete nargs functionality which denies the programmer a very useful tool to reduced the overhead and name clutter in is program. I know that the later option is one I must assume when I am writing very portable programs, but there are many times when I am writing system specific code and it is annoying to have to do things like "node1(a), node2(a, b), node3(a,b,c)". In environments where I have NARGS guaranteed, I make more use of it than tail recursion.
henry@utzoo.UUCP (Henry Spencer) (04/15/86)
> >A good optimizer should compile tail-recursion into a jump anyway... > > There is a problem if you want to support a "nargs" function with this... Nargs was a useful thing back in the days of V5 and early V6, when almost everything in C was one word in size. Its usefulness is greatly diminished now that C's data types have gotten more diverse. Especially since there are serious portability problems involved in *doing* anything with the information, and with implementing nargs at all. For these reasons, most everyone has stopped using it. Nargs is not a major argument against a potentially useful optimization. -- Support the International League For The Derision Henry Spencer @ U of Toronto Zoology Of User-Friendliness! {allegra,ihnp4,decvax,pyramid}!utzoo!henry
sam@delftcc.UUCP (Sam Kendall) (04/17/86)
I haven't seen it mentioned yet that if you optimize away a stack frame which is referred to by a jmp_buf (the setjmp data type), a longjmp to that stack frame will fail. Therefore a compiler that wants to optimize tail recursion must know about setjmp in order to suppress tail recursion optimization in functions that call setjmp. This is compatible with the ANSI draft standard. A couple of points to answer (square brackets mine): In article <2122@watmath.UUCP>, atbowler@watmath.UUCP writes: > There is a problem if you want to support a "nargs" function with [tail > recursion]. > If an implementation tries stores the nargs value in some fixed position > in the call sequence then it cannot optimize tail recursion into > a branch to this or some other function. If you really want nargs, just optimize tail recursion into a change to the nargs value, followed by a branch. What's the problem? > [I]t is annoying to have to do things like > "node1(a), node2(a, b), node3(a,b,c)". You can use varargs here. You also need an argument list terminator, so do something like #define NIL ((NODE *) NULL) /* assuming arguments to node are of type NODE * */ node(a, NIL) node(a, b, c, NIL) ---- Sam Kendall { ihnp4 | seismo!cmcl2 }!delftcc!sam Delft Consulting Corp. ARPA: delftcc!sam@NYU.ARPA