<div dir="ltr">While fixing the excessive consing of certain functions (LDB, DPB, etc) I came to the conclusion that ECL needs to handle better the discovery of constant expressions.<div><br></div><div>The thing is that many many macros create temporary values and store them in LET forms. Many other macros, including ECL's own compiler macros, try to optimize expressions but then see that the values of those expressions are variable names they cannot analyze -- are they constant, what are their types?</div>
<div><br></div><div>Since ECL does not yet have the environment API, I have adopted a different approach:</div><div><br></div><div>1* CONSTANTP will macroexpand expressions. This means that functions assuming CONSTANTP returns T only on atoms will break.</div>
<div><br></div><div>2* LET now checks for (:READ-ONLY var1 ... varn) declarations and if the value assigned to those variables are constants, then replaces those variables with SYMBOL-MACROLET definitions.</div><div><br>
</div>
<div>Note that :READ-ONLY is an internal declaration which is proprietary to ECL and it is only use by its own macros, including SETF expanders, optimizing compiler macros, etc.</div><div><br></div><div>This change is likely to affect code relying on CONSTANTP. For instance, ECL does not build if CONSTANTP macroexpands also list expressions, something I am now investigating. Nevertheless, I think it is worth the change, due to the better code generated. See for instance</div>
<div><br></div><div><div>> (disassemble '(lambda (x) (setf (mask-field (byte 10 3) x) 2) x))</div><div>;;; Compiling (DEFUN C::GAZONK ...).<br></div><div>;;; Emitting code for C::GAZONK.</div><div>/*<span class="" style="white-space:pre"> </span>function definition for GAZONK */</div>
<div>/*<span class="" style="white-space:pre"> </span>optimize speed 3, debug 0, space 0, safety 2 */</div><div>static cl_object L1c__gazonk(cl_object v1x)</div><div>{</div><div> cl_object T0;</div><div>
const cl_env_ptr cl_env_copy = ecl_process_env();</div>
<div> cl_object value0;</div><div> ecl_cs_check(cl_env_copy,value0);</div><div> {</div><div>TTL:</div><div> {</div><div> cl_object v2;</div><div> T0 = ecl_boole(ECL_BOOLANDC2,(v1x),(ecl_make_fixnum(8184)));</div><div>
v2 = ecl_boole(ECL_BOOLIOR,(T0),(ecl_make_fixnum(0)));</div><div> v1x = v2;</div><div> }</div><div> value0 = v1x;</div><div> cl_env_copy->nvalues = 1;</div><div> return value0;</div><div> }</div><div>}</div><div>
<br></div><div style>where a lot of constant folding has happened at the macro-level</div><div style><br></div><div style><div>> (pprint (macroexpand '(setf (mask-field (byte 10 3) x) 2)))</div><div><br></div><div>
(LET* ((#:G18977 10) (#:G18978 3))</div><div> (DECLARE (:READ-ONLY #:G18977 #:G18978))</div><div> (MULTIPLE-VALUE-BIND</div><div> (#:G18979)</div><div> 2</div><div> (DECLARE (:READ-ONLY #:G18979))</div><div>
(LET ((#:G18976 (DEPOSIT-FIELD #:G18979 (BYTE #:G18977 #:G18978) X)))</div><div> (SETQ X #:G18976)</div><div> #:G18979)))</div><div><br></div></div><div><br></div>-- <br>Instituto de Física Fundamental, CSIC<br>
c/ Serrano, 113b, Madrid 28006 (Spain) <br><a href="http://juanjose.garciaripoll.googlepages.com" target="_blank">http://juanjose.garciaripoll.googlepages.com</a>
</div></div>