SSA:终于知道编译器偷摸做了哪些事

你好,我是轩脉刃。

在golang中,我们可以使用 go tool compile -S main.go 工具将一个go程序直接转换为汇编代码。但是你会发现,最终编译出来的汇编代码其实是已经被优化过了的,编译器其实很聪明,甚至将一些函数合并,取消等。至于这个过程,并不是一蹴而就的,在golang代码和最终的汇编代码中,还有一种中间的代码结构,这个结构就叫做SSA (Static Single Assignment) 静态单赋值。

这个中间的代码结构是有必要存在的,go源码解析后是一个AST树,是一个树形结构,而最终的汇编是一条一条的线性命令。将树形结构转化拆分优化为汇编命令是比较复杂的。所以这里将这么一个大的步骤分成两步走,能大大降低编译器优化的难度。

SSA:终于知道编译器偷摸做了哪些事

怎么生成ssa

我们可以使用命令 GOSSAFUNC=Foo go build index.go 来看我们将一个go源码,怎么转化为SSA的全过程的。

go代码

package array

func Foo () int {
    a := [3]int{1,3,5}
    i := 2
    elem := a[i]
    return elem
}

SSA:终于知道编译器偷摸做了哪些事

生成ssa.html

怎么看ssa

SSA:终于知道编译器偷摸做了哪些事

这个html中的ssa中间语言的语法是由 cmd/compile/internal/ssa/gen/genericOps.go 生成的。

SSA:终于知道编译器偷摸做了哪些事

每一行和对应的SSA代码都标记出来了,有一些即使没有SSA的经验,也是能立马看懂的。比如像v10 是常量1,而v13是代表指针指向a[0], v14 代表将常量1存储进入a[0]。不过有一些则不是那么容易看出了。

通过中间可以看出过了很多优化步骤才最终生成了汇编码。

SSA:终于知道编译器偷摸做了哪些事

有哪些步骤可以参考这里:https://github.com/golang/go/blob/release-branch.go1.15/src/cmd/compile/internal/ssa/compile.go#L418

至于每个步骤做了什么事情,这个就很复杂了。

关于ssa

关于ssa,我自己的理解就是,将源码的AST树,先演变成像

v1= xxx
v2= xxx
v3= xxx

这种线性执行语句。这种语句的特点就是每一行都定义了一个变量。所以叫”静态单赋值语句”。然后使用各种之间的赋值规则,可以很容易看出哪些赋值变量其实是没有用到的。对于没有用到的直接可以删除。当然还有其他各种规则,最终将v1…vn的赋值变量进行预计算,优化,最后优化为最简的几个赋值变量。这点可以从ssa.html的start到最后的trim就看出了。

最开始的源码

SSA:终于知道编译器偷摸做了哪些事

切换为AST树

SSA:终于知道编译器偷摸做了哪些事

再变成SSA语言

SSA:终于知道编译器偷摸做了哪些事

经过不断优化,变成三个执行语言。(其实这个foo函数直接可以在编译阶段将5返回)

SSA:终于知道编译器偷摸做了哪些事

最后再变化为汇编码:

SSA:终于知道编译器偷摸做了哪些事

这个编译器优化的过程,我感觉对于语言使用者还是主要适用于纯研究。

比如想研究下数组是在栈上分配内存还是在静态数据区分配内存,可以生成ssa看看。

或者想研究下哪行代码对应哪个内部函数等。

参考:

https://gocompiler.shizhz.me/10.-golang-bian-yi-qi-han-shu-bian-yi-ji-dao-chu/10.2.1-ssa

https://oftime.net/2021/02/14/ssa/

https://draveness.me/golang/docs/part1-prerequisite/ch02-compile/golang-ir-ssa/

https://github.com/golang/go/blob/master/src/cmd/compile/internal/ssa/README.md

https://en.wikipedia.org/wiki/Static_single_assignment_form

