有限责任公司

来自Free Pascal wiki
跳转到导航跳转到搜索

的当前状态低级虚拟机(LLVM)支持准备进行一般测试.

灯泡 注:本节中的信息已于2023年9月更新,可能在您阅读时已过时

进度

git主分支上提供了带有LLVM代码生成器后端的FPC。它目前支持以下目标:

  • 达尔文/x86-64
  • 达尔文/AArch64(macOS,未在iOS上测试)
  • Linux/x86-64
  • Linux/AArch64系统
  • Linux/ARMHF

用法

安装Clang

您可以使用LLVM版本中包含的版本,该版本可从LLVM官方网站,或使用Xcode(macOS)或Linux发行版附带的版本。

FPC可以生成LLVM代码,该代码可以使用LLVM 7.0进行编译,直到至少17.0。使用FPC-伊尔命令行参数,列出所有支持的LLVM和Xcode版本。可以使用-Clv公司命令行参数。

使用LLVM支持构建FPC

像往常一样构建FPC,但添加LLVM=1到make命令行,以及

  • 通过添加适当的-Clv公司命令行参数到OPTNEW(可选新)FPCMAKEOPT公司例如。OPTNEW=“-Clv11.0”FPCMAKEOPT=“-Crv11.0”(LLVM/Clang 11.0)或OPTNEW=“-ClvXcode-11.0”FPCMAKEOPT=“-ClvXcode-11.0”(Xcode 11.0-11.3附带的Clang)。无论FPC支持的最新版本是什么,生成的代码都很可能与更高版本兼容。如果clang接受生成的代码,它应该可以正常工作。
警告-icon.png

警告:如果通过指定任何自定义参数选择在构建FPC时,还应将其添加到OPTNEW(可选新)FPCMAKEOPT公司原因是在编制包装目录仅包含的内容OPTNEW(可选新)将被使用(很难改变这一点,因为在交叉编译期间,对构建fpmake公司实用程序)。

  • FPC使用clang来“组装”生成的LLVMIR-XlS<x>参数指定此后缀。例如。-XlS-7型以防调用clang二进制文件叮当声7.
  • 如果您使用自定义安装的LLVM版本,请使用FPC指定其Clang二进制文件的路径-频差命令行选项(将其添加到makeOPTNEW(可选新)选项)。如果需要,编译器还将使用此路径查找LTO库(请参阅下文)。
    • 在这种情况下,还要将自定义clang二进制文件的路径添加到$HOME/.fpc.cfg文件中(这样,在“make”命令完成后使用编译器编译代码时就会找到它),例如:
#包括/etc/fpc.cfg#ifdef CPULLVM-FD/Users/Me/clang+llvm-8.0.0-x86_64-apple-darwin/bin-第8.0类#结尾
  • 在Linux上,还要将路径添加到libgcc_s的“$HOME/.fpc.cfg”文件中。例如,在Ubuntu 16.04上:-Fl/usr/lib/gcc/x86_64-linux-gnu/5,与上述类似。

安装支持LLVM的FPC

使用LLVM支持构建的FPC不包含内置代码生成器。此外,安装它将覆盖当前安装在相同前缀(目标目录)中的具有相同版本号的任何FPC。由于FPC使用LLVM后端生成的单元与FPC使用内置代码生成器生成的单元不兼容,因此最好暂时在不同的前缀(目标目录)中安装这样的版本。使用make参数INSTALL_PREFIX=/xxx/yyy以指定此前缀。如上所述,您可以在“$HOME/.fpc.cfg”中使用自定义块来指定备用单元目录:

#ifdef CPULLVM-Fu/yourLLVMinstallPREFIX/lib/fpc/$fpcversion/units/$fpctarget/*-Fu/yourLLVMinstallPREFIX/lib/fpc/$fpcversion/units/$fpctarget/rtl#结尾

使用链接时间优化(LTO)

链接时间优化意味着整个程序及其使用的所有单元都可能一起进行优化。

要编译具有LTO支持的单元,或使用LTO编译程序或库,请添加-Clflto公司在编译器命令行上。如果您将此添加到选择/OPTNEW(可选新)在构建FPC时,所有标准单元和编译器本身也将使用LTO构建。

