A new well-known compiler

Since we do not have native C compilers on the Oric, this forum will be mostly be used by people using CC65 or the OSDK. But any general C related post will be welcome !
User avatar
Dbug
Site Admin
Posts: 3751
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: A new well-known compiler

Post by Dbug »

I will not answer to all the comments, but I want to start by two things:
- I don't think Opt65 has anything to do with CC65, it's something written by a C64 guy many years ago, that's why it's old style C. And yes, if we could get that thing to work (and play nice with auto-modified code, etc...) it would be nice to have, even when coding in assembler.
- Fabrice sent me last year some new code for the LCC code generator, which is supposed to be better, but I did not have time to do anything about that, so if some people feel like giving a shot, I can forward you the changes.

Now, regarding that:
Let's face it, guys... a C compiler will never generate good code for a 6502 architecture. Simply C is not designed for so limited 8-bit processors.
I disagree and for many reasons, but first of all I want to state that I am not looking for the perfect optimizing C compiler for the Oric, just one that is moderately good and allows me to test algorithms before I convert them to ASM.
I agree that it's possible to have a BETTER C compiler than what currently exist, but "will never generated good code for a 6502 architecture" is not a belief: It's a fact.

The reason is that the C is doing some assumptions on the machine model, things like "memory is linear" and "fields of structures should not be reordered" and "you can dereference an element of an array and from there get the position of the next element".

If you program in clean C, you cannot *by design* have something that will run efficiently on a 6502.

The best example is something as simple as a structure that holds some sprites information, with a X,Y position, a pointer to the bitmap to draw, and some life points. Then you have a bunch of these and put that in an array.

In 6502, you would use instead one array for each 8 bit piece of information: An array for the X, one for the Y, one for the lower part of the pointer, one for the higher part of the pointer, one for the life points.

Obviously you can do that in C as well, but what I mean, is that if you are not going to use arrays of structs, you are not really doing C anymore, and if you somewhat modified the compiler to allow that, it would not be a standard C compiler anymore (but it would run MUCH faster).

So yes, you could write a very fast compiler that runs nicely on the 6502, but that would not be a C compiler anymore.

Regarding GCC, what would be nice is actually to have a C++ compiler instead of just C, that would allow for things like deep inlining and constexpression, which would basically give compile time optimized code generation, and references too.
Even if the compiler reaches only half of the speed of a human it does not matter for me since that is good enough to evaluate the sanity of my algorithm before I switch to assembly. Even between humans coding in assembly, a difference of half speed is very easy to reach so that would be already good. Hell, even one quarter or one height speed would be fine.
At the moment, I evaluate the speed difference between LCC65 and pure assembler (both code written by me) to be about a factor of 10 on standard code, and up to x50 on convoluted things involving loops and bit-twidling
cc65: 301 ticks (6.02s)
gcc: 97 ticks (1.94s)
Except if you look a bit lower on the thread, you'll see that somebody pointed out that CC65 was not being called with the optimisation parameters.

Which reminds me that in the OSDK we are running LCC with -O2 instead of -O3, maybe there's something worth checking there.

User avatar
NekoNoNiaow
Flight Lieutenant
Posts: 272
Joined: Sun Jan 15, 2006 10:08 pm
Location: Montreal, Canadia

Re: A new well-known compiler

Post by NekoNoNiaow »

Chema wrote:
Tue Feb 12, 2019 2:16 pm
Yeah, I know. But nasty things start happening with automatic int promotions, such as:

Code: Select all

    unsigned char a=200, b=200,c;
    
    c=(a+b)/2;
