Some news about the compiler... But before I write about them let me explain that this is not yet uploaded to git/CVS due to firewall problems<br><br>I have implemented various simplifications. Just in case anyone care, they are the following ones.<br>
<br>First, improved the accuracy with which variables keep track of the forms in which they are read or assigned values. This is essential for substituting variables with their values, thus simplifying (LET ((X 2)) (COS X)) into (COS 2).<br>
<br>Second, when replacing a variable with its value, ECL used to create a kind of proxy. The translation would be (COS (VALUES 2)) instead of (COS 2). Since we have no type propagation algorithm activated, this meant that COS did not know the actual type of the argument and it would not get optimized.<br>
<br>Third, array operations are now optimized using compiler macros. These macros produce code which may or may not contain safety checks (ensure it has an array, right rank, right index bounds), but always result into a simple call to ROW-MAJOR-AREF/ASET, a function that can be efficiently inlined if the types are known.<br>
<br>Fourth, LET/LET* forms now incorporate a bit more accurate phases for replacing variables with their values, determining the variable types before processing the LET body, etc.<br><br>Fifth, I have compiled a database with the intermediate language that ECL uses for compilation, describing their side effects, whether forms can be moved or not, etc.<br>
<br>Sixth, DOTIMES now declares the type of the variable if the number of times is known in advance.<br><br>Using all this the compiler can indeed produce much better code, even though it still lacks good type inference. As an example, in the Spartans test suite there is a test that I rewrote for efficiency as follows<br>
<br>(defun run-array-set ()<br> (declare (optimize (speed 3) (debug 0) (safety 0)))<br> (flet ((xloop ()<br> (let ((A (make-array '(100 100 100) :element-type 'single-float<br> :adjustable nil))<br>
(value 8.5))<br> (dotimes (n 50)<br> (dotimes (i 90)<br> (dotimes (j 90)<br> (dotimes (k 90)<br> (setf (aref A i j k) value))))))))<br> (time (funcall #'xloop))))<br>
<br>These are the results of running the test:<br><br>SBCL:<br>Evaluation took:<br> 0.061 seconds of real time<br> 0.061434 seconds of total run time (0.059799 user, 0.001635 system)<br> 100.00% CPU<br> 187,758,281 processor cycles<br>
4,004,112 bytes consed<br><br>ECL(git/CVS):<br>real time : 0.079 secs<br>run time : 0.075 secs<br>gc count : 2 times<br>consed : 4000177 bytes<br><br>And here is the code it generates:<br><br>static cl_object L1c__gazonk()<br>
{ VT2 VLEX2 CLSR2 STCK2<br> const cl_env_ptr cl_env_copy = ecl_process_env();<br> cl_object value0;<br>TTL:<br> {cl_object V1; /* A */<br> V1= si_make_pure_array(ECL_SYM("SINGLE-FLOAT",776),VV[0],Cnil,Cnil,Cnil,MAKE_FIXNUM(0)) /* MAKE-PURE-ARRAY */;<br>
{int8_t V2; /* N */<br> V2= ((int8_t)0);<br> goto L5;<br>L4:;<br> {int8_t V3; /* I */<br> V3= ((int8_t)0);<br> goto L11;<br>
L10:;<br> {int8_t V4; /* J */<br> V4= ((int8_t)0);<br> goto L17;<br>L16:;<br> {int8_t V5; /* K */<br> V5= ((int8_t)0);<br>
goto L23;<br>L22:;<br> {cl_fixnum V6;<br> {cl_fixnum V7;<br> cl_fixnum V8;<br> cl_fixnum V9;<br> V7= ((cl_fixnum)V3);<br> V8= V7;<br> V9= 0;<br> V9= (V1)->array.dims[0];<br> V8= (V8)*(V9);<br>
V9= (V1)->array.dims[1];<br> V7= ((cl_fixnum)V4);<br> V8= (V8)+(V7);<br> V8= (V8)*(V9);<br> V9= (V1)->array.dims[2];<br> V7= ((cl_fixnum)V5);<br> V8= (V8)+(V7);<br> V6= V8;<br> }<br> (V1)->array.self.sf[V6]= 8.5 ;}<br>
V5= ((int8_t)(((cl_fixnum)V5))+1);<br>L23:;<br> if(!((((cl_fixnum)V5))<(90))){<br> goto L54;}<br> goto L22;<br>L54:;<br> goto L52;<br>L52:;<br> goto L19;<br> }<br>L19:;<br> V4= ((int8_t)(((cl_fixnum)V4))+1);<br>
L17:;<br> if(!((((cl_fixnum)V4))<(90))){<br> goto L60;}<br> goto L16;<br>L60:;<br> goto L58;<br>L58:;<br> goto L13;<br> }<br>L13:;<br> V3= ((int8_t)(((cl_fixnum)V3))+1);<br>L11:;<br> if(!((((cl_fixnum)V3))<(90))){<br>
goto L66;}<br> goto L10;<br>L66:;<br> goto L64;<br>L64:;<br> goto L7;<br> }<br>L7:;<br> V2= ((int8_t)(((cl_fixnum)V2))+1);<br>L5:;<br> if(!((((cl_fixnum)V2))<(50))){<br> goto L72;}<br> goto L4;<br>
L72:;<br> goto L70;<br>L70:;<br> value0=Cnil; cl_env_copy->nvalues=1;<br> return value0;<br> }<br> }<br>}<br clear="all"><br>-- <br>Instituto de Física Fundamental, CSIC<br>c/ Serrano, 113b, Madrid 28006 (Spain) <br>
<a href="http://tream.dreamhosters.com">http://tream.dreamhosters.com</a><br>