[Ecls-list] Slightly disruptive changes

Juan Jose Garcia-Ripoll juanjose.garciaripoll at gmail.com
Thu Jan 10 09:23:22 UTC 2013

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.

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

Since ECL does not yet have the environment API, I have adopted a different

1* CONSTANTP will macroexpand expressions. This means that functions
assuming CONSTANTP returns T only on atoms will break.

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.

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.

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

> (disassemble '(lambda (x) (setf (mask-field (byte 10 3) x) 2) x))
;;; Compiling (DEFUN C::GAZONK ...).
;;; Emitting code for C::GAZONK.
/* function definition for GAZONK                                */
/* optimize speed 3, debug 0, space 0, safety 2                  */
static cl_object L1c__gazonk(cl_object v1x)
 cl_object T0;
 const cl_env_ptr cl_env_copy = ecl_process_env();
 cl_object value0;
   cl_object v2;
   T0 = ecl_boole(ECL_BOOLANDC2,(v1x),(ecl_make_fixnum(8184)));
   v2 = ecl_boole(ECL_BOOLIOR,(T0),(ecl_make_fixnum(0)));
   v1x = v2;
  value0 = v1x;
  cl_env_copy->nvalues = 1;
  return value0;

where a lot of constant folding has happened at the macro-level

> (pprint (macroexpand '(setf (mask-field (byte 10 3) x) 2)))

(LET* ((#:G18977 10) (#:G18978 3))
  (DECLARE (:READ-ONLY #:G18977 #:G18978))
    (DECLARE (:READ-ONLY #:G18979))
    (LET ((#:G18976 (DEPOSIT-FIELD #:G18979 (BYTE #:G18977 #:G18978) X)))
      (SETQ X #:G18976)

Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/ecl-devel/attachments/20130110/8605a563/attachment.html>

More information about the ecl-devel mailing list