llvm clang_什么是LLVM? Swift,Rust,Clang等的强大功能

llvm clang

新语言以及对现有语言的改进在整个开发环境中如雨后春笋般冒出。 Mozilla的Rust , 苹果的Swift , Jetbrains的Kotlin以及许多其他语言为开发人员提供了速度,安全性,便利性,便携性和功能性方面的新选择。

为什么现在? 一个重要的原因是用于构建语言的新工具,特别是编译器。 其中最主要的是LLVM ,这是一个由Swift语言创建者Chris Lattner最初开发的开源项目,是伊利诺伊大学的一项研究项目。

[ 同样在InfoWorld上:我们应该担心“公司”编程语言吗? ]

LLVM不仅使创建新语言更加容易,而且使现有语言的开发更加容易。 它提供了用于自动执行语言创建任务中许多最令人不快的部分的工具:创建编译器,将输出的代码移植到多个平台和体系结构,生成特定于体系结构的优化(例如矢量化)以及编写代码以处理诸如通用语言隐喻之类的代码例外情况。 它的自由许可意味着它可以作为软件组件自由重用,也可以作为服务部署。

使用LLVM的语言花名册有许多熟悉的名称。 Apple的Swift语言使用LLVM作为其编译器框架,Rust使用LLVM作为其工具链的核心组件。 此外,许多编译器都有LLVM版本,例如Clang,C / C ++编译器(此名称为“ C-lang”),它本身就是与LLVM紧密相关的项目。 .NET实现Mono可以选择使用LLVM后端编译为本地代码 。 而且Kotlin,名义上是JVM语言,正在开发一种称为Kotlin Native的语言版本,该版本使用LLVM编译为机器本地代码。

LLVM定义

LLVM的核心是用于以编程方式创建机器本地代码的库。 开发人员使用API​​以称为中间表示或IR的格式生成指令。 然后,LLVM可以将IR编译为独立的二进制文件,或者对代码执行JIT(即时)编译,以在其他程序的上下文中运行,例如该语言的解释器或运行时。

LLVM的API提供了用于开发许多通用语言和编程语言的原语。 例如,几乎每种语言都具有函数和全局变量的概念,并且许多语言都具有协程和C外部函数接口。 LLVM在其IR中将函数和全局变量作为标准元素,并具有用于创建协程和与C库接口的隐喻。

您无需花费时间和精力来重新设计那些特定的轮子,您只需使用LLVM的实现,并专注于需要注意的语言部分。

llvm clang_什么是LLVM? Swift,Rust,Clang等的强大功能_第1张图片 IDG

LLVM的中间表示(IR)的示例。 右边是一个用C语言编写的简单程序。 左侧是Clang编译器翻译成LLVM IR的相同代码。

阅读有关Go,Kotlin,Python和Rust的更多信息

走:

  • 发挥Google Go语言的强大功能
  • 最好的Go语言IDE和编辑器

Kotlin:

  • 什么是Kotlin? Java替代说明
  • Kotlin框架:JVM开发工具概述

Python:

  • 什么是Python? 您需要知道的一切
  • 教程: 如何开始使用Python
  • 每个Python开发人员都有6个基本库

锈:

  • 什么是锈? 安全,快速,轻松进行软件开发的方式
  • 了解如何开始使用Rust

LLVM:专为可移植性而设计

要理解LLVM,可能需要考虑与C编程语言的类比:C有时被描述为一种可移植的高级汇编语言,因为它的结构可以紧密地映射到系统硬件,并且已经移植到了几乎每个系统架构。 但是C只是作为一种便携式汇编语言才有用。 它不是为特定目的而设计的。

相比之下,LLVM的IR从一开始就被设计为便携式组件。 实现这种可移植性的一种方法是通过提供独立于任何特定机器体系结构的原语。 例如,整数类型不限于底层硬件的最大位宽(例如32或64位)。 您可以使用所需的任意位数(例如128位整数)来创建原始整数类型。 您也不必担心制作输出以匹配特定处理器的指令集的情况; LLVM也会为您解决这一问题。

