Help us understand the problem. What is going on with this article?

Goのssa.htmlの変更点まとめ2018

More than 1 year has passed since last update.

Go2 Advent Calendar 2018 20日目の記事です。
空きを見つけたので代筆させていただきます。

はじめに

Goコンパイラの中間表現として採用されているSSA(Static Single Assignment)の小ネタです。

SSA(静的単一代入)についてはWikipediaが詳しいのでご覧ください。

GoコンパイラにはSSA形式が最適化パスを通してどのように変化してくのかをHTMLファイル(ssa.html)にダンプする機能があります。この記事ではssa.htmlが2018年にどのように進化していったかをコミットログから追っていきます。

ssa.htmlの作り方

$ env GOSSAFUNC=main go build

コンパイル時に環境変数GOSSAFUNCに関数名をセットすることで、ssa.htmlを生成できます。

後述しますが、2017年はGOSSAFUNCには単に関数名を指定するだけでしたが、2018年の変更で複雑な指定もできるようになりました。

変更点

では、以降でどのような変更があったかを見ていきます。変更は

  • 現在の最新安定版(Go11.4)までに入っているもの
  • まだmaster(go1.12beta1)にしか入っていないもの

に分けて見ていきます。

変更点は、ssa.htmlを生成しているcmd/compile/internal/ssa/html.goのコミットログから調べました。

今回解析対象としたコードは以下のサンプルのssa関数です。Wikipediaの例を拝借しました。

package main

import "fmt"

func ssa() {
        var w, x, y, z int

        x = 5
        x = x - 3
        if x < 3 {
                y = x * 2
                w = y
        } else {
                y = x - 3
        }
        w = x - y
        z = x + y

        fmt.Printf("%d, %d\n", w, z)
}

func main() {
        ssa()
}

1.9.2〜1.11.4の変更点

昨年末の最新版Go1.9.2と現在の最新版Go1.11.4ssa.htmlがどのくらい違うのか比べて見ましょう。

大きく違うのはいくつかの最適化パスが折りたたまれていることでしょうか。

では、順に見ていきます。

Jul 28, 2017 (1.10beta1-) Goコードの変数名が出力されるように

[dev.debug] cmd/compile: better DWARF with optimizations on

SSA形式の変数名だけでは元のコードのどの変数だったのかが分かりづらかったのですが、この変更によって対応する変数が表示されるようになりました。
この変更自体は、最適化によって失われていた変数の位置情報をコンパイラオプション-dwarflocationlistsによってデバッグ情報として付与できるようにした、
というものです。

-dwarflocationlistsオプションについては以下に少し書いてあります
https://tip.golang.org/doc/diagnostics.html#debugging

Aug 18, 2017 (1.10beta1-) (リファクタリングなのでスキップ)

cmd/compile: rename SSA Register.Name to Register.String

Oct 12, 2017 (1.10beta1-) 変数に対応する行数が表示されるように

cmd/compile: add line numbers to values & blocks in ssa.html

元のコードの行数がSSAの変数の横に括弧書きされるようになりました。

Apr 5, 2018 (go1.11beta1-) IsStmtによって行数の表示が変わるように

cmd/compile: add IsStmt breakpoint info to src.lico

Includes changes to html output for GOSSAFUNC to indicate
not-default is-a-statement with bold and not-a-statement
with strikethrough.

https://github.com/golang/go/commit/619679a3971fad8ff4aa231d7942c95579ceff23#diff-8cd6c5dd336a16009909e578d8b6fcb3R394

この変更時点ではIsStmtマークは使われていませんが、現在は例えば以下の演算で行番号がストライクアウトされます。
https://github.com/golang/go/blob/release-branch.go1.11/src/cmd/compile/internal/ssa/numberlines.go#L62

Jun 14, 2018 (go1.11beta1-) 最適化の各フェーズの列を折り畳めるように

cmd/compile: use expandable columns in ssa.html

