Difference between revisions of "LLVM"

From Free Pascal wiki
Jump to navigationJump to search
Line 1: Line 1:
 
The current status of '''Low Level Virtual Machine''' (LLVM) is ''in progress''.
 
The current status of '''Low Level Virtual Machine''' (LLVM) is ''in progress''.
  
{{Note|The information in this section has been updated as of September 2016 and might be outdated by the time you read it}}
+
{{Note|The information in this section has been updated as of December 2018 and might be outdated by the time you read it}}
  
 
==Progress==
 
==Progress==
LLVM support has not yet fully landed in trunk, so it is not yet possible to use it.
+
FPC with an LLVM code generator backend can be built from the https://svn.freepascal.org/svn/fpc/branches/debug_eh/ branch. It currently only supports Darwin/x86-64 and Linux/x86-64.
  
The main missing features before the result is usable for real world code are:
+
Building:
# LLVM has support for explicit setjmp/longjmp (which FPC uses on most platforms for exception handling), but we need to make use of some LLVM exception handling intrinsics to ensure the correctness of its control flow analysis <br />A future, better, way may be to solely use LLVM's built-in primitives for exception handling.
+
* Add '''LLVM=1''' to the make command line options
# possibly support for debug information generation<br />There are also a few LLVM limitations:
+
* On Linux, add the path to libgcc_s to the compilation options. E.g. on Ubuntu 16.04: '''OPT="-Fl/usr/lib/gcc/x86_64-linux-gnu/5"'''
#* LLVM has no support for arbitrary instructions throwing exceptions. I.e., segmentation faults, alignment exceptions, bus errors, floating point exceptions etc are not supported in any way by LLVM. If it can prove at compile time that a non-floating point exception will happen (e.g., you store nil in a pointer and immediately dereference it), it will simply interpret the exception-causing instruction as having "undefined behaviour", which generally results in pretty much all code depending on the result of that instruction getting "optimised" away. In case of floating point exceptions, LLVM will replace the result of the instruction with Inf/Nan at compile time. They are aware of this limitation (http://llvm.org/devmtg/2015-10/slides/KlecknerMajnemer-ExceptionHandling.pdf), but there is no one actively working on it right now (https://groups.google.com/forum/#!topic/llvm-dev/7yLycHmeydo )
 
#* LLVM has no support for the i386 "register" calling convention, so the support for the i386 target using LLVM will probably never be added.
 
  
As alluded to above, LLVM support needs to be added/tested/maintained separately for each supported architecture and to a lesser extent for each supported OS.
+
==Current Limitations==
 +
* add support for specifying the target LLVM version. Currently it's hard-coded to LLVM 3.9, although it works all the way up to at least LLVM 7.0. Specifying the version number would mainly be necessary (for now) to target older LLVM versions
 +
* add support for more platforms. Windows will be harder (and not something I plan on working any time soon), because I have not yet added support for generating LLVM-based exception handling code that is needed for SEH-based exception handling. Other 64 bit platforms should be "reasonably" easy (the parameter handling needs to be generalised more though). 32 bit platforms will probably require either some compiler re-engineering, hacking, or a translation of the tcg64 code generator to some kind of high-level code generator as well.
 +
** LLVM has no support for the i386 "register" calling convention, so the support for the i386 target using LLVM will probably always miss this feature (unless someone adds it to LLVM).
 +
* add support for generating debug info
 +
* add support for generating more meta-information for optimizations (e.g. range information about subrange types and enums)
 +
* add support for saving the bitcode in addition to the native object files, and subsequently using link-time optimisation
 +
* add support for some custom calling conventions
 +
* pass on more FPC-related code generation options to LLVM (currently, mainly -CfXXX and -Ox get passed on)
 +
* add support for TLS-based threadvars
  
 
==Frequently Asked Questions==
 
==Frequently Asked Questions==

Revision as of 11:40, 9 December 2018

The current status of Low Level Virtual Machine (LLVM) is in progress.

Light bulb  Note: The information in this section has been updated as of December 2018 and might be outdated by the time you read it

Progress

FPC with an LLVM code generator backend can be built from the https://svn.freepascal.org/svn/fpc/branches/debug_eh/ branch. It currently only supports Darwin/x86-64 and Linux/x86-64.

Building:

  • Add LLVM=1 to the make command line options
  • On Linux, add the path to libgcc_s to the compilation options. E.g. on Ubuntu 16.04: OPT="-Fl/usr/lib/gcc/x86_64-linux-gnu/5"

Current Limitations

  • add support for specifying the target LLVM version. Currently it's hard-coded to LLVM 3.9, although it works all the way up to at least LLVM 7.0. Specifying the version number would mainly be necessary (for now) to target older LLVM versions
  • add support for more platforms. Windows will be harder (and not something I plan on working any time soon), because I have not yet added support for generating LLVM-based exception handling code that is needed for SEH-based exception handling. Other 64 bit platforms should be "reasonably" easy (the parameter handling needs to be generalised more though). 32 bit platforms will probably require either some compiler re-engineering, hacking, or a translation of the tcg64 code generator to some kind of high-level code generator as well.
    • LLVM has no support for the i386 "register" calling convention, so the support for the i386 target using LLVM will probably always miss this feature (unless someone adds it to LLVM).
  • add support for generating debug info
  • add support for generating more meta-information for optimizations (e.g. range information about subrange types and enums)
  • add support for saving the bitcode in addition to the native object files, and subsequently using link-time optimisation
  • add support for some custom calling conventions
  • pass on more FPC-related code generation options to LLVM (currently, mainly -CfXXX and -Ox get passed on)
  • add support for TLS-based threadvars

Frequently Asked Questions

Will the FPC team, somewhere in the future, adopt the LLVM as the backend on all platforms?
No, for various reasons:
  • LLVM will almost certainly never support all targets that we support (Gameboy Advance, OS/2, WinCE, ...), or at some point drop support for targets that we still support (as already happened with Mac OS X for PowerPC/PowerPC64).
  • the native FPC code generators require very little maintenance once written, as they are quite well insulated via abstractions from the rest of the compiler
  • you still need some of the hardest parts of the FPC native code generators anyway for LLVM (entry/exit code handling, parameter manager), to be able to deal with assembler routines and because LLVM does not fully abstract parameter passing
  • a hardware architecture seldom changes in backward-compatibility breaking ways once released, while LLVM makes no such promises. They do seem to have finally settled more or less on the binary bitcode format (even there are no guarantees, but maybe I'll add support for that after all)
  • LLVM changes a lot, all the time. That means a high chance of introducing regressions. I don't know how likely it would be that FPC-with-LLVM would one day be admissible to be run as part of LLVM's buildbots and automatic regression tests, but if not then it's possible that maintaining the LLVM backend may become more work than the regular code generators and optimizers combined (at least if we want to keep up with the latest LLVM versions, and not stick with a particular version for long times like most out-of-tree "consumers" of LLVM do)
  • most OS-specific support is in the run time library, not in the compiler. As a result, LLVM will not save much time there
  • our native code generators are much faster than LLVM's (even if you would neglect the overhead of FPC generating bitcode and the LLVM tool chain reading it back in), so especially while developing it may be more interesting to use our code generators
Is it at all likely that an LLVM compiler would produce significantly better/faster optimizations than FPC as it stand currently?
It depends on the kind of code. The more pure maths (floating point or integer, especially in tight loops), the more likely it will be faster.
Artificial benchmarks will also be much faster.
For a typical database program, don't expect much change.
actual performance comparison tests to be done

See Also