[fpc-devel] LLVM Backend?
Jonas Maebe
jonas.maebe at elis.ugent.be
Wed Nov 11 20:43:08 CET 2009
On 11 Nov 2009, at 16:55, Samuel Crow wrote:
> ----- Original Message ----
>> From: Jonas Maebe <jonas.maebe at elis.ugent.be>
>> To: FPC developers' list <fpc-devel at lists.freepascal.org>
>> Sent: Wed, November 11, 2009 5:03:52 AM
>> Subject: Re: [fpc-devel] LLVM Backend?
>>
>> In a sense it's no problem if the LLVM backend doesn't support all
>> targets that
>> the other backends support, after all it'll be just another choice
>> that people
>> can use. I just want to avoid the LLVM backend being completely
>> disconnected
>> from the other backends or require an inordinate amount of
>> maintenance to keep
>> it in sync with the other backends, because in that case it would
>> probably be
>> quite short-lived (unless some dedicated maintainer would step up
>> and constantly
>> keep it in sync with the rest).
>
> What I originally had in mind was to use the LLVM support classes
> based on C bindings for libstdc++ and LLVM's template libraries.
> See http://llvm.org/docs/ProgrammersManual.html for LLVM's best
> practices. So, as such, it wouldn't be entirely disconnected from
> the rest of the project. It would just be another LLVM frontend.
I think we're talking about two different things here: I meant that it
could get disconnected from the rest of the FPC project, not from the
LLVM project.
> As for the code maintenance, the Mattathias BASIC team would be
> using the code for our compiler in the future as well so we'd have
> to protect it from bitrot. Unfortunately something so drastic would
> be like a fork of the project and I like the fact that FPC will work
> on my old PowerMac G4 as well as the newer systems. I was also
> hoping to avoid having to write our compilers as GCC frontends as
> well since that framework is poorly documented.
Not only that: a fork without any modifications in the "regular FPC"
would probably be quite hard to keep in sync, because new frontend
features still get added to FPC. Sometimes these also require
(abstract, non-cpu-specific) code generator support, and if the
regular FPC only keeps its current code generator, then a lot of those
changes will require porting to be integrated the LLVM backend.
>> FPC already has a fairly abstract code generator interface, because
>> we don't use
>> intermediate code: parse tree nodes are translated into machine
>> code by calling
>> the appropriate code generator class methods. The existing abstract
>> code
>> generator's interface is lower level than LLVM's as far as the type
>> info is
>> concerned though, so we need a higher level (either sitting above
>> the current
>> code generator, or replacing existing code generator).
>
> We may want to replace the existing code generator, unfortunately.
> The reason that LLVM requires such high-level code for the calling
> routines is that it supports not only different calling conventions
> but it promotes from the stack-based C calling convention to a
> register-loaded fastcall convention whenever possible. This may not
> have been necessary when using the Borland Fastcall convention but
> sometimes being able to rearrange the registers when calling
> different functions can avoid some spillage to the stack.
I agree that the current function call infrastructure in FPC's code
generator is way over-engineered for what LLVM requires, and that part
would probably not be used. An LLVM call instruction handles all of
the parameter passing and return value handling by itself, so that is
no problem. There are however other things where you do may want to
keep the current code generator, because you'd have to implement
support just as low level in LLVM as it currently exists in FPC.
One example is bitpacked arrays. Last I checked, LLVM did not support
this yet (only bitpacked structs were functional), so you'd also need
the explicit loading, masking, inserting and storing (unless you
translate that into an array of structs with 1-byte elements
consisting of 8 bits each, but then the debug info will suffer).
Another example is the Objective-Pascal support we've added: unless
you'd build the FPC frontend on top of Clang rather than on top of
LLVM, you'll have to re-implement all of the metadata generation for
Objective-C classes in an LLVM way if you'd throw away all of FPC's
low level code generation stuff.
> I think the biggest obstacles to using LLVM at this point is that
> Borland Fastcall isn't supported by the x86 backend for LLVM and
> that the type information isn't high-level enough in the FPC compiler.
The code generation in FPC is implemented in basically two steps. The
parse tree nodes are all class instances with a "generate_code"
method. The generic implementations of these methods use the various
(generic) code generator methods to actually emit the (cpu-specific)
assembler instructions. If you just create descendent classes for all
of these parse tree nodes whose generate_code methods call into the
LLVM run time rather than in FPC's abstract code generator, then you
have access to all high level information that you could want.
This approach is what would correspond to the "replace the existing
code generator" you mentioned. The big downside to this approach, as
mentioned earlier, is that it would result in a lot of maintenance
work to keep the LLVM version up-to-date, because newly added tree
node types and changes to the regular FPC-versions of the
generate_code methods of the FPC would have to be manually ported to
the LLVM version (the language/dialects that FPC supports, and hence
the parse tree classes and/or their implementation, are still evolving
-- we're not just fixing implementation bugs or optimising).
Another approach would be to introduce a higher level code generator
in FPC that can be implemented via either
a) the current low level code generator
b) an LLVM backend
In that case, new parse tree nodes etc would be implemented using this
high level code generator, and no extra porting effort would be
required for supporting both the LLVM backend and the regular code
generators (once the initial implementation is finished, obviously).
Since designing such a beast is hard and a lot of work, one
possibility could be to model it on the interface that LLVM offers.
Then we immediately know that it's complete and appropriate for
compiler use (since LLVM was designed as a compiler backend), and that
by definition it will fulfil the needs of the LLVM backend (and
presumably also that of other high level backends, should anyone ever
want to implement that).
Of course, that's probably quite a bit of work (and it would slow down
the compiler due to the extra abstraction level), but I think it
offers the best chances of avoiding a fork and lots of additional
porting efforts afterwards.
> That's two problems, both fairly significant (although the latter is
> definitely heavier than the former). Do you think it's too soon to
> divide out the work? Is there more that needs discussion?
It's not entirely clear to me yet how you see the result: an FPC
frontend added to the LLVM project, or an LLVM backend added to the
FPC project. I favour the latter, but a lot of what you talk about
seems to be about the former. Or am I misunderstanding things?
Jonas
More information about the fpc-devel
mailing list