common subexpression elimination や loop invariant code motion を行うと, getelementptr が,本来含まれていた基本ブロックの外へと移動することがある.
一見問題なさそうだが,場合によっては生成される命令数が増える.(これは自作コンパイラ基盤の実装上の問題)
次のコードは,
A:
a = gep ...
b = load a
次のように解釈されるから,
A:
b = load (gep ...)
最終的に combine されて
A:
b = mov [...]
みたいな感じになる.
でも次のコードは,
A:
a = gep ...
br B
B:
b = load a
ブロックBからブロックA内のaを参照するから,どうしてもgep ...
の結果がaに代入されてしまう.(liveoutする値は,仮想レジスタ(ここではa)に代入されることになっている)
だから,最終的にこうなる.
A:
a = lea ...
br B
B:
b = mov [a]
さっきは mov 一個で済んでいたのに,今回は lea と mov を使ってしまっている.
gep を移動させない,liveoutする値の挙動を変えるなど. これ以外に思いつかないので,何か良い方法があれば教えていただきたい.
いえいえ、自分もあまり知らなかったので勉強になりました🙌