Original: https://www.cnblogs.com/yjf512/p/15719493.html
Author: 轩脉刃
Title: SSA:终于知道编译器偷摸做了哪些事

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/554362/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • docker学习:docker镜像

    镜像是什么 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。 Uni…

    技术杂谈 2023年7月10日
    0135
  • 树状数组

    简述 什么是树状数组呢,顾名思义就是树一样的数组,本质就是用数组模拟树形结构。 树状数组有什么用呢,树状数组可以实现单点更新,单点查询,区间查询和区间更新,维护的东西和线段树可以类…

    技术杂谈 2023年7月11日
    099
  • WSL 一例运行时提示access denied解决办法

    我的是默认wsl1,所以导入时候是wsl1版本,通过网上的删补丁之类的方法没有解决问题(不存在对应补丁),尝试升级为wsl2解决。 本博客是个人工作中记录,遇到问题可以互相探讨,没…

    技术杂谈 2023年6月1日
    0115
  • HTTP状态管理机制之Cookie

    一、cookie 起源 cookie 最早是网景公司的雇员 Lou Montulli 在1993年3月发明,后被 W3C 采纳,目前 cookie 已经成为标准,所有的主流浏览器如…

    技术杂谈 2023年6月1日
    0107
  • python3GUI–天气预报小工具By:PyQt5(附源码)

    @ 一.准备工作 二.预览 1.启动 2.添加城市 三.设计流程 1.UI设计(草图) 2.UI设计(QT设计师) 3.解释 四.源代码 五.总结 之前用tk写过一款python3…

    技术杂谈 2023年6月21日
    0131
  • crontab定时任务

    (1)任务配置格式 crontab任务配置基本格式: * *  *  *  * &#…

    技术杂谈 2023年7月24日
    086
  • svg图标爽使用

    svg图标爽使用 一、总结 一句话总结: 【网站】:https://iconpark.oceanengine.com/official: 在这个网站可以选择好颜色和样式直接下载下来…

    技术杂谈 2023年5月31日
    0108
  • 小知识:vi如何使用列编辑模式快速插入

    经常需要用到列编辑这种操作,现在很多超文本的编辑器都可以轻松实现。但有时需要在vi界面直接使用,但是vi的列编辑操作因不常使用总是忘记现查。这次干脆记录下加深印象。vi编辑某个文本…

    技术杂谈 2023年5月31日
    0168
  • Mysql整体介绍(适用于5.X版本)(上)

    Mysql整体介绍(适用于5.X版本)(标贝科技) Mysql 8.X版本和 5.X版本相比,有比较大的调整。目前工作中应用最广的是Mysql 5.6/5.7的版本,所以文章将聚焦…

    技术杂谈 2023年7月25日
    0102
  • vnpy源码阅读学习(8):关于app

    关于app 在入口程序中,我们看到了把 gateway, app, 各类的 engine都添加到 mainEngine中来。不难猜测 gateway主要是处理跟外部的行情,接口各方…

    技术杂谈 2023年7月11日
    0105
  • coroot-pg-agent 专注性能的pg promtheus exporter

    尽管已经有不少pg 的prometheus exporter 了,但是coroot-pg-agent 是关注与查询性能统计的还是很支持使用的pmm 也是支持pg 的,同时基于pro…

    技术杂谈 2023年5月30日
    0116
  • sqlalchemy insert or ignore

    insert ignore 批量操作 https://github.com/pallets/flask-sqlalchemy/issues/241 https://docs.sql…

    技术杂谈 2023年7月11日
    092
  • 吐血整理Java编程基础入门技术教程,免费送

    Java标识符的命名规则 使用Unicode字符集,以字母,下划线”_”,美元符号”$”,后面可以跟字母,下划线,美元符号和数字。 …

    技术杂谈 2023年6月21日
    0107
  • 前端调用突然都是406

    maven依赖飘红,没有正确导入jackson的依赖,删除idea相关文件,重新打开项目,重新加载依赖即可 Original: https://www.cnblogs.com/bi…

    技术杂谈 2023年7月11日
    090
  • 期末代码

    使用Java的输入输出流将一个文本文件的内容按行读出,每读出一行,就顺序添加行号,并写入到另一个文件中。 import java.io.*; public class E { pu…

    技术杂谈 2023年6月21日
    0100
  • 密码学入门

    原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 简介 在信息安全领域,一般会遇到”窃听”、”篡改”、…

    技术杂谈 2023年7月25日
    0121
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球