gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] Re: [Axiom-developer] Re: lsp/Makefile.pamphlet


From: Camm Maguire
Subject: [Gcl-devel] Re: [Axiom-developer] Re: lsp/Makefile.pamphlet
Date: 15 Dec 2004 10:28:50 -0500
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings!

root <address@hidden> writes:

> Bill,
> 
> I had a few typos in that Makefile.pamphlet for the windows patches
> which I've now fixed. They should be on arch shortly.
> 
> In GCL if you have exact type information the function calling
> can be reduced by quite a few instructions (possibly by 100
> instructions or more if memory serves me). Normal function 
> calling has to do type-casing. The exact type information allows
> a good lisp implementation to elide this.

There are actually two issue here, argument type and number checking,
and passing arguments via the lisp stack.  Passing arguments, even if
untyped, via the C stack is much faster.  All the better of course if
you can type the arguments too.  The beauty of GCL's fast-link
mechanism, is, IMHO, that you can have your cake and eat it too --
when enabled, you get function calling at C speed via a function
pointer, when disabled, you can push the arguments to the lisp stack
for inspection via the lisp debugger.  

It appears that the code for this has evolved somewhat over time.
Tim's memory might be the best archive left in this world :-).  There
should be no reason, AFAICT, that any function should not at least be
proclaimed with generic object arguments at compile time to enable the
fast-linking function format, though it is still necessary at present
to either do this by hand or run the automatic sys-proclaims
generation as a separate step.  The latter will always be more
efficient than a 'proclaim-as-you-go' strategy, as all such
information will be present at the beginning.  But the two are not
incompatible, and the former will transparently catch many of the most
common cases where all calls are within the same file.  This should at
least straighten out certain long-standing misconceptions when
benchmarking GCL, as it has been difficult for me to impress upon the
benchmarker that GCL has been designed with the assumption that the
sys-proclaims would be autogenerated before compilation for maximum
efficiency.

I'd like to put something like this in to 2.7.0 time permitting.  Also
on the agenda is typed optional argument passing, and tail recursion
to functions with optional arguments. 

> 
> The best way to see this is to run disassemble on the function
> before and after. I did a lot of this with the AKCL and CMUCL
> implementations. In fact, CMUCL was so good that I could get
> 
> (+ a b)
> 
> to reduce to one instruction on the IBM RT with proper declarations.
> Of course you have to declare it something like:
> 
> (the fixnum (+ (the fixnum a) (the fixnum b))) 
> 

With Pauls' help, and with the help of his fantastic random compiler
tester, we've been putting in automatic type propagation into CVS
head.  For example:

COMPILER>(defun foo (x y) (declare ((integer -1000 1000) x y)) (+ x (* 2 y) (* 
3 (1+ (+ x y))) (- (max 4 y) (- 2 x y))))

FOO

