時相論理を用いた コンパイラ最適化器の 実行の正しさの検査 東京工業大学 佐原 聡一郎 佐々 政孝 研究背景 コンパイラの最適化 重要な技術で研究が盛ん 複雑でバグが混入しやすい プログラムの意味を変えてしまう致命的なものかも バグが発見しずらい 最適化器の正しさを保証できないか? 3つのアプローチ 1. 2. 3. 最適化器そのものにバグがないことを検査 最適化の実行に誤りがなかったことを検査 多くのテストによる信頼性の向上 関連研究 1. バグがないと保証された最適化器 Laceyらの研究 [2002] CTL-FVとモデル検査による最適化システム 2. システム上では最適化器の正しさの証明が簡単 扱える最適化に制限がある 最適化の実行に誤りがなかったことの検査 Neculaの研究 [2000] 最適化実行後の記号実行を用いた検査 高速で最適化に依存せず実用的 検査が正しく行える保証がない 目標 最適化器実行の正しさを保証する手法 現実に存在する最適化器を扱えるように 実用的であるように 実装が困難すぎない、現実的な時間内の検査、など 誤った最適化に気付ければよい 最適化器自身の正しさを保証できなくてもよい 毎回の最適化の実行が正しかったかどうか 最適化器の構成 解析 変形 プログラムの解析 変形すべき箇所を探し出す データフロー方程式など プログラムの変形 解析により求めた箇所を変形する 提案手法の概要 解析 変形 検査 正しい 変形が正しかったかどうかを検査 変形箇所の満たすべき性質をCTL-FVで記述 実行パスに沿った論理で直観的 モデル検査のコストが小さい 最適化実行後にモデル検査 変形箇所ごとの検査 提案手法の詳細 x=a+b end x は使用されない 簡単な無用命令除去 使われない変数への代入文削除 提案手法の詳細 ¬E(true U use(x)) ? x=a+b 使われない変数への代入文削除 rm, x OK 簡単な無用命令除去 変形箇所の正しさ x end x は使用されない は以後使用されることはない ¬EF(use(x)) E (true U use( x)) 変形箇所にマーク付け 最適化器を拡張(AOP利用) モデル検査 マークに関するCTL-FV式の検査 最適化器の拡張 optimize() { pos = analyze() foreach (p in pos) { transform(p) } } 拡張ポイント 変形を行うコードの箇所 マーク付けコードの挿入 optimize() { pos = analyze() foreach (p in pos) { transform(p) marking(p) } } transform(p) marking(p) AOPの利用 pointcut transform(p) weave marking(p) CTL-FVの構文と意味 φ:: prop | φ |φφ | Eψ | Aψ | Eψ | Aψ ψ:: Xφ | Gφ |φUφ |φWφ ループ不変式移動 ループ不変式を移動 一時変数への代入文を挿入 元の式の計算を一時変数で置換 正しいための条件 挿入箇所 一時変数 t は他で定義されない x=a+b E (true U (node(n) def ¬EF(¬node(n)∧def(t)) ∧ (t ))) ¬rEF(¬node(n)∧def(t)) E (true U (node(n) def (t ))) 置換箇所 前方に挿入箇所が必ず存在する その間、式の値は変わらない rA(trans(e) A(trans(e) W W mark(ins,t,e)) mark(ins, t, e)) *SSA形式を仮定 ループ不変式移動 t=a+b ループ不変式を移動 一時変数への代入文を挿入 ins,t,e OK 元の式の計算を一時変数で置換 正しいための条件 挿入箇所 一時変数 t は他で定義されない x=a+b x=t rpl,t,e OK *SSA形式を仮定 E (true U (node(n) def ¬EF(¬node(n)∧def(t)) ∧ (t ))) ¬rEF(¬node(n)∧def(t)) E (true U (node(n) def (t ))) 置換箇所 前方に挿入箇所が必ず存在する その間、式の値は変わらない rA(trans(e) A(trans(e) W W mark(ins,t,e)) mark(ins, t, e)) ループ不変式移動のバグ 例外の発生する式の移動 計算のないパスに挿入不可 例外が発生するようになるかも 挿入点が追加で満たすべき性質 全てのパスに元々計算があった A(trueW Wmark(rpl,t,e)) m ark(rpl, t , e)) A(true x=a/b COINSのバグ 未知のバグ SPECを用いて検査中に発見 テストで発見されなかった潜在的バグ *SSA形式を仮定 ループ不変式移動のバグ t=a/b 例外の発生する式の移動 計算のないパスに挿入不可 例外が発生するようになるかも ins,t,e NG 挿入点が追加で満たすべき性質 全てのパスに元々計算があった A(trueW Wmark(rpl,t,e)) m ark(rpl, t , e)) A(true x=a/b x=t rpl,t,e COINSのバグ 未知のバグ SPECを用いて検査中に発見 テストで発見されなかった潜在的バグ *SSA形式を仮定 条件分岐を考慮した定数伝播 B1 t0=0 抽象実行に基づく最適化 プログラムを順にたどることで解析 B2 t1=φ(t0,t3) t1==0 ? t2=t1+1 B3 B4 複雑な最適化 Laceyらの手法では行えない最適化 B5 t3=φ(t1,t2) g=2*t3 g<=0 ? 常にt1==0が成立 B4は通らない 全ての辺を通るかもという前提 ⇒ t1が0となることが解析できない 単純なデータフロー方程式でも行えない 本手法による最適化後検査は可能 t1==0が本当に正しいかは検査は可能 B6 *SSA形式 *詳細は省略 条件分岐を考慮した定数伝播 B1 t0=0 抽象実行に基づく最適化 プログラムを順にたどることで解析 B2 t1=φ(t0,t3) t1==0 ? t2=t1+1 B3 B4 複雑な最適化 Laceyらの手法では行えない最適化 B5 t3=φ(t1,t2) g=2*t3 0 g<=0 ? 常にt1==0が成立 B4は通らない 全ての辺を通るかもという前提 ⇒ t1が0となることが解析できない 単純なデータフロー方程式でも行えない 本手法による最適化後検査は可能 t1==0が本当に正しいかは検査は可能 B6 *SSA形式 *詳細は省略 COINSの最適化器への適用 行数 拡張 357 2 cstp 1143 5 2 条件分岐付定数伝播 cpyp 143 3 2 (cstp) コピー伝播(cpyp) 共通部分式除去(cse) 無用命令除去(dce) cse 408 7 1 dce 480 3 lcm 1259 2 SSA形式 ループ不変式移動(hli) hli 部分冗長除去(lcm) 拡張箇所は少ない 通常形式 改変 ⇒ マークも少ない 探し出すのも容易 ソースの改変もほぼない ポイントカットの都合のみ 本手法の考察 論理式の記述について 記述量は少ない 変形箇所自体が少ない 論理式は変形箇所一つにつき、1~3行程度 最適化のきちんとした理解が必要 論理式の記述は決して容易というわけではない 最適化器製作者なら可能な範囲か バグの原因特定の容易さについて 論理式のモデル検査で反例 ⇒ 式に関する変形は誤りであった バグを発見した際の原因特定は容易 本手法の考察 正しさの保証について 検査付コンパイルは高信頼 「誤った最適化に気づかずプログラム実行」とはならない テストだけでは得られない信頼性 次に最適化コンパイルするプログラムの正しさは保証外 厳密なプログラムの意味保存を示すものではない 論理式を満たす≠プログラムの意味が保存される ギャップを埋めるための証明が必要になる ただし、直観的にはほぼ明らかか Lacey>本手法≒ Necula≫テスト Laceyらの最適化器は常に正しい(証明付の場合) ただし、扱えるのは簡単な最適化のみという制限がある 検査時間の計測実験 目的 検査にかかる時間が現実的であることを確かめる 実験環境 Intel Pentium 4 CPU 2.80GHz Linux 2.6.17-13msmp JavaVM 1.5.0_08 Heap 256Mbyte、Stack 2Mbyte COINS 1.4.1 最適化O2 に相当するSSA最適化オプション GluonJ 1.2 ベンチマーク SPEC CPU2000 version1.2 から14本 1.m cf p m m ke su 8.a m ua 9.a rt 17 3.e q 18 18 19 af ty 7.p ar se r 25 4.g ap 25 5.v or te x 25 6.b z ip 2 30 0.t wo lf 17 1.s wi m 17 2.m gr id 17 7.m es a 6.c r 18 18 r 17 5.v p p m m su 18 8.a m ke 9.a rt ua 18 3.e q 17 p 5.v or te x 25 6.b z ip 2 30 0.t wo lf 17 1.s wi m 17 2.m gr id 17 7.m es a 25 r rs e af ty cf 4.g a 25 7.p a 19 18 6.c r r 5.v p 18 1.m 17 検査時間の計測実験 最適化時間の比 30 25 5 総コンパイル時間の比 2 1.5 1 0.5 0 コンパイル時間の比較 20 15 10 0 3 2.5 検査on/offの比 最適化時間比 総コンパイル時間比 あくまで参考値 検査した最適化は一部 考察 速度比 最適化のみでは15倍 総コンパイル時間では1.7倍 高速化も十分可能 現実的な時間の範囲内 まとめ 最適化実行後に正しかったかどうかを検査 変形箇所がCTL-FV式を満たせば正しいと判断 最適化後のプログラムをモデル検査 特徴 既存の手書きの最適化器に適用可能 複雑な最適化器でも扱える可能性 バグを発見した際の原因特定が容易 常に検査を行うことで高い信頼性 検査時間は現実的な範囲 今後の課題 正しさの厳密な証明 時相論理による証明はいくつか行われている Laceyらの証明法、各最適化ごとの証明、など 本手法においても同様にして行えると期待 さらに多くの最適化器に適用 演算の強さ軽減、PREQPなどに適用可能か? 検査の高速化 本手法に特化したモデル検査 データフロー方程式のビットベクトル法の応用 おわり CTL-FVの例 A(φ1Uφ2) 全パスでφ2の成立までφ1が常に成立 φ2の成立する状態が必ずある { s |= A(φ1Uφ2) } = {3,4,8} A(φ1Wφ2) 全パスで以下のいずれかが成立 { φ2の成立までφ1が常に成立 φ2が成立せず、永遠にφ1が成立でもよい ループし続けるパスの考慮の回避 s |= A(φ1Wφ2) } = {3,4,5,6,7,8} 本手法の考察 厳密な意味での正しさについて 厳密な意味での「検証」ではない 式を満たした≠最適化が正しく行われた 厳密には証明が必要 ただし、直観的にはほぼ明らかといえる Lacey>本手法≒ Necula>テスト Laceyらの最適化器は常に正しい(証明付の場合) プログラムは無限にあるので、全テストは無理 次に最適化コンパイルするプログラムの正しさは保証外 条件分岐を考慮した定数伝播 B1 B2 t0=0 抽象実行に基づく最適化 t1=φ(t0,t3) t1==0 ? CTL-FVの記述では… t2=t1+1 B3 常にt1==0 B4は通らない B4 t1が取る値を解析するのは無理 B5 t3=φ(t1,t2) g=2*t3 g<=0 ? t1==0という解析結果の検査は可能 Laceyらの手法では行えない最適化 データフロー方程式でも行えない 本手法では検査可能 Laceyらが扱えない最適化も検査可能 「解析」は「結果の検査」より大変 B6 *詳細は省略 条件分岐を考慮した定数伝播 B1 B2 t0=0 抽象実行に基づく最適化 t1=φ(t0,t3) t1==0 ? CTL-FVの記述では… t2=t1+1 B3 常にt1==0 B4は通らない B4 t1が取る値を解析するのは不可能 B5 t3=φ(t1,t2) g=2*t3 0 g<=0 ? t1==0という解析結果の検査は可能 Laceyらの手法では行えない最適化 データフロー方程式でも行えない 本手法では検査可能 Laceyらが扱えない最適化も検査可能 「解析」は「結果の検査」より大変 B6 *詳細は省略
© Copyright 2024 ExpyDoc