You are absolutely right and I just got bitten by that issue: while debugging opt65, I noticed that some additions of 8 bit values were actually compiled into 16 bit values additions, thus generating more than twice the necessary amount of work.
I had forgotten these integral promotion rules of C/C++ but some compilers have options which allow to disable them so maybe lcc65 has them?
(http://www.keil.com/support/docs/1754.htm)
Chema wrote:
Tue Feb 12, 2019 2:16 pm
Indexing also produces sub-optimal results. You can manage arrays quite quickly on the 6502 if they are less than 256 bytes long. But the C compiler does not know about this and uses 16-bit arithmetic. You probably won't have string functions using Y indexing which only work for strings < 256 chars...
I am under the impression that modern compilers such as GCC or LLVM can generate adapted indexing code when they know about the size of the data types they are manipulating. I might be wrong though and in many cases you are right that they cannot detect that.
This said, with some hints (gcc's attributes) one could help them choose the proper ones.
Ex: __attribute( "8bitindex" ) char* mypointer = 0; // Indexes on this pointer will be 8bit.
Chema wrote:
Tue Feb 12, 2019 2:16 pm
And the register usage... well if only we had a few general-purpose registers... but there is only A, then the indexes, which can be used partially for some operations. You can use page zero, of course, which is what most compilers do, but beware that some (namely cc65) uses almost all the zero page for its needs (or that I read).
Yup, but modern compilers are quite good at that. They can juggle memory and registers very efficiently, even using X or Y for temporary storage to avoid touching memory if the code generating backend is properly written.
Chema wrote:
Tue Feb 12, 2019 2:16 pm

In any case, it was my fault jumping with my personal rants :wink: into your thread, because, as you said, you have clearly stated your idea many times, and my post was along another different path, and (frankly) completely unhelpful. I am really sorry for that. As I said it was just my discussion-eager me :mrgreen:

I sincerely apologize.
Hey, do not apologize, you provided interesting and valuable feedback! ;)
I certainly welcome discussion of any kind as long as it is on topic (and your input mostly was).

Chema wrote:
Tue Feb 12, 2019 2:16 pm
And that is indeed impressive! I know Fabrice Frances once took a look at the 65C02 target for gcc, but never adapted it for 6502... http://oric.free.fr/software.html
Argh, I did not know about that one but I suspect that version is now quite obsolete since GCC's internal architecture has evolved and improved a lot since (due to the pressure of LLVM).

User avatar
NekoNoNiaow
Flight Lieutenant
Posts: 272
Joined: Sun Jan 15, 2006 10:08 pm
Location: Montreal, Canadia

Re: A new well-known compiler

Post by NekoNoNiaow »

Dbug wrote:
Tue Feb 12, 2019 3:41 pm
I will not answer to all the comments, but I want to start by two things:
- I don't think Opt65 has anything to do with CC65, it's something written by a C64 guy many years ago, that's why it's old style C. And yes, if we could get that thing to work (and play nice with auto-modified code, etc...) it would be nice to have, even when coding in assembler.
Oh, thanks for the information and sorry about the confusion I might have introduced.
And I confirm officially that I am working on opt65. I have been debugging it on a small example and so far I have not yet found any mis-optimizations but I guess that will arrive soon enough. ;)
Dbug wrote:
Tue Feb 12, 2019 3:41 pm
- Fabrice sent me last year some new code for the LCC code generator, which is supposed to be better, but I did not have time to do anything about that, so if some people feel like giving a shot, I can forward you the changes.
Oh, interesting. I could indeed give it a go as well.
That coupled with a working opt65 could be a nice update for the OSDK.
Dbug wrote:
Tue Feb 12, 2019 3:41 pm
I agree that it's possible to have a BETTER C compiler than what currently exist, but "will never generated good code for a 6502 architecture" is not a belief: It's a fact.
I globally agree, I only expect a "moderately good" result, not even a "good" one. ;)
Dbug wrote:
Tue Feb 12, 2019 3:41 pm
In 6502, you would use instead one array for each 8 bit piece of information: An array for the X, one for the Y, one for the lower part of the pointer, one for the higher part of the pointer, one for the life points.

Obviously you can do that in C as well, but what I mean, is that if you are not going to use arrays of structs, you are not really doing C anymore, and if you somewhat modified the compiler to allow that, it would not be a standard C compiler anymore (but it would run MUCH faster).
You are absolutely correct.
I actually write my C code in this style since my algorithms are really targeting the Oric and are not made to be platform agnostic.

In essence I am really using C only to have the convenience of easily readable variables and control flow branches but not using any structs or functions. For my needs, it is really only a high level assembly language of sort.
The only thing I currently expect from a "moderately good" compiler would be to generate assembly code that is reasonably understandable at first glance even if it is not super efficient, this way I could rewrite the algorithm starting from the generated code rather than from scratch.
Dbug wrote:
Tue Feb 12, 2019 3:41 pm
So yes, you could write a very fast compiler that runs nicely on the 6502, but that would not be a C compiler anymore.

Regarding GCC, what would be nice is actually to have a C++ compiler instead of just C, that would allow for things like deep inlining and constexpression, which would basically give compile time optimized code generation, and references too.
Absolutely! These would allow interesting optimizations indeed.
From what I understand, the version of GCC I linked to (in the Atari age forum) does support C++ since it is just the backend part of GCC and C++ has already been transformed into internal representation at this stage.
I do not know if that version supports constexpr though, you would have to verify. ;)
Dbug wrote:
Tue Feb 12, 2019 3:41 pm
cc65: 301 ticks (6.02s)
gcc: 97 ticks (1.94s)
Except if you look a bit lower on the thread, you'll see that somebody pointed out that CC65 was not being called with the optimisation parameters.

Which reminds me that in the OSDK we are running LCC with -O2 instead of -O3, maybe there's something worth checking there.
Ah, excellent point. I missed that.
I will experiment with -O3 while working on opt65! Thanks for the info!

