Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2015-07

Enable LLVM?

10 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Den

Hi there!

I was just wondering if there was an option to enable compiling to LLVM bitcode? I see a bit of work happening in SVN from it, and would love to start using it.

- Dennis Fehr

Reply by email

Jonas Maebe
to Den
Den wrote
I was just wondering if there was an option to enable compiling to LLVM bitcode? I see a bit of work happening in SVN from it, and would love to start using it.

You cannot use it, because it does not work yet. And as mentioned in earlier messages:
* it will need architecture and OS-specific support per target (I'm only working on Darwin/x86-64 right now)
* it will probably only work with specific LLVM versions, because LLVM only cares to an extremely limited extent about backward/forward compatibility
* LLVM's handling of parameter passing is split between Clang and LLVM in a way that makes it impossible for third parties to support it in a reliable way (although some people are looking into splitting off that functionality into a - C++ - library; not sure how useful that would be for FPC)

LLVM also makes a lot of assumptions that are wrong as far as non-C languages are concerned. For example, the result of a load from a nil address is considered to be "undefined", which means they (and every instruction that depends on such a result) may be "optimised" away completely by LLVM. In Pascal (or at least FPC), you instead expect a segmentation fault if that happens. You can find a few other such issues documented at
http://www.mono-project.com/docs/advanced/runtime/docs/llvm-backend/ , but there are more. They are open to fixing such assumptions (or to at least add a command line parameter to disable them), but I'm not aware of anyone actually working on LLVM to do this (and I'm not going to do that myself either).

Finally, it is not possible at this time to combine units compiled with a regular code generator with units compiled with LLVM due to differences in the PPU format between the two. I don't know if it will be possible to solve this without a significant rewrite of in particular our handling of inline functions.

Just to say: don't get your hopes up that it will just be a simple "recompile and take advantage of all LLVM features", especially in the beginning.

Jonas

Reply by email

Den
to Jonas Maebe

Ah, thanks for giving me a heads up Jonas. I'll have to wait and see where it goes then. Do you have a page/blog where I can keep up to date with your progress/roadmap of it? :)

- Den

Jonas Maebe wrote 46 lines
Den wrote: > I was just wondering if there was an option to enable compiling to > LLVM bitcode? I see a bit of work happening in SVN from it, and would > love to start using it. You cannot use it, because it does not work yet. And as mentioned in earlier messages: * it will need architecture and OS-specific support per target (I'm only working on Darwin/x86-64 right now) * it will probably only work with specific LLVM versions, because LLVM only cares to an extremely limited extent about backward/forward compatibility * LLVM's handling of parameter passing is split between Clang and LLVM in a way that makes it impossible for third parties to support it in a reliable way (although some people are looking into splitting off that functionality into a - C++ - library; not sure how useful that would be for FPC) LLVM also makes a lot of assumptions that are wrong as far as non-C languages are concerned. For example, the result of a load from a nil address is considered to be "undefined", which means they (and every instruction that depends on such a result) may be "optimised" away completely by LLVM. In Pascal (or at least FPC), you instead expect a segmentation fault if that happens. You can find a few other such issues documented at http://www.mono-project.com/docs/advanced/runtime/docs/llvm-backend/ , but there are more. They are open to fixing such assumptions (or to at least add a command line parameter to disable them), but I'm not aware of anyone actually working on LLVM to do this (and I'm not going to do that myself either). Finally, it is not possible at this time to combine units compiled with a regular code generator with units compiled with LLVM due to differences in the PPU format between the two. I don't know if it will be possible to solve this without a significant rewrite of in particular our handling of inline functions. Just to say: don't get your hopes up that it will just be a simple "recompile and take advantage of all LLVM features", especially in the beginning. Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
to Den
Den wrote
Ah, thanks for giving me a heads up Jonas. I'll have to wait and see where it goes then. Do you have a page/blog where I can keep up to date with your progress/roadmap of it? :)

No, just the svn commit log. The status right now is that the system unit for Darwin/x86-64 can be mostly compiled and "assembled" (i.e., the generated LLVM IR can be successfully parsed by llc -- although since it doesn't get completely to the end, I may not have seen all errors for code coming before that yet) other than
a) RTTI
b) inline assembler
c) get_frame
d) trampolines for interface methods

RTTI is not that difficult to solve (just work to convert ncgrtti to the high level typed constant infrastructure), but the others are fairly hard problems.

Jonas

Reply by email

