目的コードの生成

目的コードの生成
•
•
•
•
中田育男著
コンパイラの構成と最適化
朝倉書店, 1999年
第9章
中間語
• 構文木とDAG
– 抽象構文木(AST:abstract syntax tree)
– DAG(directed acyclic graph)
– 中間木
• 四つ組(3番地コード)と三つ組
(演算子, オペランド1, オペランド2, 結果)
(演算子, オペランド1, オペランド2)
• 結果を三つ組の場所で示す。
中間語(続き)
• RTL
– Register transfer language
– 命令語はレジスタとのやりとりが主。
– 例: a[i]=b+1;
r[1]=m[b]
r[1]=r[1]+1
r[2]=m[i]
r[2]=r[2]*4
m[a+r[2]]=r[1]
• 機械語
コード生成器生成系
パターンマッチングによるコード生成器
中間木
コード生成器
パターン
…..
+
+
r1
reg
4
const
…..
目的コード
機械語
…..
→ add reg, reg, const
…..
パターンマッチングと
コード生成のプログラム
add r1, r1, 4
木のパターンマッチングによる
コード生成
↑
=
+
C
R2
R1
store R2,C(R1)
→ R2
+
C
*
2
→ R2
R1
R1
load R2,C(R1)
R1やR2はレジスタにマッチする。
Cは定数にマッチする。
shiftL R2,R1,1
=
+
a
*
r1
↑
2
+
b
r1
=
+
a
r2
r1
*
↑
2
+
store r2,a(r1)
b
r1
=
+
a
r2
r1
*
2
r2
↑
+
shiftL r2,r2,1
store r2,a(r1)
b
r1
=
+
a
r2
r1
*
2
r2
↑
+
load r2,b(r1)
shiftL r2,r2,1
store r2,a(r1)
b
r1
極大食い(maximal munch)
• トップダウンのパターンマッチング
– 中間木の根から葉の方向に。
• いろいろなマッチングがありうるときは、
できるだけ大きなパターンを選ぶ。
• 極大食いが常に最適とは限らない。
ダイナミックプログラミングによる
コード生成
(1)
(2)
(3)
=
=
C
+
C
R2
R1
M[R1+C]←R2
cost=5
R1
↑
R2
M[R1]←M[R2]
cost=6
R1←C
cost=1
→ R1
(5)
(4)
↑
→ R1
↑
→ R2
+
C
C
R1←M[C]
cost=3
(6)
+
C
→ R1
R1
R1
R2←M[R1+C]
cost=5
R1←R1+C
cost=1
(7)
+
→ R1
(8)
↑
R2
+
C
+
R1
→ R2
R2
R1
R1←R2+M[R1+C]
cost=6
R1←R1+R2
cost=1
=
↑
+
a
↑
k
+
b
↑
j
a[k]=b[j];
=
↑
+
a
↑
k
+
b
r1←b; 1
b; 0
↑
j
=
↑
+
a
r3←a; 1
a; 0
↑
k
r4←k; 1
k; 0
+
b
r1←b; 1
b; 0
↑
j
r2←j; 1
j; 0
=
↑
+
a
r3←a; 1
a; 0
↑
k
r4←k; 1
k; 0
+
b
r1←b; 1
b; 0
↑
j
r2←j; 1
j; 0
r2←M[j]; 0+3=3
r2←M[r2+0]; 1+5=6
=
↑
+
a
r3←a; 1
a; 0
↑
k
r4←k; 1
k; 0
+
b
r1←b; 1
b; 0
r2←r2+b; 3+0+1=4
r2←r2+r1; 3+1+1=5
↑
j
r2←j; 1
j; 0
r2←M[j]; 0+3=3
r2←M[r2+0]; 1+5=6
=
+
a
r3←a; 1
a; 0
↑
k
r4←k; 1
k; 0
b
r1←b; 1
b; 0
↑
r2←M[r2+b]; 3+0+5=8
r2←M[r2+0]; 4+5=9
+
r2←r2+b; 3+0+1=4
r2←r2+r1; 3+1+1=5
↑
j
r2←j; 1
j; 0
r2←M[j]; 0+3=3
r2←M[r2+0]; 1+5=6
=
↑
+
a
↑
k
r2←M[r2+b]; 3+0+5=8
r2←M[r2+0]; 4+5=9
+
b
r1←b; 1
b; 0
↑
j
r2←M[j]; 0+3=3
=
↑
+
a
↑
k
+
b
r2←M[r2+b]; 3+0+5=8
r2←M[r2+0]; 4+5=9
r2←r2+b; 3+0+1=4
↑
j
=
r4←r4+a; 3+0+1=4
+ r4←r4+r3; 3+1+1=5 ↑
a
r3←a; 1
a; 0
r2←M[r2+b]; 3+0+5=8
r2←M[r2+0]; 4+5=9
r4←M[k]; 0+3=3
r4←M[r4+0]; 1+5=6 r2←r2+b; 3+0+1=4
↑
+
r2←r2+r1; 3+1+1=5
k
r4←k; 1
k; 0
b
r1←b; 1
b; 0
↑
j
r2←j; 1
j; 0
r2←M[j]; 0+3=3
r2←M[r2+0]; 1+5=6
=
M[r4+a]←r2; 3+8+5=16
M[r4]←M[r2]; 4+4+6=14
r4←r4+a; 3+0+1=4
+ r4←r4+r3; 3+1+1=5 ↑
a
r3←a; 1
a; 0
r2←M[r2+b]; 3+0+5=8
r2←M[r2+0]; 4+5=9
r4←M[k]; 0+3=3
r4←M[r4+0]; 1+5=6 r2←r2+b; 3+0+1=4
↑
+
r2←r2+r1; 3+1+1=5
k
r3←k; 1
k; 0
b
r1←b; 1
b; 0
↑
j
r2←j; 1
j; 0
r2←M[j]; 0+3=3
r2←M[r2+0]; 1+5=6
r2 ← M[j]
r2 ← r2+b
r4 ← M[k]
r4 ← r4+a
M[r4] ← M[r2]
3
1
3
1
6
文のコード生成
T(e,c,L)の定義:if (e==c) goto Lの目的コード
c=true
e=e1|e2
e=e1&e2
e=!e1
e=変数
T(e1,true,L)
T(e2,true,L)
T(e1,false,newL)
T(e2,true,L)
newL:
c=false
T(e1,true,newL)
T(e2,false,L)
newL:
T(e1,false,L)
T(e2,false,L)
T(e1,false,L)
T(e1,true,L)
Load R,e
BrT R,L
Load R,e
BrF R,L
文のコード生成
T((a&b)|!(c|d),true,L)
=
T(a&b,true,L)
=
T(a,false,L1)
T(b,true,L)
L1:
T(!(c|d),true,L)
=T(c|d,false,L)
=
T(c,true,L2)
T(d,false,L)
L2:
Load
BrF
Load
BrT
L1:
R1,a
R1,L1
R1,b
R1,L
Load
BrT
Load
BrF
L2:
R1,c
R1,L2
R1,d
R1,L
手続き呼び出しのコード
• レジスタの使い方
– 特定目的に使われるレジスタ
BrLink L
! Branch and Link
– 大域的に使われるレジスタ群
• 手続き呼び出しをしても値が変わらない。
• 呼び出され側で大域的なレジスタを使う場合は、
呼び出され側で退避する(callee save register)。
– 局所的に使われるレジスタ群
• それが保証されないもの。
• 呼び出し側で局所的なレジスタを使っている場合は、
• 呼び出し側で退避する(caller save register)。
L:
フレーム領域の獲得
大域レジスタの退避
(特定レジスタの退避
と新設定も含む)
プ
ロ
ロ
ー
グ
局所レジスタの退避
パラメタのセット
BrLink
手続き本体のコード
L
局所レジスタの回復
大域レジスタの回復
フレーム領域の解放
戻り値のセット
戻り命令
呼び出し側
呼び出され側
エ
ピ
ロ
ー
グ