User avatar
polluks
Pilot Officer
Posts: 69
Joined: Tue Jun 05, 2012 10:09 pm
Location: Germany
Contact:

Re: A new well-known compiler

Post by polluks »

By the way opt65 was developed by Daniel Dallmann.
See his https://en.wikipedia.org/wiki/LUnix.
cc65 development
Oric Atmos + Cumulus
Acorn Electron

User avatar
NekoNoNiaow
Flight Lieutenant
Posts: 272
Joined: Sun Jan 15, 2006 10:08 pm
Location: Montreal, Canadia

Re: A new well-known compiler

Post by NekoNoNiaow »

polluks wrote:
Tue Mar 05, 2019 2:21 pm
By the way opt65 was developed by Daniel Dallmann.
See his https://en.wikipedia.org/wiki/LUnix.
Wow, Unix on the C64/128, fascinating! \(oO)/

(I wonder if that could be ported to the Oric/other-8-bitters? Probably.)
I could not find anything about Daniel Dallmann when I was looking for information about opt65 a few weeks ago so this might be a useful lead. Thanks! ;)

User avatar
ibisum
Wing Commander
Posts: 1465
Joined: Fri Apr 03, 2009 8:56 am
Location: Vienna, Austria
Contact:

Re: A new well-known compiler

Post by ibisum »

>(I wonder if that could be ported to the Oric/other-8-bitters? Probably.)

I think Orix has a bit more potential: http://orix.oric.org

User avatar
polluks
Pilot Officer
Posts: 69
Joined: Tue Jun 05, 2012 10:09 pm
Location: Germany
Contact:

Re: A new well-known compiler

Post by polluks »

NekoNoNiaow wrote:
Tue Mar 05, 2019 10:14 pm
(I wonder if that could be ported to the Oric/other-8-bitters? Probably.)
Sure :wink: https://github.com/jedeoric/Lunix/blob/ ... EADME.ORIC
cc65 development
Oric Atmos + Cumulus
Acorn Electron

User avatar
iss
Wing Commander
Posts: 1319
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: A new well-known compiler ... again [cc65 vs lcc65 vs vbcc]

Post by iss »

Well, after I saw the info about 'a new compiler' - VBCC I decided to resurrect this thread again :).

Using the aes256 example from my earlier posts I made test with vbcc too.
I think the results are interesting and promising.

All sources and a Makefile are in a new repo: https://github.com/iss000/oricCompilerBenchmark

All sources are available and compiled TAP files in tap-*/ subdirectories.
Please, test your self and comment. If you can achieve better results tweaking compiler options let me know I'll update the info asap!

