■
Sethi Ulluman Register Allocation
セシーウルマンレジスタアロケーション
あけましておめでとうございます。 h_sakurai です。今年もよろしくお願いします。
というわけで、<どういうわけだ
レジスタアロケーションを勉強中なわけですが、基本からもう一度勉強してみました。
まず、スタックマシンを使えばレジスタアロケーションをせずに、言語を作る事ができます。
だから、スタックマシンは簡単でいいわけです。
でスタックマシンの次にレジスタアロケーションを簡単に行う方法が、Sethi Ullman Register Allocation です。
このアルゴリズムでは1つのネストした式に対して、レジスタアロケーションを行います。
セシウルマンのアルゴリズムは2つのパートに分かれていまして、
1つ目のパートでは、ラベル名をつけます。
2つ目のパートでは、ラベルを使ってルートから探索して、コードを生成します。
完全ではないかもしれませんが、以下にセシウルマンのレジスタアロケーションのサンプルコードを示します。
ということを、ここ3連休で調べてみてました。
次に、セミグローバルなレジスタアロケーションをやってみて、リニアレジスタアロケーションを把握して、
最後にグラフによるレジスタアロケーションをもう一度見直してみようと思っています。
やっぱり、基本をしっかり押さえないとねっ。
package compiler object SethiUllmanRegisterAllocation { def main(argv: Array[String]) { val exp = ("add", ("mul", "a", "b"), ("add", ("add", "a", "c"), ("mul", "d", "e"))) val rc = visit(null, exp) println(rc) genCode(rc, List("r1"), 1) } def max(a: Int, b: Int): Int = { if (a > b) a else b } def visit(parent: Any, t: Any): (Any, Int) = { (parent, t) match { // 親ノードのとき case (_, (op, n1, n2)) => val (nn1, j) = visit(t, n1) val (nn2, k) = visit(t, n2) val v = if (j == k) j + 1 else max(j, k) ((op, (nn1, j), (nn2, k)), v) // 葉ノードのとき case ((op, a, b), c) => val v = if (c == a) 1 else 0 (c, v) } } def gen(s: String) { println(s) } def genCode(n: Any, reglist: List[String], tmp: Int): String = { n match { case (x: String, n) => val r = reglist.first gen("load " + r + ", " + x) r case ((op: String, n1, (x, 0)), _) => val r = genCode(n1, reglist, tmp) gen(op + " " + r + ", " + r + ", " + x) r case ((op: String, n1 @ (_, j: Int), n2 @ (_, k: Int)), _) => if (k <= j && k < reglist.size) { val r1 = genCode(n1, reglist, tmp) val r2 = genCode(n2, reglist - r1, tmp) gen(op + " " + r1 + ", " + r1 + ", " + r2) r1 } else if (k > j && j < reglist.size) { val r1 = genCode(n2, reglist, tmp) val r2 = genCode(n1, reglist - r1, tmp) gen(op + " " + r1 + ", " + r1 + ", " + r2) r1 } else if (k >= reglist.size) { val r = genCode(n2, reglist, tmp) gen("store " + r + ", t" + tmp) val r2 = genCode(n1, reglist, tmp + 1) gen(op + " " + r2 + ", " + r2 + ", t" + tmp) r2 } else { "error" } case _ => "error" } } }
実行結果
((add,((mul,(a,1),(b,0)),1),((add,((add,(a,1),(c,0)),1),((mul,(d,1),(e,0)),1)),2)),2) load r1, d mul r1, r1, e store r1, t1 load r1, a add r1, r1, c add r1, r1, t1 store r1, t1 load r1, a mul r1, r1, b add r1, r1, t1
参考
http://pages.cs.wisc.edu/~cs701-1/NOTES/5.REGISTER-ALLOCATION.html