_g6sn
Joined 4 years ago
Joined 4 years ago
Edit: The external source archive page was. Although, with a very simple bash script, but nevertheless
Here I am not speaking about the compiler optimizing based on known libc behavior, but libc "specializing" based on assumed compiler behavior. Which is, again, absolutely reasonable -- both compiler and libc typically go hand in hand. However, as my compiler "parasites" on the existing libc implementations, I would have preferred that such assumptions would be validated to the extent it is possible at compile time, preferably with some graceful failure.
Glibc provides quite profound libc part even to non-GNU C-compatible compilers, but in some places it might fail silently and disruptively.
I am deeply thankful to all developers of libc implementations for Linux and BSD systems, and I am in no way accusing anyone or demanding anything. In the project's README I explicitly note, that any standard library function not being usable will be treated as a bug in Kefir itself. In the above rant, I just expressed a mere wish that some things could be a bit smoother.
I am in no way accusing any of libc developers, they got much higher priority things to do than supporting obscure compilers, and this is my problem as a compiler developer, but nevertheless. For instance, glibc may simply override __attribute__ keyword with an empty macro, or omit packed attributes for non GNU C compilers (breaking epoll ABI along the way). Of course, strictly standard-compliant compiler may not have attributes at all, but in my opinion #warning/#error directive would have been more appropriate than silently producing ABI breakage.
Although, I have not engaged with glibc developers on these topics, and mostly documented encountered challenges as patches in my own test suite.
I'll immediately reveal some issues with the project. On the compilation speed, it is unfortunately atrocious. There are multiple reasons for that:
1. Initially the compiler was much less ambitious, and was basically generating stack-based threaded code, so everything was much simpler. I have managed to make it more reasonable in terms of code generation (now it has real code generator, optimization pipeline), but there is still huge legacy in the code base. There is a whole layer of stack-based IR which is translated from the AST, and then transformed into equivalent SSA-based IR. Removing that means rewriting the whole translator part, for which I am not ready.
2. You've outlined some appealing points (standard compliance, debug info, optimization passes), but again -- this came at the expense of being over-engineered and bloated inside. Whenever, I have to implement some new feature, I hedge and over-abstract to keep it manageable/avoid hitting unanticipated problems in the future. This has served quite well in terms of development velocity and extending the scope (many parts have not seen complete refactoring since the initial implementation in 2020/2021, I just build up), but efficiency of the compiler itself suffered.
3. I have not particularly prioritized this issue. Basically, I start optimizing the compiler itself only when something gets too unreasonable (either, in terms of run time, or memory). There are all kinds of inefficiencies, O(n^2) algorithms and such simply because I knew that I would be able to swap that part out should that be necessary, but never actually did. I think the compiler efficiency has been the most de-prioritized concern for me.
Basically, if one is concerned with compilation speed, it is literally better to pick gcc, not even talking about something like tcc. Kefir is abysmal in that respect. I terms, of code base size, it is 144k (sans tests, 260k in total) which is again not exactly small. It's manageable for me, but not hacker-friendly.
With respect to marketing, I am kind of torn. I cannot work on this thing full time, unless somebody is ready to provide sufficient full-time funding for myself and also other expenses (machines for tests, etc). Otherwise, I'll just increase the workload on myself and reduce the amount of time I can spend actually working on the code, so it'll probably be net loss for the project. Either way, for now I treat it closer to an art project than a production tool.
As for compiled code performance, I have addressed it here https://lobste.rs/s/fxyvwf -- it's better than, say, tcc, but nowhere near well-established compilers. I think this is reasonable to expect, and the exact ways to improve that a bit are also clear to me, it's only question of development effort
P.S. JKU is a great school, although by the time I enrolled there the project has already been on the verge of bootstrapping itself.
EDIT: formatting
- Kefir name is simply a reference to milk drink, no other connotation is intended. Updated project README with this information.
- The compiler is indeed quite primitive, especially, in terms of code generation. My main goal was implementing a C compiler that is reasonably compliant with language standard and platform ABIs, so I decided to simply ignore any performance considerations as I wouldn't compete with well-established compilers anyway.
Usage of threaded code is also caused by the same reason -- it is very simple to obtain assembly from intermediate representation when the assembly is mostly composed from references to runtime routines. Even without considering more sophisticated schemes of code generation, current approach is not optimal -- threaded code encoding scheme is very wasteful in terms of generated code (which was also noted in the blog post) and has awful runtime performance.
- I have tried to keep compiler compliant with the standard as well as compatible some of widespread C extensions (with some exceptions which I listed in README). Will try to address compilation errors found by Brian. Unfortunately, currently I do not have much time to work on the compiler. Identifying and fixing such bugs might also be quite tedious, so I expect that there are enough unnoticed compatibility problems there.
- Patches implementing OpenBSD support are appreciated. I plan to integrate those into the main code tree at some point.
I should have communicated this more clearly in README. Kefir requires relatively recent GNU Make versions (see dist/Dockerfile for full and complete set of dependencies), as it basically uses make for all project lifecycle tasks. I remember there were some parallel build issues with older GNU Make versions. This could be an issue.