My plan is to add more C compilers (which I've already collected).
It will be very helpful to propose more C sources - best is to not use any library functions supplied with the toolchain.
Interesting are only the size of the compiled binary and the speed.

URL: https://github.com/iss000/oricCompilerBenchmark
Screenshot_20210129_232459.png

User avatar
Dbug
Site Admin
Posts: 3751
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: A new well-known compiler

Post by Dbug »

Interesting, vbcc generates the smallest code for the "empty main", but the largest (and fastest) for th AES256, I wonder if it's somewhat unrolling code.

What would be interesting is to attach the actual generated assembler source for each of the cases, to see what the differences are.

As far as I know, the main issue with LCC65 is not really the speed, yes it's not fast, but not catastrophically bad, it's mostly the generated code size, it's way too fast to fill the memory.

User avatar
jbperin
Flight Lieutenant
Posts: 344
Joined: Wed Nov 06, 2019 11:00 am
Location: Valence, France

Re: A new well-known compiler

Post by jbperin »

This C compiler bench is very interesting.

From my point of view, someone targeting speed can't really avoid assembly language.
In this context, C is just a step to prototype and validate algorithms before coding them in assembly language.
In this perspective, a C compiler should also be evaluated through the facilities it offers to mix C and assembly language and to switch from one to another.

( On the other hand, if the code generated by the C compiler is very performant, it pushes a bit further the need to switch to assembly language.
With a performant C compiler, it becomes possible to stay in C where, with a less performant compiler, it would require to use assembly. )

I can say that I love the possibility offered by LCC65 to inline assembly instruction right within C code. I find it is very convenient to ease the switch between C and assembly. I'm also fond of:
- the possibility to share #define between C and assembly.
- the possibility to easily have symbol available in Oricutron monitor.

For optimisation purpose with a C compiler not offering the inline assembly facility, one workflow which is convenient as well is:

Code in C --> make C compiler generater ASM --> optimize generated ASM --> stun your friend and family with high performance result.

This workflow is of interest only if the generated ASM code is human readable.

Some other question of interest when evaluating a C compiler for 6502:
- Does it allow to work with real 8 bits (rather than truncated 16 bits operations such as with LCC65).
- What recursivity level does it allow (directly linked to stack consumption) because recursivity is typically what a developer prefers to do in C rather than is assembly .. so painful.
-
I'm currently moving so I can't dive into the C complier bench as I would like to do.
I just wanted to give the point of view of a cheap developer who has never produced neither game nor app and author of the most unused 3D library available on the internet.

So it worth what it worth .. my contribution.

User avatar
Chema
Game master
Posts: 2827
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: A new well-known compiler

Post by Chema »

I agree. I prefer small code than fast code from a C compiler, as I doubt it can compare to direct use of asm.

Sharing header files is indeed great. I also like how easy it is to mix C and asm in LCC65, and hope it is the same in VBCC. I prefer that to inline asm, if I have to choose.

In fact my usual workflow was write a prototype in C, then convert routines to asm. Not optimize the generated asm (which is not easy to understand) but write the whole function again in asm. That is clearly visible in Space 1999 (where all the high level routines are converted from the C initial versions and still use the C stack for parameter passing, etc. - not the best idea performance-wise, though).

As soon as I got more confident with asm, I wrote more and more code directly in asm, but still C is good for setting things up, organizing the main program and prototyping.

User avatar
iss
Wing Commander
Posts: 1319
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: A new well-known compiler

Post by iss »

Well, I decided to update to most recent version all compilers and to re-run the benchmark.
... and the result is full disappointment! :(

Code: Select all

cc65: dummy-cc65      :   250 ->  250  =>    +0
cc65: aes256-cc65     :  7330 -> 7558  =>  +228
cc65: aes256-tab-cc65 :  7513 -> 7746  =>  +233
                                       
osdk: dummy-osdk      :   452 ->   452 =>    +0
osdk: aes256-osdk     : 15491 -> 15491 =>    +0
osdk: aes256-tab-osdk : 14064 -> 14064 =>    +0
                                       
vbcc: dummy-vbcc      :   243 ->   243 =>    +0
vbcc: aes256-vbcc     : 14571 -> 20334 => +5763
vbcc: aes256-tab-vbcc : 12113 -> 12921 =>  +808
You can see how the size of the compiled binary grows for CC65 and VBCC, without any remarkable speed improvements.

Obviously everything goes in the same wrong direction as @Dbug twitted HERE :)....

User avatar
Dbug
Site Admin
Posts: 3751
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: A new well-known compiler

Post by Dbug »

iss wrote:
Sun Apr 25, 2021 10:32 am
Well, I decided to update to most recent version all compilers and to re-run the benchmark.
... and the result is full disappointment! :(
(...)
You can see how the size of the compiled binary grows for CC65 and VBCC, without any remarkable speed improvements.
This is indeed sad.
Maybe looking at the release notes for the compilers it's possible to understand what happened, maybe they changed some default values to be "optimized for speed" and "inline everything" by default?

User avatar
iss
Wing Commander
Posts: 1319
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: A new well-known compiler

Post by iss »

The last changes in CC65 are mainly bug-fixes, in VBCC maybe some unrolled-loops features are introduced but I'm not sure.
Indeed, release notes may give more explanations.

User avatar
xahmol
Flying Officer
Posts: 240
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: A new well-known compiler

Post by xahmol »

Strange indeed.

But for me the conclusion stays the same: if you want to code purely in C, CC65 is the only viable choice for Oric Atmos at the moment.
Quite literally so actally: I never tried Vbcc, but my game in C only just fits in memory with CC65, absolutely does not fit in memory using the OSDK bundled C compiler. And that is not even taking into account that obviously porting code is way simpler from one CC65 target to another.

By the way: porting code between Commodore, Atmos and Telestrat targets on CC65 and GCC-TMS9900 compiler for TI-99/4a learned me that actually the Atmos target is not 100% compliant in the conio.h implementation to the CC65 reference docs in its behaviour.
Example: I now misuse cputc() in CC65 for Atmos to print screen attribute codes 0-31, but only on porting that code to the TI I noted that actually cputc() is not supposed to print codes under 32 according to CC65 reference documentation, it is supposed to print control codes instead (such as left, right, enter, tab, etc.) Actually I think the Atmos implementation is more convenient as I lack to see the use of printing control codes with cputc(), but reading the docs it seems clear that it is the intended way how it should work.
Was actually (luckily not very convinced) accusing the author of the TI library I use that provides a conio.h implementation to the TI that he did implement it not entirely correct, but had to admit his implementation is actually more correct to CC65 reference docs than the Atmos CC65 implementation.
So guess there is still room for bug fixing there.

Still communicating with Jede on the Telestrat target as that still gives me issues (fwrite() not yet functional, kbhit() now fixed but seemingly at least on my side at the expensive that joystick stopped functioning. Cputc() already fixed before, now works). Use it to try to port to Twlighte Board/Orix.

Post Reply