LLVM与体系结构无关的设计使支持现在和将来的各种硬件变得更加容易。 例如, IBM最近贡献了代码来支持z / OS,Linux on Power(包括对IBM MASS矢量化库的支持 )以及LLVM的C,C ++和Fortran项目的AIX体系结构。

如果要查看LLVM IR的实时示例,请访问ELLCC Project网站,并尝试在浏览器中将C代码转换为LLVM IR的实时演示 。

[ 同样在InfoWorld上:为什么C编程语言仍会统治 ]

编程语言如何使用LLVM

LLVM最常见的用例是作为一种语言的提前(AOT)编译器。 例如,Clang项目提前将C和C ++编译为本机二进制文件。 但是LLVM也使其他事情成为可能。

LLVM即时编译

在某些情况下,需要在运行时动态生成代码,而不是提前编译。 例如, Julia语言使用 JIT编译其代码,因为它需要快速运行并通过REPL(读-评估-打印循环)或交互式提示与用户进行交互。

Numba是用于Python的数学加速包,它通过JIT将选定的Python函数编译为机器代码。 它也可以提前编译用Numba装饰的代码,但是(像Julia一样)Python通过作为一种解释语言来提供快速的开发。 与预先编译相比,使用JIT编译产生这样的代码可以更好地补充Python的交互式工作流。

其他人正在尝试使用LLVM作为JIT的新方法,例如编译PostgreSQL查询 ,从而使性能提高五倍。

llvm clang_什么是LLVM? Swift,Rust,Clang等的强大功能_第2张图片 IDG

Numba使用LLVM即时编译数字代码并加快其执行速度。 JIT加速的sum2d函数完成其执行的速度比常规Python代码快139倍。

LLVM自动代码优化

LLVM不仅将IR编译为本机代码。 您还可以以编程方式将其定向以在整个链接过程中一直以较高的粒度来优化代码。 优化可能非常激进,包括内联函数,消除无效代码(包括未使用的类型声明和函数参数)以及展开循环。

同样,其功能在于不必自己执行所有这些操作。 LLVM可以为您处理它们,或者您可以指导它根据需要将其关闭。 例如,如果您希望以较小的性能为代价来使用较小的二进制文件,则可以让编译器前端告诉LLVM禁用循环展开。

LLVM特定领域的语言

LLVM已被用来为许多通用语言生成编译器,但它对于生成高度垂直或问题域专有的语言也很有用。 在某些方面,这是LLVM发光最亮的地方,因为它消除了创建这种语言的繁琐工作,并使其表现出色。

例如, Emscripten项目采用LLVM IR代码并将其转换为JavaScript,从理论上讲,任何具有LLVM后端的语言都可以导出可在浏览器中运行的代码。 长期计划是要有可以产生WebAssembly的基于LLVM的后端,但是Emscripten是LLVM可以多么灵活的一个很好的例子。

LLVM可以使用的另一种方法是向现有语言添加特定于域的扩展。 Nvidia使用LLVM创建了Nvidia CUDA编译器 ,该语言使语言可以添加对CUDA的本机支持,而CUDA可以作为生成的本机代码的一部分(更快)进行编译,而不是通过附带的库来调用(更慢)。

LLVM在特定领域语言方面的成功促使LLVM中的新项目解决了它们所产生的问题。 最大的问题是,如何在不进行大量前端工作的情况下很难将某些DSL转换为LLVM IR。 工作中的一种解决方案是多层中间表示或MLIR项目 。

MLIR提供了表示复杂数据结构和操作的便捷方法,然后可以将它们自动转换为LLVM IR。 例如, TensorFlow机器学习框架可以使用MLIR将其许多复杂的数据流图操作有效地编译为本机代码。

[ 也在InfoWorld上:什么是WebAssembly? 下一代Web平台的解释 ]

使用各种语言的LLVM

使用LLVM的典型方法是通过使用一种您喜欢的语言编写代码(当然,该语言支持LLVM的库)。