Adriaan van Os
to Jonas Maebe
Jonas Maebe wrote 14 lines
Den wrote: > Ah, thanks for giving me a heads up Jonas. I'll have to wait and see > where it goes then. Do you have a page/blog where I can keep up to date > with your progress/roadmap of it? :) No, just the svn commit log. The status right now is that the system unit for Darwin/x86-64 can be mostly compiled and "assembled" (i.e., the generated LLVM IR can be successfully parsed by llc -- although since it doesn't get completely to the end, I may not have seen all errors for code coming before that yet) other than a) RTTI b) inline assembler c) get_frame d) trampolines for interface methods

Ehw, trampolines. They requires executable stacks. Is there a possibility to pass activation frames instead or apply lambda/lifting ?

Regards,

Adriaan van Os

Reply by email

Jonas Maebe
to Adriaan van Os
Adriaan van Os wrote
Jonas Maebe wrote: > d) trampolines for interface methods Ehw, trampolines. They requires executable stacks.

No, they don't.

Is there a possibility to pass activation frames instead or apply lambda/lifting ?

Trampolines for interface methods are generated at compile time are are of the form:

self:=self-offset(objectself,intfvmt);
branch(interfacemethod); // can either be a direct or indirect branch

This cannot be expressed in LLVM IR. The above can in principle be replaced by a tail call that passes on all arguments (although LLVM won't generate an actual tail call, because it only supports tail calls for functions using the C fastcall calling convention) because FPC does not support C-style varargs functions (in which case "calling through passing the caller arguments" again could not be expressed), but since inline assembly needs to be supported anyway, it's probably easier to just generate assembler for them and call that.

Jonas

Reply by email

Jonas Maebe
to Jonas Maebe: No, just the svn commit log. The status right now is that the system unit for…
Jonas Maebe wrote 6 lines
No, just the svn commit log. The status right now is that the system unit for Darwin/x86-64 can be mostly compiled and "assembled" (i.e., the generated LLVM IR can be successfully parsed by llc -- although since it doesn't get completely to the end, I may not have seen all errors for code coming before that yet) other than a) RTTI

This has now been implemented as well. With some local hacks and a few manual changes to the generated code, the system unit for Darwin/x86-64 can now be compiled and successfully assembled. Note that this is with all inline assembly code removed (and pure inline assembly functions just returning 0 or its equivalent, so a lot of code is wrongly optimised away by llvm based on that).

Some results are interesting, like the lowercase(shortstring) function becoming a rather impressive vectorised jungle:
http://pastebin.com/vpugp80e . The only other vectorised functions in the system unit are lowercase(shortstring),
UCS4StringToUnicodeString/Widestring, ArrayStringToPPChar and the helpers to add/sub/mul/symdif large sets.

On the other hand, it seems that loading an array as a plain value in llvm bitcode results in rather suboptimal code (this is with -O2): http://pastebin.com/krXhuEzF :)

Jonas

Reply by email

Den
to Jonas Maebe: This has now been implemented as well. With some local hacks and a few manual changes to…

Good results! Thanks for keeping us updated, keep it up! :)

- Dennis Fehr

Jonas Maebe wrote 31 lines
On 14/07/15 10:13, Jonas Maebe wrote: > No, just the svn commit log. The status right now is that the system > unit for Darwin/x86-64 can be mostly compiled and "assembled" (i.e., the > generated LLVM IR can be successfully parsed by llc -- although since it > doesn't get completely to the end, I may not have seen all errors for > code coming before that yet) other than > a) RTTI This has now been implemented as well. With some local hacks and a few manual changes to the generated code, the system unit for Darwin/x86-64 can now be compiled and successfully assembled. Note that this is with all inline assembly code removed (and pure inline assembly functions just returning 0 or its equivalent, so a lot of code is wrongly optimised away by llvm based on that). Some results are interesting, like the lowercase(shortstring) function becoming a rather impressive vectorised jungle: http://pastebin.com/vpugp80e . The only other vectorised functions in the system unit are lowercase(shortstring), UCS4StringToUnicodeString/Widestring, ArrayStringToPPChar and the helpers to add/sub/mul/symdif large sets. On the other hand, it seems that loading an array as a plain value in llvm bitcode results in rather suboptimal code (this is with -O2): http://pastebin.com/krXhuEzF :) Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Michael Schnell
to Jonas Maebe: This has now been implemented as well. With some local hacks and a few manual changes to…
Jonas Maebe wrote
Some results are interesting, like the lowercase(shortstring) function becoming a rather impressive vectorised jungle: http://pastebin.com/vpugp80e .

Really interesting !!!!

It would take a lot of expertize to do this manually.

Did you check that it really works ?

IMHO it might be a nice idea to use the ASM code to provide an optimized function that is used in the standard library for ARM.

-Michael

Reply by email