デフォルトでは以下の名前で始まるパスが最初から広がっており(html.go#L297)、それ以外は折りたたまれるようになりました。パス名の辺りをクリックすることで畳んだり広げたりできます。

  • "start"
  • "deadcode"
  • "opt"
  • "lower"
  • "late deadcode"
  • "regalloc"
  • "genssa"

Jun 16, 2018 (go1.11beta1-) 選択した時の色の種類が増えました

cmd/compile: add more color choices to ssa.html

ブロックや各行を選択するたびに別の色でハイライトされますが、この色が5色ほど増えました。

1.12(予定)以降の変更点

まだmasterブランチにしか入ってませんが、かなり変更が入っていますので紹介しておきます。全て@ysmolskyさんによるものです。

Go1.11.4と最新リリースのGo1.12beta1でssa.htmlがどのくらい違うのか比べて見ましょう。

ソースコードやAST、そしてCFG(Control Flow Graph)が追加されています。

では、1つずつ見ていきます。

Aug 23, 2018 Goの元のソースコードがssa.htmlに含まれるように

cmd/compile: display Go code for a function in ssa.html

今まではSSA形式に変換されてからの変遷でしたが、元のソースコードと対応づけて表示できるようになりました。

Aug 23, 2018 ssa.htmlの出力パスが標準出力に表示されるように

cmd/compile: clean the output of GOSSAFUNC

この変更は、GOSSAFUNCをつけたときに標準出力に表示される大量のデバッグプリントを抑制するためのものです。従来のようにデバッグプリントが必要な時はGOSSAFUNC=Foo+のように関数名の後ろに+をつければよいです。ssa.htmlの内容に変化はありませんが、html.goの中ではssa.htmlの出力パスを表示するよう変更になりました。

Aug 23, 2018 ソースコードにインライン展開後のソースが追加

cmd/compile: add sources for inlined functions to ssa.html

https://github.com/golang/go/issues/25904

インライン展開された関数がソースコードの列に追加されるようになりました。

Aug 25, 2018 ソースコードとSSAの間にASTの列が追加

cmd/compile: display AST IR in ssa.html

https://github.com/golang/go/issues/26662

ソースコードとSSAの間にAST(Abstract Syntax Tree)の列が入りました。ソースコード⇔AST⇔SSA間も対応づけてハイライトされます。

Sep 19, 2018 [bug fix]

cmd/compile/internal/ssa: fix a == a to a == b

Goのソースコードの列の関数の順序の計算が間違ってました。

Oct 17, 2018 タブ幅を狭く

cmd/compile: make tabs narrow in src column of ssa.html

Goのソースコードのインデントのタブ幅を狭くしました。

Oct 25, 2018 ヘッダの高さを控えめに

cmd/compile: reduce the size of header in ssa.html

関数名とヘルプで上部領域が埋まってたので調整したようです。
毎日見ていると、この高さが気になるのでしょう。

Nov 21, 2018 各フェーズのCFGを表示できるように

cmd/compile: add control flow graphs to ssa.html

大きめの機能が入りました。各フェーズにCFG(Control Flow Graph)を表示できるようになりました。コミットログにも書かれていますが、関数名の後ろに次の指定をすることでCFGが生成されます。

:*            - dump CFG for every phase
:lower        - just the lower phase
:lower-layout - lower through layout
:w,x-y        - phases w and x through y

サンプルはこちらでも確認できます。

https://github.com/golang/go/issues/28177

実行には、graphviz(dotコマンド)が必要です。SVG出力したものがssa.htmlに埋め込まれています。SSAの各ブロックを選択するとそれ対応してCFGのノードがハイライトされます。反対にノードを選択すると対応するブロックが選択されます。

細かい話ですが、先ほど紹介した「Aug 23, 2018 ssa.htmlの出力パスが標準出力に表示されるように」で末尾に「+」を追加するとデバッグプリントが表示されるのは、この形式になっても有効です。

# 全フェーズでCFGを生成、デバッグプリントも表示
$ env GOSSAFUNC=ssa:*+ go build main.go

Nov 22, 2018 ↑の手直し

cmd/compile: fix TestFormats by using valid formats

Nov 24, 2018 ブロックが畳めるように

cmd/compile: make ssa blocks collapsable in ssa.html

小さいですが各ブロックの右上に-ボタンが追加されました。押すとブロックを畳めます。

まとめ

2018年に導入されたssa.htmlへの変更点をまとめました。主に次の変更点がありました。

  • 元のソースコードとの対応づけ強化
  • CFG表示
  • 最適化パスやブロックの折りたたみ
  • 色数増加

go1.12がリリースされた際にはお試しください。

それでは良いお年を。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away