tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] Using TCC as a backbone for our compiler


From: Basile STARYNKEVITCH
Subject: Re: [Tinycc-devel] Using TCC as a backbone for our compiler
Date: Mon, 15 Jun 2009 22:25:33 +0200
User-agent: Mozilla-Thunderbird 2.0.0.19 (X11/20090103)

Jerome St-Louis wrote:
Hi, thanks for the reply.

Of course we're considering all options, and I'll admit we're not very
familiar with any of them yet.

I was particularly fond of TCC however, and maybe the thing that
naturally brought us to TCC is the fact that we currently output
intermediate C code and uses GCC, and TCC is a lighter and smaller
alternative...
Jerome, feel free to forward this to any eC mailing list if you want.

I just downloaded ecere-sdk-0.44d1.tar.gz and tried to compile it (Debian/Sid/AMD64, Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz, 8Gb RAM)

Actually, I copied its ec-pass1.c, indent-ed it, and tried:

% time gcc-4.4 -O0 -c ec-pass1.c
ec-pass1.c:747: warning: 'struct __ecereNameSpace__ecere__com__Instance' declared inside parameter list ec-pass1.c:747: warning: its scope is only this definition or declaration, which is probably not what you want ec-pass1.c:748: warning: 'struct __ecereNameSpace__ecere__com__Instance' declared inside parameter list
ec-pass1.c: In function 'ProcessClassFunction':
ec-pass1.c:1334: warning: passing argument 2 of 'CopyList' from incompatible pointer type ec-pass1.c:1104: note: expected 'void * (*)(void *)' but argument is of type 'struct Specifier * (*)(struct Specifier *)'
ec-pass1.c: At top level:
ec-pass1.c:2257: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2259: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2261: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2263: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2265: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2266: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2267: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2268: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2270: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2272: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2274: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2276: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2278: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2280: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2282: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2284: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2286: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2288: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2290: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2291: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2293: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2295: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2297: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2299: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2301: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2302: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2304: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2306: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2308: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2310: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2312: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2314: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2316: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2318: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2320: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2439: warning: conflicting types for built-in function 'strlen'
gcc-4.4 -O0 -c ec-pass1.c  0.13s user 0.02s system 101% cpu 0.150 total


Obviously, you should hack your C code generator so that its output all the struct definition before anything else. That should not be a big deal!

I also tried
% time gcc-4.4 -O3 -Wall -c ec-pass1.c
ec-pass1.c:747: warning: 'struct __ecereNameSpace__ecere__com__Instance' declared inside parameter list ec-pass1.c:747: warning: its scope is only this definition or declaration, which is probably not what you want ec-pass1.c:748: warning: 'struct __ecereNameSpace__ecere__com__Instance' declared inside parameter list
ec-pass1.c: In function 'ProcessClassFunction':
ec-pass1.c:1334: warning: passing argument 2 of 'CopyList' from incompatible pointer type ec-pass1.c:1104: note: expected 'void * (*)(void *)' but argument is of type 'struct Specifier * (*)(struct Specifier *)'
ec-pass1.c:1137: warning: unused variable 'id'
ec-pass1.c: In function 'RegisterMembersAndProperties':
ec-pass1.c:1636: warning: format '%d' expects type 'int', but argument 3 has type 'long unsigned int' ec-pass1.c:1650: warning: implicit declaration of function '__ecereNameSpace__ecere__com__eSystem_Delete'
ec-pass1.c: At top level:
ec-pass1.c:2257: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2259: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2261: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2263: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2265: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2266: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2267: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2268: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2270: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2272: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2274: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2276: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2278: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2280: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2282: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2284: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2286: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2288: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2290: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2291: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2293: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2295: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2297: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2299: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2301: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2302: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2304: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2306: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2308: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2310: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2312: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2314: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2316: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2318: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2320: warning: 'struct Operand' declared inside parameter list
ec-pass1.c:2439: warning: conflicting types for built-in function 'strlen'
ec-pass1.c: In function 'ProcessClass':
ec-pass1.c:3200: warning: format '%d' expects type 'int', but argument 3 has type 'void *'
ec-pass1.c:3362: warning: missing braces around initializer
ec-pass1.c:3362: warning: (near initialization for 'op.<anonymous>')
ec-pass1.c: In function '__ecereRegisterModule_pass1':
ec-pass1.c:3802: warning: unused variable 'class'
gcc-4.4 -O3 -c ec-pass1.c  0.47s user 0.02s system 99% cpu 0.494 total

As you can see, -O3 compiles a lot slower than -O0!


with -O2,
gcc-4.4 -O2 -c ec-pass1.c  0.44s user 0.02s system 101% cpu 0.454 total

with -O1
gcc-4.4 -O1 -c ec-pass1.c  0.26s user 0.02s system 97% cpu 0.284 total

The printf warning should be really annoying to you! Put %ld instead of %d; that matters on 64 bits machine!


I also tried llvm-gcc; same warning since common gcc frontend. The best timings are /usr/lib/llvm/llvm/gcc-4.2/bin/llvm-gcc -O2 -c ec-pass1.c 0.26s user 0.01s system 98% cpu 0.276 total /usr/lib/llvm/llvm/gcc-4.2/bin/llvm-gcc -O3 -c ec-pass1.c 0.27s user 0.01s system 100% cpu 0.275 total


tinycc 0.0.25  fails to compile your code:
% time tcc -D__GNUC__ ec-pass1.c
ec-pass1.c:1334: cannot cast 'struct Specifier *(struct Specifier *)' to 'void **(void *)'
tcc -D__GNUC__ ec-pass1.c  0.00s user 0.00s system 0% cpu 0.002 total

I was able to patch quickly this ec-pass1.c by hand (of course I did not patch the generator) so that tcc accepts it.
And indeed the compilation time is very quick, barely measurable.

% time tcc -D__GNUC__ -c ec-pass1.c
tcc -D__GNUC__ -c ec-pass1.c  0.00s user 0.00s system 82% cpu 0.005 total


Binary sizes, as measured with size:
with tcc
  text    data     bss     dec     hex filename
 43353    2923       0   46276    b4c4 ec-pass1.o
with gcc-4.4 -O1
  text    data     bss     dec     hex filename
 20828       0      48   20876    518c ec-pass1.o
with gcc-4.4 -O2
  text    data     bss     dec     hex filename
 20884       0      48   20932    51c4 ec-pass1.o
with gcc-4.4 -O3
  text    data     bss     dec     hex filename
 21436       0      48   21484    53ec ec-pass1.o
with gcc-4.4 -Os
  text    data     bss     dec     hex filename
 18150       0      48   18198    4716 ec-pass1.o
with gcc-4.4 -O0
  text    data     bss     dec     hex filename
 28786       0      44   28830    709e ec-pass1.o

As you can see, gcc produces less code than tcc.

I actually suggest that the compiler to run on eC's generated C code should be user configurable.



However, if execution time (of the generated code) don't matters much to you, and if generation & compilation time of the generated code matters to you more, I would consider not generating C code at all, but perhaps using LLVM or Gnu Lightning or Libjit.

Perhaps even, you could have your compiler work in two different modes:

a JIT mode, perhaps using LLVM or LibJit (or libtcc if you really want). You won't even have to produce any executable binary. You could run it in the same process as your compiler.

the current AOT way of generating C code and having it compiled with gcc (or tcc if people like; I believe it should be user configurable)

Regards.

--
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***





reply via email to

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