// File: /workspace/github_c_makefile_star2_O3/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, %r13
movq %rdx, %r12
movl %esi, %ebp
movq %rdi, %rbx
movq %r8, %rsi
callq 0x39d0d
testq %rax, %rax
js 0xe17fe
je 0xe1a1b
incl 0xa88(%rbx)
jne 0xe166d
movl $0x1, 0xa88(%rbx)
incl 0xa8c(%rbx)
cmpb $0x1, (%r13)
movq %r13, %rax
jne 0xe16aa
movq %r13, %rax
movq 0x8(%rax), %rcx
cmpb $0xa, (%rcx)
je 0xe1687
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 0xe167a
cmpq 0x110(%rbx), %rax
je 0xe16cd
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 %r12, %rsi
movq %r15, %rdx
movl $0x1, %ecx
callq 0xe1b54
movl %eax, %r14d
incl 0xa88(%rbx)
jne 0xe1704
movl $0x1, 0xa88(%rbx)
incl 0xa8c(%rbx)
testb %bpl, %bpl
jne 0xe175a
cmpb $0x1, (%r13)
jne 0xe1755
movq %r13, %rax
movq 0x8(%rax), %rcx
cmpb $0x1, (%rcx)
jne 0xe174c
movq 0x10(%rcx), %rcx
cmpb $0x1, (%rcx)
jne 0xe174c
movq 0x8(%rcx), %rdi
movzbl (%rdi), %ecx
cmpl $0x1, %ecx
je 0xe173b
cmpl $0xa, %ecx
jne 0xe174c
jmp 0xe191e
movq 0x8(%rdi), %rcx
cmpq 0x17b0(%rbx), %rcx
jne 0xe191e
movq 0x10(%rax), %rax
cmpb $0x1, (%rax)
je 0xe1713
orb $0x4, 0x1(%r15)
movl %r14d, %eax
cmpl $0x2, %r14d
jb 0xe1778
orb $0x10, 0x1(%r15)
movl $0x3, %eax
cmpl $0x3, %r14d
jne 0xe1778
orb $0x10, 0x6(%r15)
movl %eax, 0x14(%rsp)
cmpb $0xa, (%r12)
movq %r12, 0x8(%rsp)
movq %r13, (%rsp)
jne 0xe1880
movl 0xa88(%rbx), %eax
movl %eax, 0x2c(%r12)
movl 0xa8c(%rbx), %eax
movq 0x8(%r12), %rcx
movq 0x20(%rcx), %rcx
movl %eax, 0xc(%rcx)
movq 0x90(%rbx), %rax
movq 0x110(%rbx), %r14
cmpq 0x98(%rbx), %rax
ja 0xe17d3
movq %rbx, %rdi
callq 0xa550
movq 0x90(%rbx), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x90(%rbx)
movq -0x8(%rax), %r13
movq $0x200001, (%r13)       # imm = 0x200001
movq %r12, 0x8(%r13)
movq %r14, 0x10(%r13)
movq %r13, 0x540(%rbx)
jmp 0xe1887
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 0x367f7(%rip), %rcx     # 0x118020
movq %rcx, 0x10(%rax)
movq $0x1f, 0x8(%rax)
xorb $0x1, %bpl
movzbl %bpl, %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
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x38dfa
movq 0x110(%rbx), %r13
movq %rbx, %rdi
movq (%rsp), %rsi
movq %r13, %rdx
callq 0xe0710
movq %rax, %r12
movq %rbx, %rdi
movq %r15, %rsi
movl $0x1, %edx
movq %rax, %rcx
callq 0xe1a2a
cmpl $0x2, %eax
jne 0xe18be
movq %r15, %rdi
callq 0xcc395
jmp 0xe19dd
cmpl $0x0, 0x14(%rsp)
je 0xe19dd
xorl %r14d, %r14d
movq (%rsp), %rax
cmpb $0x1, (%rax)
jne 0xe195d
xorl %r14d, %r14d
movq (%rsp), %rax
incl %r14d
movq 0x10(%rax), %rax
cmpb $0x1, (%rax)
je 0xe18e0
cmpq 0x110(%rbx), %rax
jne 0xe195d
movq %rbx, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0xd151a
movq (%rsp), %rax
movq 0x8(%rax), %rsi
cmpb $0x1, (%rsi)
jne 0xe1914
movq 0x8(%rsi), %rsi
cmpl $0x1, %r14d
jne 0xe1940
xorl %edx, %edx
jmp 0xe1955
xorl %eax, %eax
testl %r14d, %r14d
je 0xe1778
callq 0xd14d2
testb %al, %al
movl $0x0, %eax
je 0xe175a
jmp 0xe1778
movq (%rsp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rdx
cmpb $0x1, (%rdx)
jne 0xe1955
movq 0x8(%rdx), %rdx
movq %r15, %rdi
callq 0xcd182
cmpl $0x1, %r14d
sete %al
orb %al, %bpl
cmpb $0x1, %bpl
jne 0xe19dd
movq 0x10(%r15), %rax
cmpq 0x110(%rbx), %rax
jne 0xe19dd
cmpb $0x1, 0x24e(%rbx)
jne 0xe19a4
movq 0x8(%r15), %r8
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
movl %r14d, %edx
movq (%rsp), %rcx
callq 0xe1c1d
testb %al, %al
je 0xe19a4
orb $0x10, 0x1(%r15)
cmpb $0x1, 0x24f(%rbx)
jne 0xe19dd
movq 0x8(%r15), %r8
movl $0xfffffcbc, %eax       # imm = 0xFFFFFCBC
addl 0x4(%r8), %eax
cmpw $-0x17, %ax
ja 0xe19dd
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
movl %r14d, %edx
movq (%rsp), %rcx
callq 0xe364a
testb %al, %al
je 0xe19dd
orb $0x10, 0x1(%r15)
movq 0x8(%rsp), %rax
cmpb $0xa, (%rax)
jne 0xe1a12
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