KazuminEngine

プログラマーの日記

golang(cgo)コンパイラのcopyelim最適化パスについて

golangコンパイラの処理系のcgoコンパイラの最適化パスを適当に解説していく記事です。

今回は、copy eliminationです。copy 駆除(削除)ですね。

たぶん、以下を持って助長だと判断して、elimするようです。

a = b;c = a;

だと思います。

c = b 

でいいよね。たぶん。

COPY

opのCOPYってのは、型変換みたいなmov命令系のことだと思います。

機械語を吐く、以下のコードから推測しました。

ちなみに、レジスタが同じだったら、そもそも機械語を吐かないことになってますね。

case ssa.OpCopy: // TODO: use MOVLreg for reg->reg copies instead of OpCopy?
        if v.Type.IsMemory() {
            return
        }
        x := v.Args[0].Reg()
        y := v.Reg()
        if x != y {
            opregreg(s, x86.AMOVL, y, x)
        }

cgo

肝心の処理系のコードですが、説明むずかしいので、ほぼ無しです

めっちゃ適宜コード削除しているので、しっかり読みたい方は、本家を見ましょう。

go/copyelim.go at master · golang/go · GitHub

func copyelim(f *Func) {
    //すべてのvalueの引数(arg)の0番目のopがCOPYだったら、wに入れて、そして、wをvの引数に戻す。
    //a = b;c = a; が c = bになる感じだと思います多分。
    //コピーが入れ子になってるから、浅くしようね。といった感じです。

    for _, b := range f.Blocks {
        for _, v := range b.Values {
            w := v.Args[0]

            //適宜書き換えたので、無限ループになっちゃう感じだけど、
            //forじゃなくてifの方がわかりやすいかもしれない
            for w.Op == OpCopy {
                w = w.Args[0]
            }

            for v != w {
                x := v.Args[0]
                v.SetArg(0, w)
                v = x
            }
        }
    }
}