[comp.lang.lisp] AKCL declarations

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