COMPILER>(disassemble 'foo)

Compiling gazonk0.lsp.

;; Note: var #:G3288 is type (INTEGER -1000 1000) from outer scope, declaring

;; Note: var #:G3289 is type (INTEGER -2000 2000) from deduced function return 
type, declaring

;; Note: var #:G3290 is type (INTEGER -5997 6003) from deduced function return 
type, declaring

;; Note: var #:G3291 is type (INTEGER -1998 2998) from deduced function return 
type, declaring

;; Note: Let* bindings ((#:G3288 X) (#:G3289 (* 2 Y))
                        (#:G3290 (* 3 (1+ (+ X Y))))
                        (#:G3291 (- (MAX 4 Y) (- 2 X Y)))) declared (((INTEGER
                                                                       -1000
                                                                       1000)
                                                                      #:G3288)
                                                                     ((INTEGER
                                                                       -2000
                                                                       2000)
                                                                      #:G3289)
                                                                     ((INTEGER
                                                                       -5997
                                                                       6003)
                                                                      #:G3290)
                                                                     ((INTEGER
                                                                       -1998
                                                                       2998)
                                                                      #:G3291))
End of Pass 1.  
End of Pass 2.  
OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3, (Debug 
quality ignored)
Finished compiling gazonk0.lsp.

#include "gazonk0.h"
void init_code(){do_init(VV);}
/*      function definition for FOO     */

static void L1()
{register object *base=vs_base;
        register object *sup=base+VM1; VC1
        vs_check;
        {long V1;
        register long V2;
        V1=fix(base[0]);
        V2=fix(base[1]);
        vs_top=sup;
        goto TTL;
TTL:;
        {long V3;
        long V4;
        long V5;
        long V6;
        V3= V1;
        V4= (fixnum)((fixnum)2)*(V2);
        V5= (fixnum)((fixnum)3)*((fixnum)((fixnum)(V1)+(V2))+((fixnum)1));
        {long V7= (fixnum)(((fixnum)4)>=(V2)?((fixnum)4):V2);
        V6= (fixnum)(/* INLINE-ARGS 
*/V7)-((fixnum)((fixnum)2)-((fixnum)(V1)+(V2)));}
        base[2]= CMPmake_fixnum((long)((fixnum)((fixnum)(V3)+(V4))+(V5))+(V6));
        vs_top=(vs_base=base+2)+1;
        return;}
        }
}
       
#(
#((system::%init . #((system::mf (lisp::quote compiler::foo) 0) 
(system::debugger (lisp::quote compiler::foo) (lisp::quote (compiler::x 
compiler::y))))))
)

static void L1();
#define VC1
#define VM1 3
static char * VVi[1]={
#define Cdata VV[0]
(char *)(L1)
};
#define VV ((object *)VVi)

gazonk0.o:     file format elf32-i386

Disassembly of section .text:

00000000 <L1>:
L1():
   0:   83 ec 1c                sub    $0x1c,%esp
   3:   8b 15 00 00 00 00       mov    0x0,%edx
   9:   39 15 00 00 00 00       cmp    %edx,0x0
   f:   89 5c 24 0c             mov    %ebx,0xc(%esp)
  13:   8b 1d 00 00 00 00       mov    0x0,%ebx
  19:   89 6c 24 18             mov    %ebp,0x18(%esp)
  1d:   89 74 24 10             mov    %esi,0x10(%esp)
  21:   8d 6b 0c                lea    0xc(%ebx),%ebp
  24:   89 7c 24 14             mov    %edi,0x14(%esp)
  28:   0f 83 82 00 00 00       jae    b0 <L1+0xb0>
  2e:   8b 33                   mov    (%ebx),%esi
  30:   8b 4b 04                mov    0x4(%ebx),%ecx
  33:   8b 56 04                mov    0x4(%esi),%edx
  36:   8b 41 04                mov    0x4(%ecx),%eax
  39:   89 2d 00 00 00 00       mov    %ebp,0x0
  3f:   8d 0c 10                lea    (%eax,%edx,1),%ecx
  42:   83 f8 04                cmp    $0x4,%eax
  45:   8d 3c 00                lea    (%eax,%eax,1),%edi
  48:   8d 74 49 03             lea    0x3(%ecx,%ecx,2),%esi
  4c:   7d 05                   jge    53 <L1+0x53>
  4e:   b8 04 00 00 00          mov    $0x4,%eax
  53:   01 fa                   add    %edi,%edx
  55:   8d 44 01 fe             lea    0xfffffffe(%ecx,%eax,1),%eax
  59:   01 f2                   add    %esi,%edx
  5b:   01 c2                   add    %eax,%edx
  5d:   8d 82 00 04 00 00       lea    0x400(%edx),%eax
  63:   89 15 00 00 00 00       mov    %edx,0x0
  69:   a9 00 f8 ff ff          test   $0xfffff800,%eax
  6e:   8d 0c d5 00 20 00 00    lea    0x2000(,%edx,8),%ecx
  75:   75 29                   jne    a0 <L1+0xa0>
  77:   89 4b 08                mov    %ecx,0x8(%ebx)
  7a:   8d 53 08                lea    0x8(%ebx),%edx
  7d:   8b 74 24 10             mov    0x10(%esp),%esi
  81:   89 2d 00 00 00 00       mov    %ebp,0x0
  87:   8b 5c 24 0c             mov    0xc(%esp),%ebx
  8b:   8b 7c 24 14             mov    0x14(%esp),%edi
  8f:   89 15 00 00 00 00       mov    %edx,0x0
  95:   8b 6c 24 18             mov    0x18(%esp),%ebp
  99:   83 c4 1c                add    $0x1c,%esp
  9c:   c3                      ret    
  9d:   8d 76 00                lea    0x0(%esi),%esi
  a0:   89 14 24                mov    %edx,(%esp)
  a3:   e8 fc ff ff ff          call   a4 <L1+0xa4>
  a8:   89 c1                   mov    %eax,%ecx
  aa:   eb cb                   jmp    77 <L1+0x77>
  ac:   8d 74 26 00             lea    0x0(%esi),%esi
  b0:   e8 fc ff ff ff          call   b1 <L1+0xb1>
  b5:   e9 74 ff ff ff          jmp    2e <L1+0x2e>
  ba:   8d b6 00 00 00 00       lea    0x0(%esi),%esi

000000c0 <init_code>:
init_code():
  c0:   83 ec 0c                sub    $0xc,%esp
  c3:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  ca:   e8 fc ff ff ff          call   cb <init_code+0xb>
  cf:   83 c4 0c                add    $0xc,%esp
  d2:   c3                      ret    
T

COMPILER>(proclaim '(ftype (function (fixnum fixnum) fixnum) foo))

NIL

COMPILER>(disassemble 'foo)

Compiling gazonk0.lsp.

;; Note: var #:G3301 is type (INTEGER -1000 1000) from outer scope, declaring

;; Note: var #:G3302 is type (INTEGER -2000 2000) from deduced function return 
type, declaring

;; Note: var #:G3303 is type (INTEGER -5997 6003) from deduced function return 
type, declaring

;; Note: var #:G3304 is type (INTEGER -1998 2998) from deduced function return 
type, declaring

;; Note: Let* bindings ((#:G3301 X) (#:G3302 (* 2 Y))
                        (#:G3303 (* 3 (1+ (+ X Y))))
                        (#:G3304 (- (MAX 4 Y) (- 2 X Y)))) declared (((INTEGER
                                                                       -1000
                                                                       1000)
                                                                      #:G3301)
                                                                     ((INTEGER
                                                                       -2000
                                                                       2000)
                                                                      #:G3302)
                                                                     ((INTEGER
                                                                       -5997
                                                                       6003)
                                                                      #:G3303)
                                                                     ((INTEGER
                                                                       -1998
                                                                       2998)
                                                                      #:G3304))
End of Pass 1.  
End of Pass 2.  
OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3, (Debug 
quality ignored)
Finished compiling gazonk0.lsp.

#include "gazonk0.h"
void init_code(){do_init(VV);}
/*      local entry for function FOO    */

static object LI1(V3,V4)

long V3;register long V4;
{        VMB1 VMS1 VMV1
        goto TTL;
TTL:;
        {long V5;
        long V6;
        long V7;
        long V8;
        V5= V3;
        V6= (fixnum)((fixnum)2)*(V4);
        V7= (fixnum)((fixnum)3)*((fixnum)((fixnum)(V3)+(V4))+((fixnum)1));
        {long V9= (fixnum)(((fixnum)4)>=(V4)?((fixnum)4):V4);
        V8= (fixnum)(/* INLINE-ARGS 
*/V9)-((fixnum)((fixnum)2)-((fixnum)(V3)+(V4)));}
        {long V10 = (fixnum)((fixnum)((fixnum)(V5)+(V6))+(V7))+(V8);
        VMR1((object)V10)}}
}
       
#(
#((system::%init . #((system::mfsfun (lisp::quote compiler::foo) 0 20738))))
)

static object LI1();
#define VMB1
#define VMS1
#define VMV1
#define VMR1(VMT1) return(VMT1);
#define VM1 0
static char * VVi[1]={
#define Cdata VV[0]
(char *)(LI1)
};
#define VV ((object *)VVi)

gazonk0.o:     file format elf32-i386

Disassembly of section .text:

00000000 <init_code>:
init_code():
   0:   83 ec 0c                sub    $0xc,%esp
   3:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
   a:   e8 fc ff ff ff          call   b <init_code+0xb>
   f:   83 c4 0c                add    $0xc,%esp
  12:   c3                      ret    
  13:   8d b6 00 00 00 00       lea    0x0(%esi),%esi
  19:   8d bc 27 00 00 00 00    lea    0x0(%edi),%edi

00000020 <LI1>:
LI1():
  20:   83 ec 08                sub    $0x8,%esp
  23:   8b 44 24 10             mov    0x10(%esp),%eax
  27:   89 74 24 04             mov    %esi,0x4(%esp)
  2b:   8b 74 24 0c             mov    0xc(%esp),%esi
  2f:   83 f8 04                cmp    $0x4,%eax
  32:   89 1c 24                mov    %ebx,(%esp)
  35:   8d 14 30                lea    (%eax,%esi,1),%edx
  38:   8d 1c 00                lea    (%eax,%eax,1),%ebx
  3b:   8d 4c 52 03             lea    0x3(%edx,%edx,2),%ecx
  3f:   7d 05                   jge    46 <LI1+0x26>
  41:   b8 04 00 00 00          mov    $0x4,%eax
  46:   8d 54 02 fe             lea    0xfffffffe(%edx,%eax,1),%edx
  4a:   8d 04 33                lea    (%ebx,%esi,1),%eax
  4d:   8b 1c 24                mov    (%esp),%ebx
  50:   8b 74 24 04             mov    0x4(%esp),%esi
  54:   01 c8                   add    %ecx,%eax
  56:   01 d0                   add    %edx,%eax
  58:   83 c4 08                add    $0x8,%esp
  5b:   c3                      ret    
T

COMPILER>

> or some such. I believe some of the macros I wrote do a lot of
> this kind of expansion. I also load proclaims.lisp into the image
> so GCL function type information is available. 
> 
> Schelter and I worked quite a bit on speeding up function calling
> as much as possible. If I remember correctly the fast-links code
> will trade space (a link) for speedup.

I think the major tradeoff with fast-linking is that one has no
debugging information via the lisp stack.  Amazingly, this can be
toggled at runtime.

> 
> If you look in src/boot you'll see a newly created file called
> boot-proclaims.lisp which is part of my recent efforts to optimize
> the system. I plan to push it as far as I can. Eventually the 
> makefiles will automatically re-compile the lisp code to get the
> optimization information and type optimization will be pushed
> into the algebra code. I'm just not there yet.
> 

I think the Debian package does the extra pass now -- when this
changes in the official tree, please let me know so I can remove the
extra pass here.

Take care,

> t
> 
> 
> _______________________________________________
> Axiom-developer mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/axiom-developer
> 
> 
> 

-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

[Prev in Thread] Current Thread [Next in Thread]