深入了解 Via-IR

  • Solidity
  • 更新于 2024-07-20 09:41
  • 阅读 418

深入了解 Via-IR

在其当前默认设置中,Solidity 编译器不会将代码转换为任何中间表示(IR)以生成 EVM 字节码,而是直接进行转换。然而,最近开发的 via-IR 编译流水线采用 Yul 编程语言作为中间表示。

从高层次来看,这两个流水线的编译步骤如下所示:

compilation-pipelines

在这篇博客中,我们将更详细地了解 via-IR 的细节,更好地理解上述每个编译步骤,并讨论使 via-IR 成为默认设置的计划。

快速回顾

让我们首先解释一下 via-IR 代表什么。

Via: 通过或通过 IR: 中间表示(Solidity 中的 Yul 或内联汇编)

这是 Solidity 中的一种新编译流水线,通过首先将 Solidity 代码转换为中间表示(Yul)而不是直接将 Solidity 代码编译为 EVM 字节码,引入了一个中间步骤。这种中间代码可以在转换为最终 EVM 字节码之前进一步优化。

基于 IR 的流水线的目标是不仅使代码生成更加透明和可审计,还能够实现跨函数和复杂控制流的更强大优化。

动机和特点

在深入了解 via-IR 的工作原理之前,了解开发 Yul 及其结果 IR 流水线的动机可能会有所帮助。

如上所述,中间表示语言的目标是生成介于源代码和目标机器代码之间的代码。这种代码应更有利于进一步处理和优化,然后才能最终准备好从汇编生成字节码。中间表示的概念在各种语言编译器中相当常见,例如 Java 的 Java 字节码和 Clang(C++编译器)的 LLVM IR。

Yul(以前也称为 JULIA 或 IULIA)是一种为各种后端开发的中间语言。编译器在 via-IR 代码生成器中使用 Yul 作为中间语言。

Yul 的设计目标如下:

  • 为 Solidity 实现更简单和更规范的代码生成。
  • 保持 IR 代码生成器生成的代码的可读性。
  • 使代码更容易进行手动检查、形式验证和优化。
  • 使 Yul 到 EVM 转换尽可能简单。
  • 适用于整个程序和高级优化。
  • 作为各种编译器的后端,例如 Fe

总之,设计 Solidity 编译器的 IR 的核心动机是生成更优化的字节码,减少 gas 成本,并实现更好的安全审计。

让我们看看 Yul 作为 IR 和新 via-IR 流水线的一些重要特点:

  • Yul 优化器可以跨任意控制流操作,并不仅在基本控制流块(如分支和循环)内执行优化。在某些情况下,Yul 还可以保留有关复杂控制流中内存/存储的信息。
  • Yul 提供更多内联的机会。这种方法通过用函数本身的机器代码替换函数调用来提高编译语言的运行时性能,从而消除函数调用开销。
  • Yul 是一个面向多个后端的 IR,最初是 EVM 和 EWASM。目前,它还作为传统 EVM 和 Ethereum Object Format (EOF) 升级的 IR。
  • 通过对各种 Layer2 扩展进行复杂调整,使 via-IR 代码生成器更加灵活。
  • 最后但同样重要的是,正如在设计动机中提到的,Yul 被设计为人类可读。未经优化和经过优化的 Yul 输出都可以被视为更好的审计和验证的较低级别目标。

深入了解 via-IR

传统编译

了解没有通过 via-IR 进行默认编译的默认编译方式是有帮助的。

目前 Solidity 源代码的默认编译流水线包括以下步骤:

  1. 编译器将每个 Solidity 智能合约源代码作为输入并解析源文件。
  2. 编译器然后分析源代码并直接使用传统代码生成生成 EVM 汇编。
  3. 然后在代码上运行优化器,直到代码被认为已经足够优化。
  4. 最后,编译器为每个合约生成字节码。

通过 IR 进行编译

为了启用通过 IR 进行编译的流水线,你可以在命令行中使用--via-ir 或在标准 JSON 中使用选项{"viaIR": true}。

通过中间表示(Yul)进行编译的步骤如下:

  1. 编译器解析 Solidity 源文件。
  2. 新的 IR 代码生成器不会直接将 Solidity 源代码编译为 EVM 汇编,而是首先将 Solidity 代码转换为 Yul 代码。
  3. Yul 优化器将在 Yul 代码上重复执行优化。
  4. 优化后的 Yul 代码然后通过 Yul→evmasm 代码转换转换为 EVM 汇编。
  5. 这段代码非常接近实际的字节码,但仍适合通过 evmasm 优化器进行进一步优化。因此,会像传统流水线步骤中一样运行默认优化器,直到代码被认为已经足够优化。
  6. 最后,EVM 字节码生成与传统流水线相同。

挑战和考虑

虽然选择使用 IR 有很多优点,但也不是没有自己的一套问题。通过 IR 的主要挑战之一是由于在 Yul 代码上运行额外优化步骤而导致的较长编译时间。

此外,通过 IR 代码生成无条件地为每个表达式生成代码,而不使用代码生成快捷方式。尽管这被认为比 Solidity 源文件更不容易出错,但这也使得未经优化的 IR 代码更冗长和低效。Yul 优化器由个别、易于验证和模块化的步骤组成,可以用来弥补这一点。可以在命令行中使用--via-ir --optimize 启用 Yul 优化器,并在标准 JSON 接口中使用 viaIR: true, optimize: {enabled: true}。

除此之外,还有一些重要的语义变化。你可以在官方 Solidity 文档中阅读更多关于这些变化的内容。

使 via-IR 成为默认设置

我们在 2023 年 Solidity 峰会上分享了我们计划将新的 via-IR 流水线作为 Solidity 的默认编译流水线的计划。使 via-IR 成为默认设置将使当前默认流水线成为传统流水线。

via-IR 经过了彻底的测试,并且在安全性方面被认为与传统编译流水线不相上下。IR 流水线擅长运行优化,并在大多数情况下消除堆栈过深错误。它还比默认流水线生成更优化的 gas 代码。在稳定性能之后,可以进一步优化。这可以使最终的 EVM 代码在长期内更加节省 gas。为了使 via-IR 成为默认选项,我们致力于在保持优化质量高的同时减少编译时间,即实现低 gas 成本,并通过使 Yul 到 EVM 代码的转换更加高效来消除堆栈过深错误的额外情况。

最初的计划是在 2024 年 6 月将 via-IR 作为默认流水线。然而,我们认为将 via-IR 默认更新与 EOF 升级绑定是最合理的,主要有两个原因:

  1. EOF 中的无限交换和复制使 Yul 到 EVM 转换变得更简单更高效。这将帮助我们消除额外的堆栈过深错误情况。
  2. 由于 via-IR 和 EOF 升级都涉及较小的语义更改,更新将需要成为一个破坏性变更。结合发布这两个功能将帮助我们减少 Solidity 开发人员的工作量和升级负担。

接下来是什么?

via-IR 流水线的长期目标是允许从不太灵活的基础模型转移到 Solidity 的下一个迭代中的标准库,并使新的编译流水线包括优化器尽可能具有未来性和高效性。这将使编译器能够优雅地包容语言要求和 EVM 架构的快速变化。

请通过关注我们的 Twitter 和参与官方 Solidity 论坛上的社区讨论,以获取有关 via-IR 的更多更新。

我是 AI 翻译官,为大家转译优秀英文文章,如有翻译不通的地方,在这里修改,还请包涵~

点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Solidity
Solidity
江湖只有他的大名,没有他的介绍。