两种常见的语言选择是C和C ++。 许多LLVM开发人员默认使用这两种方法之一是出于以下几个原因:

  • LLVM本身是用C ++编写的。
  • LLVM的API具有C和C ++版本。
  • 以C / C ++为基础的语言开发工作往往会很多

尽管如此,这两种语言并不是唯一的选择。 许多语言都可以本地调用C库,因此从理论上讲,可以使用任何这种语言执行LLVM开发。 但是,使用优雅地包装LLVM API的语言来创建一个实际的库会有所帮助。 幸运的是,许多语言和语言运行库都具有这样的库,包括C#/。NET / Mono , Rust , Haskell , OCAML , Node.js , Go和Python 。

一个警告是,与LLVM的某些语言绑定可能不如其他语言完整。 以Python为例,有很多选择,但是每种选择的完整性和实用性各不相同:

  • llvmlite ,由创建Numba团队开发,已成为当前的竞争者在Python与LLVM工作。 根据Numba项目的需求,它仅实现LLVM功能的一部分。 但是该子集提供了LLVM用户所需的绝大多数。 (llvmlite通常是在Python中使用LLVM的最佳选择。)
  • LLVM项目维护自己的与LLVM的C API 的绑定集 ,但目前未维护。
  • llvmpy是LLVM的第一个流行的Python绑定,于2015年退出维护。对于任何软件项目而言 ,这都是不利的 ,但考虑到每个LLVM版本都会带来许多更改,使用LLVM时更糟。
  • llvmcpy旨在使C库的Python绑定保持最新状态,以自动化方式对其进行更新,并使用Python的本机惯用语对其进行访问。 llvmcpy仍处于早期阶段,但是已经可以使用LLVM API进行一些基本的工作。

如果您对如何使用LLVM库构建语言感到好奇,则LLVM自己的创建者提供了使用C ++或OCAML的教程 ,该教程将逐步引导您创建一种称为Kaleidoscope的简单语言。 此后已移植到其他语言:

  • Haskell :原始教程的直接移植。
  • Python: 一个类似的端口紧跟本教程,而另一个则是使用交互式命令行进行更雄心勃勃的重写 。 两者都使用llvmlite作为LLVM的绑定。
  • RustSwift :不可避免地,我们会将本教程的端口移植到LLVM帮助实现的两种语言中。

最后,该教程还提供人类语言版本。 使用原始的C ++和Python将其翻译成中文。

LLVM不能做什么

LLVM确实提供了所有功能,因此也知道不执行的操作很有用。

例如,LLVM不会解析语言的语法。 许多工具已经可以完成这项工作,例如lex / yacc , flex / bison , Lark和ANTLR 。 无论如何,解析都是要与编译分离的,因此LLVM不会尝试解决这些问题也就不足为奇了。

LLVM并没有直接解决围绕给定语言的大型软件文化。 安装编译器的二进制文件,在安装中管理软件包以及升级工具链-您需要自己完成。

[ 通过InfoWorld的App Dev Report新闻通讯了解软件开发中的热门话题 ]

最后,也是最重要的一点,LLVM仍然有一些通用的语言部分,它们不提供原语。 许多语言都有某种方式的垃圾回收内存管理,既可以作为管理内存的主要方式,也可以作为RAII之类的策略(C ++和Rust使用)的辅助。 LLVM并没有为您提供垃圾收集器机制,但是它确实提供了通过允许用元数据标记代码来实现垃圾收集的工具 ,从而使编写垃圾收集器变得更加容易。

但是,这一切都不能排除LLVM最终可能添加用于实现垃圾回收的本机机制的可能性。 LLVM发展Swift,每六个月左右发布一次主要版本。 而且由于许多当前语言已将LLVM置于其开发过程的核心,因此开发速度可能只会加快。

翻译自: https://www.infoworld.com/article/3247799/what-is-llvm-the-power-behind-swift-rust-clang-and-more.html

llvm clang

你可能感兴趣的:(c++,大数据,编程语言,python,java)