djb@stoney.mitre.org (David J. Braunegg) (12/05/90)
Does anyone know how to make declarations in AKCL work? I looked at the code in the .c file for the following four functions, and they were all the same. (defun test1 (x) (* x x)) (defun test2 (x) (declare (fixnum x)) (* x x)) (defun test3 (x) (the fixnum (* x x))) (defun test4 (x) (declare (fixnum x)) (the fixnum (* x x))) The C code is shown below. I would have at least expected #2 to produce code using int instead of object for V1. static L1() {register object *base=vs_base; register object *sup=base+VM1; VC1 vs_check; {object V1; V1=(base[0]); vs_top=sup; TTL:; base[1]= number_times((V1),(V1)); vs_top=(vs_base=base+1)+1; return; } } Likewise, the following four functions produced the same C code; (proclaim '(ftype (function (fixnum) fixnum) test5)) (defun test5 (x) (* x x)) (proclaim '(ftype (function (fixnum) fixnum) test6)) (defun test6 (x) (declare (fixnum x)) (* x x)) (proclaim '(ftype (function (fixnum) fixnum) test7)) (defun test7 (x) (the fixnum (* x x))) (proclaim '(ftype (function (fixnum) fixnum) test8)) (defun test8 (x) (declare (fixnum x)) (the fixnum (* x x))) The C code this time included int declarations for the function and arg, but rather than accepting that the arguments and result would be fixnum, explicitly converted them to fixnums using CMPmake_fixnum. (I guess the fix operation on the result in case the result got too large.) static int LI5(V6) int V6; { VMB5 VMS5 VMV5 TTL:;{object V7; V7= CMPmake_fixnum(V6);{object V8; V8= CMPmake_fixnum(V6); VMR5(fix(number_times(V7,V8)))}} }
srt@aerospace.aero.org (Scott "TCB" Turner) (12/06/90)
Try: (proclaim '(function foo (fixnum) fixnum)) (defun foo (x) (declare (fixnum x)) (the fixnum (* x x))) That should produce what you expect. I went through this whole business a few months ago. It can be tricky to figure out exactly what declarations AKCL needs to perform optimizations, but you rarely can go wrong if you declare everything in sight. Once you get the hang of it, it becomes obvious what you need. In this case, I think you are a little confused over declarations inside a function and outside the function. For example, (defun test4 (x) (declare (fixnum x)) (the fixnum (* x x))) This declaration does *not* tell AKCL that test4 will be called with a fixnum argument. What it says is that *test4* assumes that the argument will be a fixnum. So AKCL generates code on the assumption that x could be anything, and needs to be turned into a fixnum. The proclaim tells AKCL about how a function will be called. The proclamation (proclaim '(function test4 (fixnum) fixnum)) tells AKCL that the arguments to test4 will be fixnums and that the returned result will also be a fixnum. Incidentally, if you are worried about speed, I've found that the three biggest factors in AKCL code are: (1) GC. My personal experience has been that frequent small GCs win *big* over infrequent large GCs. (On a Sun 4/110.) (2) Explicit operations wherever possible. Avoiding object conversions and generic functions is not only much faster, but it greatly reduces the amount of garbage generated. "Foo" with the fixnum declarations above produces *no* garbage. Without it generates three ephemeral objects. (3) Declaration of functions with fixed arguments. In AKCL, function calls of fixed arguments are much faster than generic function calls. -- Scott Turner