// File: /workspace/github_c_makefile_star2_O1/BernardTatin[P]s7sh/s7.c
// Function: optimize_lambda
static void optimize_lambda(s7_scheme *sc, bool unstarred_lambda, s7_pointer func, s7_pointer args, s7_pointer body)
                {
                    s7_int len;

                    len = s7_list_length(sc, body);
#if OPTIMIZE_PRINT
                    fprintf(stderr, "%s[%d]: %s %s %ld\n", __func__, __LINE__, DISPLAY(func), DISPLAY(args), len);
#endif

                    if (len < 0)                /* (define (hi) 1 . 2) */
                        s7_error(sc, sc->syntax_error_symbol,
                                set_elist_3(sc, wrap_string(sc, "~A: function body messed up, ~A", 31),
                                    (unstarred_lambda) ? sc->lambda_symbol : sc->lambda_star_symbol,
                                    sc->code));

                    if (len > 0)  /* i.e. not circular */
                    {
                        body_t result;
                        s7_pointer p, lst, cleared_args;

                        clear_symbol_list(sc);
                        for (p = args; is_pair(p); p = cdr(p))
                            add_symbol_to_list(sc, (is_symbol(car(p))) ? car(p) : caar(p));
                        if (!is_null(p))
                            add_symbol_to_list(sc, p);
                        sc->got_tc = false;
                        sc->got_rec = false;
                        result = body_is_safe(sc, func, body, true);
                        clear_symbol_list(sc);

                        /* if the body is safe, we can optimize the calling sequence */
                        if (!unstarred_lambda)
                        {
                            bool happy = true;
                            /* check default vals -- if none is an expression or symbol, set simple args */
                            for (p = args; is_pair(p); p = cdr(p))
                            {
                                s7_pointer arg;
                                arg = car(p);
                                if ((is_pair(arg)) &&                   /* has default value */
                                        (is_pair(cdr(arg))) &&              /*   is not a ridiculous improper list */
                                        ((is_symbol(cadr(arg))) ||          /*   if default value might involve eval in any way, it isn't simple */
                                         (is_unquoted_pair(cadr(arg)))))    /*   pair as default only ok if it is (quote ...) */
                                {
                                    happy = false;
                                    if ((result > UNSAFE_BODY) &&
                                            (tree_has_definers_or_binders(sc, cadr(arg)))) /* if the default has a definer, body is not safe (funclet is not stable) */
                                        result = UNSAFE_BODY;
                                    break;
                                }
                            }
                            if (happy)
                                lambda_set_simple_defaults(body);
                        }
                        if (result >= SAFE_BODY)
                        {
                            set_safe_closure_body(body);	  /* this bit is set on the function itself in make_closure and friends */
                            if (result == VERY_SAFE_BODY)
                                set_very_safe_closure_body(body);
                        }

                        if (is_symbol(func))
                        {
                            lst = cons(sc, add_symbol_to_list(sc, func), sc->nil);
                            sc->temp10 = lst;
                        }
                        else lst = sc->nil;

                        /* TODO: check cleared_args */
                        if (optimize(sc, body, 1, cleared_args = collect_parameters(sc, args, lst)) == OPT_OOPS)
                            clear_all_optimizations(sc, body);
                        else
                        {
                            if (result >= RECUR_BODY) /* (is_safe_closure_body(body)) */
                            {
                                int32_t nvars;
                                for (nvars = 0, p = args; is_pair(p); nvars++, p = cdr(p));

                                if (is_null(p))
                                {
                                    if (nvars > 0)
                                    {
                                        annotate_args(sc, body, cleared_args);
                                        fx_tree(sc, body,
                                                (is_pair(car(args))) ? caar(args) : car(args),
                                                (nvars > 1) ? ((is_pair(cadr(args))) ? caadr(args) : cadr(args)) : NULL);
                                    }
                                }
                                if ((unstarred_lambda) || (nvars == 1))
                                {
                                    if (is_null(cdr(body)))
                                    {
                                        if (sc->got_tc)
                                        {
                                            if (check_tc(sc, func, nvars, args, car(body)))
                                                set_safe_closure_body(body);
                                        }
                                        if ((sc->got_rec) &&
                                                (!is_tc_op(optimize_op(car(body)))) &&
                                                (result >= RECUR_BODY))
                                        {
                                            if (check_recur(sc, func, nvars, args, car(body)))
                                                set_safe_closure_body(body);
                                        }
#if 0
                                        if (((sc->got_tc) || (sc->got_rec)) &&
                                                (!is_rec_op(optimize_op(car(body)))) &&
                                                (!is_tc_op(optimize_op(car(body)))) &&
                                                (!is_symbol(cadar(body)))) /* and let as start */
                                            fprintf(stderr, "%s[%d]: %s %d %s\n", __func__, __LINE__, DISPLAY(func), nvars, DISPLAY(body));
#endif
                                    }
                                }
                            }
                        }
                        if (is_symbol(func))
                        {
                            sc->temp10 = sc->nil;
                            free_cell(sc, lst);
                        }
                        sc->got_tc = false;
                        sc->got_rec = false;
                    }
                }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, %r15
