Hi Brad,

Thank you for pointing it out - very funny.

I re-ran the test with varied compiler declares set, inspired by your test. In all cases was standard-bindings and extended-bindings on.

With safe off and interrupts off:
The u8vector-ref fx+ etc are both inlined indeed, independent of if they're ##-prefixed or not. They generate equivalent C and assembly outputs. This is the same thing as your test shows.

So this is exactly the expected behavior, it's inlined, great.

Here comes something funny:

With safe is on and interrupts off:
The only difference with the previous one in expansion, is that u8vector-length now (not ##-prefixed) now brings with it a u8vector? test call.
And here's what's funny: it appears to me that each evaluation step is made by putting on the stack, together with the host procedure's state, an instruction for the respective procedure (##u8vector-ref ##fx+ etc.) to be invoked, and then the host procedure returns.
In this mode, ##u8vector-ref ##fx+ etc. are not inlined.
There seem to be some conditions that can make the host procedure not return, but I didn't quite understand until now what happens in those cases, i.e. if some kind of jump or call to ##u8vector-ref is made directly without a return being made or alike.

This is really funny, I though just using ##-prefixes on procedures was enough for exactly those calls to be executed with the highest speed, but apparently that was not the case. I'd be interested what the motivation for this is, perhaps some kind of safety mechanism for stack overflows??

Why can't ##u8vector-ref ##fx+ etc. be inlined, wouldn't that somehow contribute??


With safe off and interrupts on:
Same as safe off and interrupts off, plus three interrupt checks.

With safe on and interrupts on:
Same as safe on and interupts off, plus six interrupt checks.


Regarding the possibility of using ##u8vector-ref for accessing arbitrary memory addresses, I'm starting to think that clearly can be done, though the details would need to be worked out. A pure ##sysmem-byte-ref would be slightly faster though, as it would not need the operation of adding together the "zeroref-u8vector"'s base address (0) with the requested offset.

Best regards,
Mikael





(In the assembly, highlighted the central loop with yellow. In the first test it's clear to me exactly which it is, in the second test it's only an approximate guess.)

First test, safe off, using procedures under their ordinary names and by their ##-prefixed names respectively, both produce equivalent C and assembly output

Code variant 1:

(declare (standard-bindings)
         (extended-bindings)
         (not interrupts-enabled)
         (not safe)
         )

(define (inc-u8v u with-what)
  (let ((l (u8vector-length u)))
    (##c-code "asm(\"noop\");")
    (##c-code "asm(\"noop\");")
    (let loop ((at 0))
      (if (fx< at l)
        (begin
          (u8vector-set! u at (fx+ (u8vector-ref u at) 123))
          (loop (fx+ at 1)))))
    (##c-code "asm(\"noop\");")
    ))

Code variant 2:

(declare (standard-bindings)
         (extended-bindings)
         (not interrupts-enabled)
         (not safe)
         )

(define (inc-u8v u with-what)
  (let ((l (u8vector-length u)))
    (##c-code "asm(\"noop\");")
    (##c-code "asm(\"noop\");")
    (let loop ((at 0))
      (if (##fx< at l)
        (begin
          (##u8vector-set! u at (##fx+ (##u8vector-ref u at) 123))
          (loop (##fx+ at 1)))))
    (##c-code "asm(\"noop\");")
    ))

Expansion:

(define inc-u8v
  (lambda (u with-what)
    (let ((l ('#<procedure #2 ##u8vector-length> u)))
      (let ((begin-temp.3 ('#<procedure #3 ##c-code> "asm(\"noop\");")))
        (let ((begin-temp.2 ('#<procedure #3 ##c-code> "asm(\"noop\");")))
          (let ((begin-temp.1
                 (letrec ((loop (lambda (u l at)
                                  (if ('#<procedure #4 ##fx<> at l)
                                      (let ((begin-temp.0 ('#<procedure #5 ##u8vector-set!> u at ('#<procedure #6 ##fx+> ('#<procedure #7 ##u8vector-ref> u at) 123))))
                                        (loop u l ('#<procedure #6 ##fx+> at 1)))
                                      #!void))))
                   (loop u l 0))))
            ('#<procedure #3 ##c-code> "asm(\"noop\");")))))))

Assembly:

        .file   "t1.c"
        .intel_syntax
        .text
        .align 2
        .type   _Z12___init_procv, @function
_Z12___init_procv:
.LFB17:
        push    %ebp
.LCFI0:
        mov     %ebp, %esp
.LCFI1:
        mov     %eax, DWORD PTR ___lp
        add     %eax, 16
        mov     DWORD PTR ___G__20_t1, %eax
        mov     %eax, DWORD PTR ___G__20_t1
        mov     DWORD PTR ___G__20_t1+4, %eax
        mov     %eax, 0
        pop     %ebp
        ret
.LFE17:
        .size   _Z12___init_procv, .-_Z12___init_procv
.globl __gxx_personality_v0
        .align 2
.globl ____20_t1
        .type   ____20_t1, @function
____20_t1:
.LFB18:
        push    %ebp
.LCFI2:
        mov     %ebp, %esp
.LCFI3:
        mov     %eax, OFFSET FLAT:___module_descr
        pop     %ebp
        ret
.LFE18:
        .size   ____20_t1, .-____20_t1
        .align 2
        .type   _Z15___H_inc_2d_u8vP25___processor_state_struct, @function
_Z15___H_inc_2d_u8vP25___processor_state_struct:
.LFB16:
        push    %ebp
.LCFI4:
        mov     %ebp, %esp
.LCFI5:
        sub     %esp, 60
.LCFI6:
        cmp     DWORD PTR [%ebp+8], 0
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L6
        mov     DWORD PTR [%ebp-60], OFFSET FLAT:_ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl
        jmp     .L8
.L6:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+24]
        mov     DWORD PTR [%ebp-48], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+8]
        mov     DWORD PTR [%ebp-44], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+36]
        mov     DWORD PTR [%ebp-40], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+40]
        mov     DWORD PTR [%ebp-36], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+44]
        mov     DWORD PTR [%ebp-32], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+48]
        mov     DWORD PTR [%ebp-28], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+52]
        mov     DWORD PTR [%ebp-24], %eax
        mov     %eax, DWORD PTR ___lp
        add     %eax, 48
        mov     DWORD PTR [%ebp-52], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+56]
        mov     DWORD PTR [%ebp-56], %eax
        mov     %eax, DWORD PTR [%ebp-56]
        add     %eax, 7
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-20], %eax
.L9:
        jmp     [DWORD PTR [%ebp-20]]
.L10:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+76]
        cmp     %eax, 2
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        jne     .L11
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-52]
        mov     DWORD PTR [%eax+60], %edx
        mov     %eax, DWORD PTR ___gstate+292
        mov     DWORD PTR [%ebp-56], %eax
        jmp     .L13
.L11:
        mov     %eax, DWORD PTR [%ebp-36]
        dec     %eax
        mov     %eax, DWORD PTR [%eax]
        shr     %eax, 8
        sal     %eax, 2
        mov     DWORD PTR [%ebp-32], %eax
#APP
        noop
        noop
#NO_APP
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 4
        mov     %edx, DWORD PTR [%ebp-40]
        mov     DWORD PTR [%eax], %edx
        mov     DWORD PTR [%ebp-28], 0
        mov     %eax, DWORD PTR [%ebp-52]
        add     %eax, 16
        mov     DWORD PTR [%ebp-40], %eax
        sub     DWORD PTR [%ebp-44], 16
        mov     %edx, DWORD PTR [%ebp-32]
        cmp     DWORD PTR [%ebp-28], %edx
        jge     .L14
.L15:
        mov     %eax, DWORD PTR [%ebp-28]
        sar     %eax, 2
        mov     %edx, %eax
        mov     %eax, DWORD PTR [%ebp-36]
        lea     %eax, [%edx+%eax]
        add     %eax, 3
        movzx   %eax, BYTE PTR [%eax]
        movzx   %eax, %al
        sal     %eax, 2
        mov     DWORD PTR [%ebp-24], %eax
        add     DWORD PTR [%ebp-24], 492
        mov     %eax, DWORD PTR [%ebp-28]
        sar     %eax, 2
        mov     %edx, %eax
        mov     %eax, DWORD PTR [%ebp-36]
        lea     %eax, [%edx+%eax]
        lea     %edx, [%eax+3]
        mov     %eax, DWORD PTR [%ebp-24]
        sar     %eax, 2
        mov     BYTE PTR [%edx], %al
        add     DWORD PTR [%ebp-28], 4
        mov     %eax, DWORD PTR [%ebp-32]
        cmp     DWORD PTR [%ebp-28], %eax
        jl      .L15
.L14:
        mov     DWORD PTR [%ebp-36], -18
        mov     %edx, DWORD PTR [%ebp-40]
        mov     DWORD PTR [%ebp-56], %edx
        jmp     .L16
.L17:
#APP
        noop
#NO_APP
        mov     %eax, DWORD PTR [%ebp-4]
        mov     DWORD PTR [%ebp-36], %eax
        add     DWORD PTR [%ebp-44], 16
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 4
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-56], %eax
.L16:
        mov     %eax, DWORD PTR [%ebp-56]
        add     %eax, 11
        mov     %eax, DWORD PTR [%eax]
        cmp     %eax, OFFSET FLAT:_Z15___H_inc_2d_u8vP25___processor_state_struct
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L13
        mov     %eax, DWORD PTR [%ebp-56]
        add     %eax, 7
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-20], %eax
        jmp     .L9
.L13:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-56]
        mov     DWORD PTR [%eax+56], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-48]
        mov     DWORD PTR [%eax+24], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-44]
        mov     DWORD PTR [%eax+8], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-40]
        mov     DWORD PTR [%eax+36], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%eax+40], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-32]
        mov     DWORD PTR [%eax+44], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-28]
        mov     DWORD PTR [%eax+48], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-24]
        mov     DWORD PTR [%eax+52], %edx
        mov     %eax, DWORD PTR [%ebp-56]
        mov     DWORD PTR [%ebp-60], %eax
.L8:
        mov     %eax, DWORD PTR [%ebp-60]
        leave
        ret
.LFE16:
        .size   _Z15___H_inc_2d_u8vP25___processor_state_struct, .-_Z15___H_inc_2d_u8vP25___processor_state_struct
        .align 2
        .type   _Z11___H__20_t1P25___processor_state_struct, @function
_Z11___H__20_t1P25___processor_state_struct:
.LFB15:
        push    %ebp
.LCFI7:
        mov     %ebp, %esp
.LCFI8:
        sub     %esp, 20
.LCFI9:
        cmp     DWORD PTR [%ebp+8], 0
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L21
        mov     DWORD PTR [%ebp-20], OFFSET FLAT:_ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl
        jmp     .L23
.L21:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+36]
        mov     DWORD PTR [%ebp-8], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+40]
        mov     DWORD PTR [%ebp-4], %eax
        mov     %eax, DWORD PTR ___lp
        add     %eax, 16
        mov     DWORD PTR [%ebp-12], %eax
.L24:
.L25:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+76]
        test    %eax, %eax
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        jne     .L26
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-12]
        mov     DWORD PTR [%eax+60], %edx
        mov     %eax, DWORD PTR ___gstate+292
        mov     DWORD PTR [%ebp-16], %eax
        jmp     .L28
.L26:
        mov     %eax, DWORD PTR [%ebp-12]
        add     %eax, 32
        mov     DWORD PTR ___G_inc_2d_u8v, %eax
        mov     DWORD PTR [%ebp-4], -18
        mov     %edx, DWORD PTR [%ebp-8]
        mov     DWORD PTR [%ebp-16], %edx
.L29:
        mov     %eax, DWORD PTR [%ebp-16]
        add     %eax, 11
        mov     %eax, DWORD PTR [%eax]
        cmp     %eax, OFFSET FLAT:_Z11___H__20_t1P25___processor_state_struct
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L28
        jmp     .L24
.L28:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-16]
        mov     DWORD PTR [%eax+56], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-4]
        mov     DWORD PTR [%eax+40], %edx
        mov     %eax, DWORD PTR [%ebp-16]
        mov     DWORD PTR [%ebp-20], %eax
.L23:
        mov     %eax, DWORD PTR [%ebp-20]
        leave
        ret
.LFE15:
        .size   _Z11___H__20_t1P25___processor_state_struct, .-_Z11___H__20_t1P25___processor_state_struct
        .section        .rodata
.LC0:
        .string " t1"
        .data
        .align 32
        .type   ___module_descr, @object
        .size   ___module_descr, 136
___module_descr:
        .long   406002
        .long   0
        .long   .LC0
        .long   1
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   ___lp
        .long   ___lbl_tbl
        .long   5
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   _Z12___init_procv
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .local  ___lp
        .comm   ___lp,4,4
        .align 4
        .type   _ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl, @object
        .size   _ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl, 16
_ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl:
        .long   0
        .long   .L10
        .long   .L17
        .long   0
        .align 4
        .type   _ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl, @object
        .size   _ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl, 12
_ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl:
        .long   0
        .long   .L25
        .long   0
        .align 32
        .type   ___lbl_tbl, @object
        .size   ___lbl_tbl, 96
___lbl_tbl:
        .long   1030
        .long   -2
        .long   .LC0
        .long   0
        .long   118
        .long   0
        .long   0
        .long   _Z11___H__20_t1P25___processor_state_struct
        .long   2054
        .long   -2
        .long   0
        .long   0
        .long   630
        .long   0
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   4101
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   0
        .long   0
        .long   0
        .long   0
        .ident  "GCC: (GNU) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)"
        .section        .note.GNU-stack,"",@progbits










Second test, safe is on, using ##-prefixed procedure name variants

Code:

(declare (standard-bindings)
         (extended-bindings)
         (not interrupts-enabled)
         ; (not safe)
         )

(define (inc-u8v u with-what)
  (let ((l (u8vector-length u)))
    (##c-code "asm(\"noop\");")
    (##c-code "asm(\"noop\");")
    (let loop ((at 0))
      (if (##fx< at l)
        (begin
          (##u8vector-set! u at (##fx+ (##u8vector-ref u at) 123))
          (loop (##fx+ at 1)))))
    (##c-code "asm(\"noop\");")
    ))


Expansion:

(define inc-u8v
  (lambda (u with-what)
    (let ((l (if ('#<procedure #2 ##u8vector?> u) ('#<procedure #3 ##u8vector-length> u) ('#<procedure #4 u8vector-length> u))))
      (let ((begin-temp.3 ('#<procedure #5 ##c-code> "asm(\"noop\");")))
        (let ((begin-temp.2 ('#<procedure #5 ##c-code> "asm(\"noop\");")))
          (let ((begin-temp.1
                 (letrec ((loop (lambda (u l at)
                                  (if ('#<procedure #6 ##fx<> at l)
                                      (let ((begin-temp.0 ('#<procedure #7 ##u8vector-set!> u at ('#<procedure #8 ##fx+> ('#<procedure #9 ##u8vector-ref> u at) 123))))
                                        (loop u l ('#<procedure #8 ##fx+> at 1)))
                                      #!void))))
                   (loop u l 0))))
            ('#<procedure #5 ##c-code> "asm(\"noop\");")))))))

Assembly:

        .file   "t1.c"
        .intel_syntax
        .text
        .align 2
        .type   _Z12___init_procv, @function
_Z12___init_procv:
.LFB17:
        push    %ebp
.LCFI0:
        mov     %ebp, %esp
.LCFI1:
        mov     %eax, DWORD PTR ___lp
        add     %eax, 16
        mov     DWORD PTR ___G__20_t1, %eax
        mov     %eax, DWORD PTR ___G__20_t1
        mov     DWORD PTR ___G__20_t1+4, %eax
        mov     %eax, 0
        pop     %ebp
        ret
.LFE17:
        .size   _Z12___init_procv, .-_Z12___init_procv
.globl __gxx_personality_v0
        .align 2
.globl ____20_t1
        .type   ____20_t1, @function
____20_t1:
.LFB18:
        push    %ebp
.LCFI2:
        mov     %ebp, %esp
.LCFI3:
        mov     %eax, OFFSET FLAT:___module_descr
        pop     %ebp
        ret
.LFE18:
        .size   ____20_t1, .-____20_t1
        .align 2
        .type   _Z15___H_inc_2d_u8vP25___processor_state_struct, @function
_Z15___H_inc_2d_u8vP25___processor_state_struct:
.LFB16:
        push    %ebp
.LCFI4:
        mov     %ebp, %esp
.LCFI5:
        sub     %esp, 68
.LCFI6:
        cmp     DWORD PTR [%ebp+8], 0
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L6
        mov     DWORD PTR [%ebp-68], OFFSET FLAT:_ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl
        jmp     .L8
.L6:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+24]
        mov     DWORD PTR [%ebp-48], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+8]
        mov     DWORD PTR [%ebp-44], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+36]
        mov     DWORD PTR [%ebp-40], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+40]
        mov     DWORD PTR [%ebp-36], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+44]
        mov     DWORD PTR [%ebp-32], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+48]
        mov     DWORD PTR [%ebp-28], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+52]
        mov     DWORD PTR [%ebp-24], %eax
        mov     %eax, DWORD PTR ___lp
        add     %eax, 48
        mov     DWORD PTR [%ebp-56], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+56]
        mov     DWORD PTR [%ebp-60], %eax
        mov     %eax, DWORD PTR [%ebp-60]
        add     %eax, 7
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-20], %eax
.L9:
        jmp     [DWORD PTR [%ebp-20]]
.L10:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+76]
        cmp     %eax, 2
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        jne     .L11
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-56]
        mov     DWORD PTR [%eax+60], %edx
        mov     %eax, DWORD PTR ___gstate+292
        mov     DWORD PTR [%ebp-60], %eax
        jmp     .L13
.L11:
        mov     %edx, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%ebp-52], %edx
        mov     %eax, DWORD PTR [%ebp-52]
        and     %eax, 3
        cmp     %eax, 1
        jne     .L14
        mov     %eax, DWORD PTR [%ebp-52]
        dec     %eax
        mov     %eax, DWORD PTR [%eax]
        and     %eax, 248
        cmp     %eax, 168
        je      .L16
.L14:
        mov     BYTE PTR [%ebp-61], 1
        jmp     .L17
.L16:
        mov     BYTE PTR [%ebp-61], 0
.L17:
        movzx   %eax, BYTE PTR [%ebp-61]
        test    %al, %al
        jne     .L18
        mov     %eax, DWORD PTR [%ebp-36]
        dec     %eax
        mov     %eax, DWORD PTR [%eax]
        shr     %eax, 8
        sal     %eax, 2
        mov     DWORD PTR [%ebp-32], %eax
        jmp     .L20
.L21:
        mov     %eax, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%ebp-32], %eax
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 24
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-36], %eax
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 28
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-40], %eax
        add     DWORD PTR [%ebp-44], 32
.L20:
#APP
        noop
        noop
#NO_APP
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 4
        mov     %edx, DWORD PTR [%ebp-40]
        mov     DWORD PTR [%eax], %edx
        mov     DWORD PTR [%ebp-28], 0
        mov     %eax, DWORD PTR [%ebp-56]
        add     %eax, 112
        mov     DWORD PTR [%ebp-40], %eax
        sub     DWORD PTR [%ebp-44], 16
.L22:
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 4
        mov     %edx, DWORD PTR [%ebp-40]
        mov     DWORD PTR [%eax], %edx
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 8
        mov     %edx, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%eax], %edx
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 12
        mov     %edx, DWORD PTR [%ebp-32]
        mov     DWORD PTR [%eax], %edx
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 16
        mov     %edx, DWORD PTR [%ebp-28]
        mov     DWORD PTR [%eax], %edx
        mov     %eax, DWORD PTR [%ebp-28]
        mov     DWORD PTR [%ebp-36], %eax
        mov     %edx, DWORD PTR [%ebp-56]
        add     %edx, 32
        mov     DWORD PTR [%ebp-40], %edx
        sub     DWORD PTR [%ebp-44], 32
        mov     %eax, DWORD PTR [%ebp+8]
        mov     DWORD PTR [%eax+76], 2
        mov     %eax, DWORD PTR ___G__23__23_fx_3c_+4
        mov     DWORD PTR [%ebp-60], %eax
        jmp     .L23
.L24:
        cmp     DWORD PTR [%ebp-36], -2
        je      .L25
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 16
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-32], %eax
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 24
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-36], %eax
        mov     %edx, DWORD PTR [%ebp-56]
        add     %edx, 48
        mov     DWORD PTR [%ebp-40], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     DWORD PTR [%eax+76], 2
        mov     %eax, DWORD PTR ___G__23__23_u8vector_2d_ref+4
        mov     DWORD PTR [%ebp-60], %eax
        jmp     .L23
.L27:
        mov     DWORD PTR [%ebp-32], 492
        mov     %edx, DWORD PTR [%ebp-56]
        add     %edx, 64
        mov     DWORD PTR [%ebp-40], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     DWORD PTR [%eax+76], 2
        mov     %eax, DWORD PTR ___G__23__23_fx_2b_+4
        mov     DWORD PTR [%ebp-60], %eax
        jmp     .L23
.L28:
        mov     %edx, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%ebp-28], %edx
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 16
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-32], %eax
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 24
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-36], %eax
        mov     %eax, DWORD PTR [%ebp-56]
        add     %eax, 80
        mov     DWORD PTR [%ebp-40], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     DWORD PTR [%eax+76], 3
        mov     %edx, DWORD PTR ___G__23__23_u8vector_2d_set_21_+4
        mov     DWORD PTR [%ebp-60], %edx
        jmp     .L23
.L29:
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 16
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-36], %eax
        mov     DWORD PTR [%ebp-32], 4
        mov     %eax, DWORD PTR [%ebp-56]
        add     %eax, 96
        mov     DWORD PTR [%ebp-40], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     DWORD PTR [%eax+76], 2
        mov     %edx, DWORD PTR ___G__23__23_fx_2b_+4
        mov     DWORD PTR [%ebp-60], %edx
        jmp     .L23
.L30:
        mov     %eax, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%ebp-28], %eax
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 20
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-32], %eax
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 24
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-36], %eax
        mov     %eax, DWORD PTR [%ebp-44]
        add     %eax, 28
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-40], %eax
        add     DWORD PTR [%ebp-44], 32
        jmp     .L22
.L25:
        mov     DWORD PTR [%ebp-36], -18
        add     DWORD PTR [%ebp-44], 32
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 4
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-60], %eax
        jmp     .L23
.L31:
#APP
        noop
#NO_APP
        mov     %edx, DWORD PTR [%ebp-4]
        mov     DWORD PTR [%ebp-36], %edx
        add     DWORD PTR [%ebp-44], 16
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 4
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-60], %eax
        jmp     .L23
.L18:
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 4
        mov     %edx, DWORD PTR [%ebp-40]
        mov     DWORD PTR [%eax], %edx
        mov     %eax, DWORD PTR [%ebp-44]
        sub     %eax, 8
        mov     %edx, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%eax], %edx
        mov     %eax, DWORD PTR [%ebp-56]
        add     %eax, 16
        mov     DWORD PTR [%ebp-40], %eax
        sub     DWORD PTR [%ebp-44], 32
        mov     %eax, DWORD PTR [%ebp+8]
        mov     DWORD PTR [%eax+76], 1
        mov     %edx, DWORD PTR ___G_u8vector_2d_length+4
        mov     DWORD PTR [%ebp-60], %edx
.L23:
        mov     %eax, DWORD PTR [%ebp-60]
        add     %eax, 11
        mov     %eax, DWORD PTR [%eax]
        cmp     %eax, OFFSET FLAT:_Z15___H_inc_2d_u8vP25___processor_state_struct
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L13
        mov     %eax, DWORD PTR [%ebp-60]
        add     %eax, 7
        mov     %eax, DWORD PTR [%eax]
        mov     DWORD PTR [%ebp-20], %eax
        jmp     .L9
.L13:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-60]
        mov     DWORD PTR [%eax+56], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-48]
        mov     DWORD PTR [%eax+24], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-44]
        mov     DWORD PTR [%eax+8], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-40]
        mov     DWORD PTR [%eax+36], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-36]
        mov     DWORD PTR [%eax+40], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-32]
        mov     DWORD PTR [%eax+44], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-28]
        mov     DWORD PTR [%eax+48], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-24]
        mov     DWORD PTR [%eax+52], %edx
        mov     %eax, DWORD PTR [%ebp-60]
        mov     DWORD PTR [%ebp-68], %eax
.L8:
        mov     %eax, DWORD PTR [%ebp-68]
        leave
        ret
.LFE16:
        .size   _Z15___H_inc_2d_u8vP25___processor_state_struct, .-_Z15___H_inc_2d_u8vP25___processor_state_struct
        .align 2
        .type   _Z11___H__20_t1P25___processor_state_struct, @function
_Z11___H__20_t1P25___processor_state_struct:
.LFB15:
        push    %ebp
.LCFI7:
        mov     %ebp, %esp
.LCFI8:
        sub     %esp, 20
.LCFI9:
        cmp     DWORD PTR [%ebp+8], 0
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L35
        mov     DWORD PTR [%ebp-20], OFFSET FLAT:_ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl
        jmp     .L37
.L35:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+36]
        mov     DWORD PTR [%ebp-8], %eax
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+40]
        mov     DWORD PTR [%ebp-4], %eax
        mov     %eax, DWORD PTR ___lp
        add     %eax, 16
        mov     DWORD PTR [%ebp-12], %eax
.L38:
.L39:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %eax, DWORD PTR [%eax+76]
        test    %eax, %eax
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        jne     .L40
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-12]
        mov     DWORD PTR [%eax+60], %edx
        mov     %eax, DWORD PTR ___gstate+292
        mov     DWORD PTR [%ebp-16], %eax
        jmp     .L42
.L40:
        mov     %eax, DWORD PTR [%ebp-12]
        add     %eax, 32
        mov     DWORD PTR ___G_inc_2d_u8v, %eax
        mov     DWORD PTR [%ebp-4], -18
        mov     %edx, DWORD PTR [%ebp-8]
        mov     DWORD PTR [%ebp-16], %edx
.L43:
        mov     %eax, DWORD PTR [%ebp-16]
        add     %eax, 11
        mov     %eax, DWORD PTR [%eax]
        cmp     %eax, OFFSET FLAT:_Z11___H__20_t1P25___processor_state_struct
        sete    %al
        movzx   %eax, %al
        test    %eax, %eax
        je      .L42
        jmp     .L38
.L42:
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-16]
        mov     DWORD PTR [%eax+56], %edx
        mov     %eax, DWORD PTR [%ebp+8]
        mov     %edx, DWORD PTR [%ebp-4]
        mov     DWORD PTR [%eax+40], %edx
        mov     %eax, DWORD PTR [%ebp-16]
        mov     DWORD PTR [%ebp-20], %eax
.L37:
        mov     %eax, DWORD PTR [%ebp-20]
        leave
        ret
.LFE15:
        .size   _Z11___H__20_t1P25___processor_state_struct, .-_Z11___H__20_t1P25___processor_state_struct
        .section        .rodata
.LC0:
        .string " t1"
        .data
        .align 32
        .type   ___module_descr, @object
        .size   ___module_descr, 136
___module_descr:
        .long   406002
        .long   0
        .long   .LC0
        .long   1
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   ___lp
        .long   ___lbl_tbl
        .long   11
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   _Z12___init_procv
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .long   0
        .local  ___lp
        .comm   ___lp,4,4
        .align 32
        .type   _ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl, @object
        .size   _ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl, 40
_ZZ15___H_inc_2d_u8vP25___processor_state_structE11___hlbl_tbl:
        .long   0
        .long   .L10
        .long   .L21
        .long   .L24
        .long   .L27
        .long   .L28
        .long   .L29
        .long   .L30
        .long   .L31
        .long   0
        .align 4
        .type   _ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl, @object
        .size   _ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl, 12
_ZZ11___H__20_t1P25___processor_state_structE11___hlbl_tbl:
        .long   0
        .long   .L39
        .long   0
        .align 32
        .type   ___lbl_tbl, @object
        .size   ___lbl_tbl, 192
___lbl_tbl:
        .long   1030
        .long   -2
        .long   .LC0
        .long   0
        .long   118
        .long   0
        .long   0
        .long   _Z11___H__20_t1P25___processor_state_struct
        .long   8198
        .long   -2
        .long   0
        .long   0
        .long   630
        .long   0
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   12309
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   61461
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   61461
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   61461
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   61461
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   28693
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   3198
        .long   4101
        .long   0
        .long   _Z15___H_inc_2d_u8vP25___processor_state_struct
        .long   0
        .long   0
        .long   0
        .long   0
        .ident  "GCC: (GNU) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)"
        .section        .note.GNU-stack,"",@progbits




2012/8/9 Bradley Lucier <lucier@math.purdue.edu>
I don't know what you want to do, but this code:

(declare (standard-bindings)
(extended-bindings)
(not interrupts-enabled)
(not safe))

(define (u8transfer in out)
  (do ((i (fx- (u8vector-length in) 1)  (fx- i 1)))
      ((fx< i 0))
    (u8vector-set! out i (u8vector-ref in i))))

expands to

[Bradley-Luciers-MacBook-Pro:~/Downloads] lucier% gsc -cc-options "-save-temps" -keep-c -expansion fxtest.scm
Expansion:

(define u8transfer
  (lambda (in out)
    (letrec ((do-temp.0
              (lambda (in out i)
                (if ('#<procedure #2 ##fx<> i 0)
                    #!void
                    (let ((begin-temp.1 ('#<procedure #3 ##u8vector-set!> out i ('#<procedure #4 ##u8vector-ref> in i))))
                      (do-temp.0 in out ('#<procedure #5 ##fx-> i 1)))))))
      (let ((i ('#<procedure #5 ##fx-> ('#<procedure #6 ##u8vector-length> in) 1)))
        (if ('#<procedure #2 ##fx<> i 0)
            #!void
            (let ((begin-temp.1 ('#<procedure #3 ##u8vector-set!> out i ('#<procedure #4 ##u8vector-ref> in i))))
              (do-temp.0 in out ('#<procedure #5 ##fx-> i 1))))))))

and the inner loop is

L14:
        movq    %rdx, %rax
        sarq    $2, %rax
        subq    $4, %rdx
        movzbl  7(%rsi,%rax), %ecx
        leaq    0(,%rcx,4), %r8
        movb    %cl, 7(%r9,%rax)
        jns     L14

which seems to have about 1 extra instruction (I don't know what the load effective address is doing there).

Brad