大域的データフロー解析 • 流れグラフ 基本ブロックをnodeとし、 基本ブロック間の制御関係をedgeとするグラフを、 流れグラフという。 • 開始ブロック プログラムの開始点を含むブロック B1 B5 t6:= 4*i x := a[t6] t7:= 4*i t8:= 4*j t9:= a[t8] t10:=4*j a[t10]:=x goto B2 i := j := t1:= v := m-1 n 4*n a[t1] B2 i := i+1 t2:= 4*i t3:= a[t2] if t3<v goto B2 B3 i := j-1 t4:= 4*i t5:= a[t4] if t5<v goto B3 B4 if i>=j goto B6 B6 t11:=4*i x :=a[t11] t12:=4*i t13:=4*n t14:=a[t13] a[t12]:=t14 t15:=4*n a[t15]:=x 到達定義 • B: 基本ブロック • gen[B] Bの中で生成され、 Bの終わりに到達する定義の集合 つまり、それ以降に同じ変数への定義はない。 • kill[B] Bによって消滅する定義の集合 つまり、Bの中で定義される変数への定義で、 gen[B]に含まれないものの集合 B1 B5 t6:= 4*i x := a[t6] t7:= 4*i t8:= 4*j t9:= a[t8] t10:=4*j a[t10]:=x goto B2 i := j := t1:= v := m-1 n 4*n a[t1] B2 i := i+1 t2:= 4*i t3:= a[t2] if t3<v goto B2 B3 i := j-1 t4:= 4*i t5:= a[t4] if t5<v goto B3 B4 if i>=j goto B6 kill[B3] gen[B3] B6 t11:=4*i x :=a[t11] t12:=4*i t13:=4*n t14:=a[t13] a[t12]:=t14 t15:=4*n a[t15]:=x 到達定義 • in[B] Bの先頭に到達する定義の集合 • out[B] Bの終わりに到達する定義の集合 • in[B]とout[B]はどうやって求めるのか? • 到達可能性 何らかの経路を通って到達すればよい。 (控え目な判断) B1 B5 t6:= 4*i x := a[t6] t7:= 4*i t8:= 4*j t9:= a[t8] t10:=4*j a[t10]:=x goto B2 i := j := t1:= v := m-1 n 4*n a[t1] B2 i := i+1 t2:= 4*i t3:= a[t2] if t3<v goto B2 in[B2] B3 i := j-1 t4:= 4*i t5:= a[t4] if t5<v goto B3 B6 B4 if i>=j goto B6 t11:=4*i x :=a[t11] t12:=4*i t13:=4*n t14:=a[t13] a[t12]:=t14 t15:=4*n a[t15]:=x データの流れ方程式 • in[B]とout[B]が満たすべき等式 in[B] = ∪ out[P] PはBの先行ブロック out[B] = gen[B] ∪ (in[B] - kill[B]) • 前進型 inからoutを求める。 • 合併型 ∪を使う アルゴリズム(到達定義) for ∀B do out[B] := gen[B] change := true while change do change := false for ∀B do in[B] := ∪ out[P] oldout := out[B] out[B] := gen[B] ∪ (in[B] - kill[B]) if out[B]≠oldout then change := true アルゴリズム(到達定義) • あらゆる実行経路を考えている。 • 定義が次第に遠くへ伝搬される。 • in[B]もout[B]も単調に増加する。 • 従って、いつかは変化しなくなる (定義の全体が有限だから)。 d1: i:=m-1 d2: j:=n d3: a:=u1 d4: i:=i+1 d5: j:=j-1 d6: a:=u2 d7: i:=u3 d1: i:=m-1 d2: j:=n d3: a:=u1 d4: i:=i+1 d5: j:=j-1 d1,d2,d3 d4,d5 d6: a:=u2 d6 d7: i:=u3 d7 d1: i:=m-1 d2: j:=n d3: a:=u1 d4: i:=i+1 d5: j:=j-1 d1,d2,d3 d1,d2,d3,d7 d4,d5,d3 d4,d5 d6: a:=u2 d6,d4,d5 d7: i:=u3 d4,d5,d6 d7,d5,d6 d1: i:=m-1 d2: j:=n d3: a:=u1 d4: i:=i+1 d5: j:=j-1 d1,d2,d3 d1,d2,d3,d7,d5,d6 d4,d5,d3,d6 d4,d5,d3 d6: a:=u2 d6,d4,d5 d7: i:=u3 d4,d5,d6,d3 d7,d5,d6,d3 d1: i:=m-1 d2: j:=n d3: a:=u1 d4: i:=i+1 d5: j:=j-1 d1,d2,d3 d1,d2,d3,d7,d5,d6 d4,d5,d3,d6 d4,d5,d3,d6 d6: a:=u2 d6,d4,d5 d7: i:=u3 d4,d5,d6,d3 d7,d5,d6,d3 利用可能な式 B1 t1 := 4*i B2 ? B3 t2 := 4*i • ?が i:=... を含まなければ、 B1の4*iはB3で利用可能。 • ?が i:=... を含んでいても、 その後で4*iが計算されればよい。 利用可能な式 • e_gen[B] ブロックBで計算され、 Bの終わりで利用可能な式の集合 • e_kill[B] ブロックBで消滅させられる式の集合 例えば、y+zという式は、 yまたはzが定義され、 その下にy+zがなければ消滅する。 利用可能な式 • out[B] ブロックBの終わりで利用可能な式の集合 • in[B] ブロックBの先頭で利用可能な式の集合 • 流れ方程式 out[B] = e_gen[B] ∪ (in[B] - e_kill[B]) in[B] = ∩ out[P] (Bは開始節でない) in[B] = φ (Bは開始節) • 前進 • 集合積 アルゴリズム(利用可能な式) in[B1] := φ; out[B1] := e_gen[B1] for B1 と異なる B do in[B] := U; out[B] := U - e_kill[B]; while 変化がある間 do for B1 と異なる B do in[B] := ∩ out[P]; PはBの先行ブロック out[B] := e_gen[B] ∪ (in[B] - e_kill[B]); U : プログラムに現れる式の全体 B1: 開始ブロック 生きている変数 • 流れ方程式 in[B] = use[B] ∪ (out[B] - def[B]) out[B] = ∪ in[S] SはBの後続ブロック • use[B] 定義より前にBで使われる変数の集合 • def[B] Bで定義される変数の集合(使われる前に定義され る) • 後進 • 合併
© Copyright 2024 ExpyDoc