仔细看一下Via-IR

本文详细介绍了Solidity编译器的新via-IR编译管道,该管道使用Yul作为中间表示,以便在生成EVM字节码之前进行优化。文章探讨了via-IR的动机、特性和转变为默认编译管道的计划,以及与传统编译流程的比较。

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

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

compilation-pipelines

在这篇博文中,我们将更详细地了解 via-IR, better 理解每个编译步骤,并讨论将 via-IR 作为默认设置的计划。

快速回顾

让我们先分解一下 via-IR 的含义。

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

这是 Solidity 中一种新的编译管道,通过首先将 Solidity 代码翻译成中间表示(Yul),而不是将 Solidity 代码直接编译为 EVM 字节码,来引入一个中间步骤。 该中间代码可以进一步优化,然后再转换为最终的 EVM 字节码。

基于 IR 的管道旨在不仅使代码生成更透明和可审计,同时也使跨函数和复杂控制流的强大优化过程能够实现。

动机与特征

在我们深入探讨 via-IR 的工作原理之前,了解开发 Yul 及其所带来的 IR 管道的动机可能会有所帮助。

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

Yul(之前也称为 JULIA 或 IULIA)是一种中间语言,作为多种后端的 IR 开发。 编译器将 Yul 作为 via-IR 代码生成器中的中间语言。

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。
  • 对于各种区块链 2 扩展的复杂调整的简便性使 via-IR 代码生成器更灵活。
  • 最后但并非最不重要的是,正如设计动机中所提到的,Yul 被设计得易于人类阅读。无论是未优化还是优化后的 Yul 输出都可以被视为更低级别的目标,以便于更好的审计和验证。

深入探讨 via-IR

传统编译

理解默认编译在没有 via-IR 的情况下是很有帮助的。

Solidity 源代码的默认编译管道目前包含以下步骤:

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

通过 IR 编译

为了启用 via-IR 编译管道,你可以在命令行中使用 --via-ir 或在 standard-json 中使用选项 {"viaIR": true} 打开它。

通过中间表示(Yul)的编译发生在以下步骤中:

  1. 编译器解析 Solidity 源文件。
  2. 与直接将 Solidity 源代码编译为 EVM 汇编不同,新的 IR 代码生成器会先将 Solidity 代码转换为 Yul 代码。
  3. Yul 优化器将不断对 Yul 代码执行优化。
  4. 优化后的 Yul 代码随后通过 Yul→evmasm 代码转换转换为 EVM 汇编。
  5. 该代码非常接近实际的字节码,但仍适合进一步优化,因此按照传统管道步骤运行默认优化器,直到代码被认为充分优化。
  6. 最后,EVM 字节码按照传统管道生成。

挑战与考虑

尽管选择 IR 有很多优势,但它也有其自身的一系列问题。via-IR 的主要挑战之一是因对 Yul 代码的额外优化步骤而导致的更长编译时间。

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

除此之外,还有一些重要的语义变化。你可以在 官方 Solidity 文档 中进一步阅读有关这些变化的信息。

将 via-IR 设为默认

我们在 Solidity Summit 2023 上分享了将新的 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 中无限的 swaps 和 dups 使 Yul 到 EVM 的转换显著更简单且更高效。这将有助于我们消除额外的深度过大的堆栈错误。
  2. 因为 via-IR 和 EOF 升级都涉及到小的语义变化,更新将被视为一个重大变化。将两个功能的发布结合在一起将帮助我们减少 Solidity 开发者的努力和升级负担。

接下来是什么?

via-IR 管道的长期目标是允许在 Solidity 的下一次迭代中从一个灵活性较低的基础模型迁移到一个标准库,并尽可能使新的编译管道(包括优化器)具有未来适应性和高效性。这将使编译器优雅地包容语言要求和 EVM 架构的快速变化。

请关注 Twitter 获取更多关于 via-IR 的更新,并参与官方 Solidity 论坛 中的社区讨论。

  • 原文链接: soliditylang.org/blog/20...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
SolidityLang
SolidityLang
https://soliditylang.org/