笔记:

  • 如果使用LTO编译单元,它也会正常编译。这意味着您可以将其用于LTO和正常(静态或智能)链接。
  • 包含在Xcode 9之前(包括10.1)中的链接器(ld)包含各种错误,当系统单元包含在LTO中时,这些错误会导致错误。您可以通过指定-Clfltonosystem公司添加到中的命令行选项-Clflto公司.
  • 在Linux上,除非您使用的是发行版的打包LLVM版本,否则还必须构建LLVMgold.so公司链接器插件并将其放在自定义LLVM安装的“lib”目录中(它不是作为正式LLVM安装程序的一部分提供的,因为它需要为系统上的binutils构建)。请参见http://llvm.org/docs/GoldPlugin.html了解更多信息。
    • 即使您确实使用了发行版的打包LLVM版本,您可能仍然需要安装一个单独的包来获得LLVMgold.so公司.

使用地址消毒剂(asan)

地址消毒剂是一种LLVM代码生成过程,它检测所有内存访问,以提供(相对)快速检测读取未初始化内存、缓冲区溢出和访问释放内存。它类似于瓦尔格林德,但速度更快,也更准确,因为LLVM确切地知道每个局部变量和全局变量的起始位置和结束位置,所以它可以检测到指向一个局部/全局变量的指针是否交叉到另一个局部或全局变量的内存中。

要使用它,请使用-Clfsanitize=地址选项。

笔记:

  • 某些版本的地址消毒剂会自动启用内存泄漏检测,并在检测到内存泄漏时中止程序。您可以使用禁用此功能导出ASAN_OPTIONS=detect_leaks=0
  • ARM(32位)不支持地址消毒剂

打开的任务

  • 目前仅支持少数平台,但可以添加更多平台。Windows将更加困难,因为它需要支持生成基于SEH样式LLVM的异常处理代码。其他平台应该“相当”容易(不过,参数处理需要更一般化)。
  • 添加对(实验)llvm.experimental.constrained.*intrinsic的支持,以正确支持浮点舍入模式和异常
    • 这已经完成了一部分,但由于它们的实验性质,并非所有的目标平台都支持它们
  • 添加对将try块自动大纲显示为“noinline”嵌套函数的支持,以便可以安全捕获硬件异常
    • 现在,您必须手动将try/except或try/finally块的主体移动到用“noinline”修饰符声明的单独过程/函数中,该块可能会捕获硬件异常
  • 扩展对生成调试信息的支持。当前支持:
    • 线路信息
    • 全局和局部变量、参数和字段(但还不支持所有类型)
  • 添加对生成更多元信息以进行优化的支持(例如,有关子范围类型和枚举的范围信息)
  • 向LLVM传递更多与FPC相关的代码生成选项(目前主要传递-CfXXX和-Ox)
  • 添加对基于TLS的threadvar的支持
  • 直接生成位代码(.bc)而不是位代码汇编(.ll)文件。原因是LLVM项目试图确保位码文件的向后兼容性,而不是位码程序集的向后兼容性。FPC目前无论如何都会生成位代码汇编文件,因为它们更容易创建和调试(在调试编译器的LLVM代码生成器的意义上)。

常见问题

FPC团队会在未来的某个时候采用LLVM作为所有平台的后端吗?
否,由于各种原因:
  • LLVM几乎肯定永远不会支持FPC支持的所有目标(Gameboy Advance、OS/2、WinCE等),也不会在某个时候放弃对FPC仍然支持的目标的支持(就像PowerPC/PowerPC64的Mac OS X已经发生的那样)。
  • 本机FPC代码生成器在编写后几乎不需要维护,因为它们通过抽象与编译器的其他部分隔离得很好,所以没有理由放弃它们
  • FPC是一个志愿者/业余项目,几个开发人员的主要兴趣是开发本地FPC代码生成器/优化程序
  • 无论如何,您仍然需要FPC本机代码生成器的一些最难的部分,以便LLVM(进入/退出代码处理、参数管理器)处理汇编程序例程,并且因为LLVM没有完全抽象参数传递
  • 硬件体系结构在发布后很少以破坏后向兼容性的方式进行更改,而LLVM则没有这样的承诺。
  • LLVM一直在发生很大变化。这意味着引入回归的可能性很高。
  • FPC的本机代码生成器比LLVM的要快得多(即使您忽略了FPC生成位代码的开销以及读回位代码的LLVM工具链),因此在开发时使用FPC自己的代码生成器可能更有趣
LLVM编译器是否有可能比目前的FPC产生更好/更快的优化?
  • 这取决于代码的类型。数学越纯(浮点或整数,尤其是在紧循环中),速度越快。
  • 人工基准测试也将更快。
  • 对于典型的数据库程序,不要期望有太多更改。
  • 示例1:在Intel Haswell处理器上使用LLVM进行编译时,x86-64上的编译器本身大约快10%,如果还启用了链接时间优化,则速度快18%。
  • 示例2:AViprinet基准为ARMv7编译,在APM野马X-Gene板上运行:速度提高18%.

另请参见