movq %rcx, %r12
movq %rdx, %r13
movl %esi, %ebp
movq %rdi, %rbx
movq %r8, %rsi
callq 0x3c299
movq %rax, %r14
testq %rax, %rax
jns 0xe9fae
movq 0x1918(%rbx), %rsi
movq 0x820(%rbx), %rax
movslq 0x7dc(%rbx), %rcx
movq (%rax,%rcx,8), %rax
incl %ecx
andl $0x7, %ecx
movl %ecx, 0x7dc(%rbx)
leaq 0x36fab(%rip), %rcx     # 0x120f10
movq %rcx, 0x10(%rax)
movq $0x1f, 0x8(%rax)
movl %ebp, %ecx
xorb $0x1, %cl
movzbl %cl, %ecx
movq 0x1798(%rbx,%rcx,8), %rcx
movq (%rbx), %rdx
movq 0x6e8(%rbx), %rdi
movq %rax, 0x8(%rdi)
movq 0x10(%rdi), %rax
movq %rcx, 0x8(%rax)
movq 0x10(%rax), %rax
movq %rdx, 0x8(%rax)
movq 0x6e8(%rbx), %rdx
movq %rbx, %rdi
callq 0x3b366
testq %r14, %r14
jle 0xea2e4
incl 0xa88(%rbx)
jne 0xe9fcf
movl $0x1, 0xa88(%rbx)
incl 0xa8c(%rbx)
cmpb $0x1, (%r12)
movq %r12, %rax
jne 0xea00c
movq %r12, %rax
movq 0x8(%rax), %rcx
cmpb $0xa, (%rcx)
je 0xe9fe9
movq 0x8(%rcx), %rcx
movl 0xa88(%rbx), %edx
movl %edx, 0x2c(%rcx)
movl 0xa8c(%rbx), %edx
movq 0x8(%rcx), %rcx
movq 0x20(%rcx), %rcx
movl %edx, 0xc(%rcx)
movq 0x10(%rax), %rax
cmpb $0x1, (%rax)
je 0xe9fdc
movl %ebp, 0xc(%rsp)
cmpq 0x110(%rbx), %rax
je 0xea033
movl 0xa88(%rbx), %ecx
movl %ecx, 0x2c(%rax)
movl 0xa8c(%rbx), %ecx
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
movl %ecx, 0xc(%rax)
movw $0x0, 0x24e(%rbx)
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
movl $0x1, %ecx
callq 0xea423
movl %eax, %ebp
incl 0xa88(%rbx)
jne 0xea069
movl $0x1, 0xa88(%rbx)
incl 0xa8c(%rbx)
cmpb $0x0, 0xc(%rsp)
jne 0xea0e5
movb $0x1, %al
cmpb $0x1, (%r12)
jne 0xea0dc
movb $0x1, %al
movq %r12, %r14
movq 0x8(%r14), %rcx
cmpb $0x1, (%rcx)
jne 0xea0c2
movq 0x10(%rcx), %rcx
cmpb $0x1, (%rcx)
jne 0xea0c2
movq 0x8(%rcx), %rdi
movzbl (%rdi), %ecx
cmpl $0xa, %ecx
je 0xea0ae
cmpl $0x1, %ecx
jne 0xea0c2
movq 0x8(%rdi), %rcx
cmpq 0x17b0(%rbx), %rcx
je 0xea0c2
testl %ebp, %ebp
je 0xea0d4
callq 0xd9cb1
xorl %ecx, %ecx
testb %al, %al
cmovnel %ecx, %ebp
xorl %eax, %eax
jmp 0xea0c4
movb $0x1, %cl
testb %cl, %cl
je 0xea0dc
movq 0x10(%r14), %r14
cmpb $0x1, (%r14)
je 0xea07e
jmp 0xea0dc
xorl %ecx, %ecx
xorl %eax, %eax
xorl %ebp, %ebp
jmp 0xea0c4
testb $0x1, %al
je 0xea0e5
orb $0x4, 0x1(%r15)
cmpl $0x2, %ebp
jb 0xea0f9
orb $0x10, 0x1(%r15)
cmpl $0x3, %ebp
jne 0xea0f9
orb $0x10, 0x6(%r15)
cmpb $0xa, (%r13)
movq %r13, 0x10(%rsp)
jne 0xea173
movl 0xa88(%rbx), %eax
movl %eax, 0x2c(%r13)
movl 0xa8c(%rbx), %eax
movq 0x8(%r13), %rcx
movq 0x20(%rcx), %rcx
movl %eax, 0xc(%rcx)
movq 0x90(%rbx), %rax
movq 0x110(%rbx), %r14
cmpq 0x98(%rbx), %rax
ja 0xea13f
movq %rbx, %rdi
callq 0xb389
movq 0x90(%rbx), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x90(%rbx)
movq -0x8(%rax), %r13
movq $0x200001, (%r13)       # imm = 0x200001
movq 0x10(%rsp), %rax
movq %rax, 0x8(%r13)
movq %r14, 0x10(%r13)
movq %r13, 0x540(%rbx)
jmp 0xea17a
movq 0x110(%rbx), %r13
movq %rbx, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xe9007
movq %rax, %r14
movq %rbx, %rdi
movq %r15, %rsi
movl $0x1, %edx
movq %rax, %rcx
callq 0xea2f3
cmpl $0x2, %eax
jne 0xea1b0
movq %r15, %rdi
callq 0xd4d0e
jmp 0xea2a6
testl %ebp, %ebp
je 0xea2a6
xorl %ebp, %ebp
cmpb $0x1, (%r12)
movq %r12, %rax
jne 0xea1d4
xorl %ebp, %ebp
movq %r12, %rax
incl %ebp
movq 0x10(%rax), %rax
cmpb $0x1, (%rax)
je 0xea1c9
cmpq 0x110(%rbx), %rax
sete %al
testl %ebp, %ebp
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0xea229
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0xd9cf3
movq 0x8(%r12), %rsi
cmpb $0x1, (%rsi)
jne 0xea206
movq 0x8(%rsi), %rsi
cmpl $0x2, %ebp
jb 0xea21f
movq 0x10(%r12), %rax
movq 0x8(%rax), %rdx
cmpb $0x1, (%rdx)
jne 0xea221
movq 0x8(%rdx), %rdx
jmp 0xea221
xorl %edx, %edx
movq %r15, %rdi
callq 0xd5a9e
cmpl $0x1, %ebp
sete %al
movl 0xc(%rsp), %ecx
orb %al, %cl
cmpb $0x1, %cl
jne 0xea2a6
movq 0x10(%r15), %rax
cmpq 0x110(%rbx), %rax
jne 0xea2a6
cmpb $0x1, 0x24e(%rbx)
jne 0xea26f
movq 0x8(%r15), %r8
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
movl %ebp, %edx
movq %r12, %rcx
callq 0xea4ec
testb %al, %al
je 0xea26f
orb $0x10, 0x1(%r15)
cmpb $0x1, 0x24f(%rbx)
jne 0xea2a6
movq 0x8(%r15), %r8
movl $0xfffffcbc, %eax       # imm = 0xFFFFFCBC
addl 0x4(%r8), %eax
cmpw $-0x17, %ax
ja 0xea2a6
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
movl %ebp, %edx
movq %r12, %rcx
callq 0xebf54
testb %al, %al
je 0xea2a6
orb $0x10, 0x1(%r15)
movq 0x10(%rsp), %rax
cmpb $0xa, (%rax)
jne 0xea2db
movq 0x110(%rbx), %rax
movq %rax, 0x540(%rbx)
movq $0x0, (%r13)
movq 0x90(%rbx), %rax
leaq 0x8(%rax), %rcx
movq %rcx, 0x90(%rbx)
movq %r13, (%rax)
movw $0x0, 0x24e(%rbx)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq