Hello all,

I'm trying to get ECL to optimize tail self-calls in the C code generated from the Lisp files and it looks like I'm missing something, because I can't find a way to do that.

Here is the behavior I'm getting for this simple Lisp function:

(defun enumerate (l &optional (index 0) (result nil))
  (cond
    ((null l) (reverse result))
(t (enumerate (cdr l) (+ index 1) (cons (list index (car l)) result)))
  )
)

As far as I can see, this function is properly tail-recursive, so I expected the generated C code to take the into account and generate a goto instead of a recursive call. But what I'm getting is this:

static cl_object L1enumerate(cl_narg narg, cl_object v1l, ...)
{
 cl_object T0, T1, T2, T3, T4;
 cl_object env0;
 const cl_env_ptr cl_env_copy = ecl_process_env();
 cl_object value0;
 ecl_cs_check(cl_env_copy,value0);
 if (ecl_unlikely(narg<1)) FEwrong_num_arguments_anonym();
 if (ecl_unlikely(narg>3)) FEwrong_num_arguments_anonym();
 {
  cl_object v2index;
  cl_object v3result;
  va_list args; va_start(args,v1l);
  {
   int i = 1;
   if (i >= narg) {
    v2index = ecl_make_fixnum(0);
   } else {
    i++;
    v2index = va_arg(args,cl_object);
   }
   if (i >= narg) {
    v3result = ECL_NIL;
   } else {
    i++;
    v3result = va_arg(args,cl_object);
   }
  }
  va_end(args);
  if (!(v1l==ECL_NIL)) { goto L3; }
  value0 = cl_reverse(v3result);
  return value0;
L3:;
  T0 = ecl_cdr(v1l);
  T1 = ecl_plus(v2index,ecl_make_fixnum(1));
  T2 = ecl_car(v1l);
  T3 = cl_list(2, v2index, T2);
  T4 = CONS(T3,v3result);
  value0 = L1enumerate(3, T0, T1, T4);
  return value0;
 }
}

The recursive call is generated as a recursive call in C too...

I'm almost sure I've seen C code generated from ECL that generated self tail calls as goto's, and I know it works when using the bytecode, where you just have to compile the function. But my search for a way to trigger this behavior for the generated C code has been unsuccessful so far.

I'm using ECL 16.1.3. I used "ecl -c ... --compile ..." to get the C code, but my main build uses asdf:make-build with an ASD file.

Reply via email to