[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Axiom-developer] Re: lsp/Makefile.pamphlet
From: |
Camm Maguire |
Subject: |
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
- [Axiom-developer] RE: lsp/Makefile.pamphlet, Page, Bill, 2004/12/15
- [Axiom-developer] RE: lsp/Makefile.pamphlet, Page, Bill, 2004/12/15
- [Axiom-developer] Re: lsp/Makefile.pamphlet, root, 2004/12/15
- [Axiom-developer] Re: lsp/Makefile.pamphlet, root, 2004/12/15
- Re: [Axiom-developer] Re: lsp/Makefile.pamphlet, Camm Maguire, 2004/12/16
- Re: [Axiom-developer] Re: lsp/Makefile.pamphlet, root, 2004/12/16
- Re: [Axiom-developer] Re: lsp/Makefile.pamphlet, Camm Maguire, 2004/12/17
- Re: [Axiom-developer] Re: lsp/Makefile.pamphlet, root, 2004/12/17
- [Axiom-developer] possible GCL 2.6.6, Camm Maguire, 2004/12/20
- [Axiom-developer] Re: possible GCL 2.6.6, root, 2004/12/20