(57)【要約】【課題】ソースプログラムのコンパイル時にライト命令に対応するダミーリードの挿入漏れを検出することができるコンパイル装置を提供する。【解決手段】実施形態のコンパイル装置は、ソースプログラムにおけるライト命令を検出するライト検出部と、前記ライト命令が検出された後のリード命令を検出するリード検出部と、前記ライト命令により書き込み領域が指定され、前記リード命令により読み出し領域が指定され、前記読み出し領域が前記書き込み領域と一致するか否かを判定する判定部とを備える。【選択図】図５
2018156568.tif 000002
【特許請求の範囲】
【請求項１】
ソースプログラムにおけるライト命令を検出するライト検出部と、
前記ライト命令が検出された後のリード命令を検出するリード検出部と、
前記ライト命令により書き込み領域が指定され、前記リード命令により読み出し領域が指定され、前記読み出し領域が前記書き込み領域と一致するか否かを判定する判定部と、
を具備するコンパイル装置。
【請求項２】
前記ライト命令による書き込み領域が第１変数により示され、前記リード命令による読み出し領域が第２変数により示され、前記第１変数と前記第２変数とが異なる場合、
前記判定部は、前記第１変数が配置される第１セクションと、前記第２変数が配置される第２セクションとが一致するか否かを判定し、
前記第１セクションは前記ライト命令によりデータが前記書き込み領域に書き込まれる単位であり、前記第２セクションは前記リード命令によりデータが前記読み出し領域から読み出される単位である請求項１に記載のコンパイル装置。
【請求項３】
前記第１変数が配置される第１セクションと、前記第２変数が配置される第２セクションとが一致しない場合、
前記判定部は、前記第１セクションと前記第２セクションとを同一のメモリ領域に割り当てる指定が前記ソースプログラム内にあるか否かを判定する請求項２に記載のコンパイル装置。
【請求項４】
前記ライト命令が、前記ソースプログラムが記述された言語規格で定められた書き込み機能を持つ関数による命令である請求項１乃至３のいずれかに記載のコンパイル装置。
【請求項５】
前記ソースプログラムは中間コードを含む基本ブロックに分割され、
前記ライト検出部は前記基本ブロックに対して前記ライト命令の検出を行い、前記リード検出部は前記基本ブロックに対して前記リード命令の検出を行う請求項１乃至４のいずれかに記載のコンパイル装置。
【請求項６】
前記ソースプログラムは中間コードを含む複数の基本ブロックに分割され、前記複数の基本ブロックは、第１基本ブロックと、前記第１基本ブロックを通った後必ず通る第２基本ブロックを含み、
前記ライト検出部は前記第１基本ブロック及び前記第２基本ブロックに対して前記ライト命令の検出を行い、前記リード検出部は前記第１基本ブロック及び前記第２基本ブロックに対して前記リード命令の検出を行う請求項１乃至４のいずれかに記載のコンパイル装置。
【請求項７】
前記ライト命令が検出された後に、前記書き込み領域と一致する前記読み出し領域を有する前記リード命令が検出された回数を記憶する記憶部をさらに備え、
前記判定部は、前記リード命令の回数に基づいて、前記ライト命令の前記書き込み領域と一致する前記読み出し領域を有する前記リード命令が前記ソースプログラムにあるか否かを判定する請求項１乃至６のいずれかに記載のコンパイル装置。
【発明の詳細な説明】
【技術分野】
【０００１】
実施形態は、ソースプログラムをコンパイルするコンパイル装置に関するものである。
【背景技術】
【０００２】
高水準言語、例えばＣ言語などで記述されたソースプログラムは、コンパイル処理されてオブジェクトプログラムに変換される。このコンパイル処理を実行するプロセッサの仕様によっては、ソースプログラムにおけるあるコア（モジュール）がメモリやレジスタへ値を書き込む場合、書き込み命令の直後に書き込みが完了することが保証できず、書き込み命令の直後に別のコア（モジュール）が値を読み出すと、書き込み前の値（前回値）が読み出される場合がある。
【０００３】
この対策として、あるコア（モジュール）によるメモリへの書き込み後に、同一のコア（モジュール）が同一メモリ領域から値を読み出し、書き込み完了を保証するという手法がある。このような書き込み完了を保証するために必要な読み出しを「ダミーリード」と呼ぶ。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開２０００−３０５８０９号公報
【特許文献２】特表２００４−５２０６４３号公報
【特許文献３】特開平１−７６１２９号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
ソースプログラムのコンパイル時にライト命令に対応するダミーリードの挿入漏れを検出することができるコンパイル装置を提供する。
【課題を解決するための手段】
【０００６】
実施形態のコンパイル装置は、ソースプログラムにおけるライト命令を検出するライト検出部と、前記ライト命令が検出された後のリード命令を検出するリード検出部と、前記ライト命令により書き込み領域が指定され、前記リード命令により読み出し領域が指定され、前記読み出し領域が前記書き込み領域と一致するか否かを判定する判定部とを具備する。
【図面の簡単な説明】
【０００７】
【図１】図１は、プログラムの開発フローを示す図である。
【図２】図２は、第１実施形態のコンパイル装置のハードウェア構成を示す図である。
【図３】図３は、第１実施形態におけるソースプログラムをオブジェクトプログラムに変換するコンパイル処理を示す図である。
【図４】図４は、図３に示したコンパイル処理中のコード生成の詳細を示すフローチャートである。
【図５】図５は、図４に示したコード生成処理中のダミーリードチェックの処理を示すフローチャートである。
【図６】図６は、図５に示したダミーリードチェックの処理で生成されるテーブル例を示す図である。
【図７】図７は、前記ダミーリードチェック処理中のリード漏れチェックの詳細を示すフローチャートである。
【図８】図８は、第１実施形態の変形例１におけるダミーリードチェックの処理を示すフローチャートである。
【図９】図９は、第１実施形態の変形例１が適用されるプログラム例を示す図である。
【図１０】図１０は、第１実施形態の変形例１におけるダミーリードチェックの処理で生成されるテーブル例を示す図である。
【図１１】図１１は、第１実施形態の変形例２が適用されるプログラム例を示す図である。
【図１２】図１２は、第１実施形態の変形例２におけるダミーリードチェックの処理で生成されるテーブル例を示す図である。
【図１３】図１３は、第２実施形態のダミーリードチェックの処理を示すフローチャートである。
【図１４】図１４は、図１３に示したダミーリードチェック処理中のリード漏れチェックの詳細を示すフローチャートである。
【図１５】図１５は、第２実施形態の変形例が適用されるプログラム例を示す図である。
【図１６】図１６は、第３実施形態のダミーリードチェックの処理を示すフローチャートである。
【図１７】図１７は、図１６に示したダミーリードチェックの処理で生成されるテーブル例を示す図である。
【図１８】図１８は、第４実施形態の処理を示すフローチャートである。
【発明を実施するための形態】
【０００８】
以下、図面を参照して実施形態について説明する。以下の説明において、同一の機能及び構成を有する構成要素については同一符号を付す。また、以下に示す各実施形態は、この実施形態の技術的思想を具体化するための装置や方法を例示するものであって、構成部品の材質、形状、構造、及び配置等を下記のものに特定するものではない。
【０００９】
各機能ブロックは、ハードウェア、コンピュータソフトウェアのいずれかまたは両者を組み合わせたものとして実現することができる。各機能ブロックが以下の例のように区別されていることは必須ではない。例えば、一部の機能が例示の機能ブロックとは別の機能ブロックによって実行されてもよい。さらに、例示の機能ブロックがさらに細かい機能サブブロックに分割されていてもよい。
【００１０】
１．第１実施形態
プロセッサ上で実行するプログラムは、例えば図１に示すようなフローで開発される。
（１）プログラム開発者がソースファイル（ソースプログラム）を作成する。
（２）コンパイラを有するコンパイル装置は、ソースファイルをコンパイル処理し、実行形式ファイル（あるいは、オブジェクトプログラム）を生成する。
（３）実行形式ファイルがプロセッサ上のメモリに置かれ、各種アプリケーションが実行される。
【００１１】
ソースプログラムは、コンパイル装置によりコンパイル処理され、中間言語ファイルの生成、およびリンカを介して実行形式ファイルとして生成される。以下に、ソースプログラムをコンパイル処理するコンパイル装置について説明する。
【００１２】
１．１  コンパイル装置の構成
図２は、第１実施形態のコンパイル装置のハードウェア構成を示す図である。コンパイル装置１０は、コンピュータ、例えば、汎用コンピュータ、ワークステーション、及びパーソナルコンピュータ等から構成される。図２に示すように、コンパイル装置１０は、ＣＰＵ(Central Processing Unit)１１、ＲＡＭ(Random Access Memory)１２、ＲＯＭ(Read Only Memory)１３、及び入出力部１４を備える。ＣＰＵ１１、ＲＡＭ１２、ＲＯＭ１３、及び入出力部１４はバス１５により相互に接続されている。
【００１３】
ＣＰＵ１１は、例えば、ＲＯＭ１３に記憶された制御プログラムに従いハードウェア各部を制御する。ＣＰＵ１１は、コンパイルプログラムに従ってソースプログラムに対してコンパイル処理を実行する。コンパイルプログラムは、例えば、ＲＯＭ１３内に格納されており、起動時にバス１５を介してＲＡＭ１２へロードされる。
【００１４】
ＲＡＭ１２は、ＣＰＵ１１によるコンパイルプログラムの実行時に発生する各種データ、例えば中間コード及びテーブルを一時的に記憶する。ＲＡＭ１２は、例えば、ＳＲＡＭ(Static RAM)または、ＤＲＡＭ(Dynamic RAM)、フラッシュメモリなどを含む。
【００１５】
ＲＯＭ１３は、例えば、制御プログラム及びコンパイルプログラムなどを記憶する。
【００１６】
入出力部１４は、外部の装置あるいはユーザから信号及びデータを受け取る入力部と、外部の装置あるいはユーザへ信号及びデータを出力する出力部を備える。入力部は、例えば、外部の装置からソースプログラム、コンパイルプログラム、及びユーザからの操作指示などを受け取る。出力部は、ＣＰＵ１１で処理されたデータあるいはオブジェクトプログラム、ＲＡＭ１２に記憶されたデータなどを出力する。
【００１７】
１．２  コンパイル装置の動作
次に、ソースプログラムをオブジェクトコードに変換するコンパイル処理の手順を説明する。図３は、ソースプログラムを機械語等のオブジェクトコード（オブジェクトプログラム）に変換するコンパイル処理を示す。このコンパイル処理はＣＰＵ１１によって実行される。
【００１８】
例えば、ソースプログラムＰ１は、入出力部１４から入力され、ＲＡＭ１２に記憶される。ソースプログラムＰ１は、高水準言語、例えばＣ言語などで記述されている。
【００１９】
まず、ソースプログラムＰ１に対して字句解析を実行する（ステップＳ１）。
【００２０】
次に、ステップＳ１での字句解析結果が文法的に正しいかどうかを解析する。すなわち、ステップＳ１で分割された字句が構文規則に従っているか解析し、構文解析情報を生成する（ステップＳ２）。
【００２１】
続いて、構文解析情報に基づいて中間コードを生成する（ステップＳ３）。さらに、中間コードを変換して、中間コードを最適化する（ステップＳ４）。
【００２２】
次に、最適化された中間コードから機械語などのオブジェクトコードを生成する（ステップＳ５）。このコード生成の処理の詳細については後述する。
【００２３】
続いて、高速実行が可能なように、オブジェクトコードを最適化する（ステップＳ６）。さらに、最適化されたオブジェクトコードＰ２を出力する（ステップＳ７）。
【００２４】
本実施形態では、図３に示す「コード生成」の処理において、ダミーリードの挿入漏れをチェックし、挿入漏れがある場合、警告を出力する処理（以下、ダミーリードチェックと記す）が実行される。なお、ダミーリードチェックは、別の処理、例えば「構文解析」や「中間コード最適化」などの処理で実行してもよい。
【００２５】
また、上述では、ステップＳ１〜Ｓ７はＣＰＵ１１が実行する処理として説明したが、ステップＳ１〜Ｓ７はそれぞれコンパイルプログラムの１部分（モジュール）として、「字句解析部」、「構文解析部」、「中間コード生成部」、「中間コード最適化部」、「コード生成部」、「コード最適化部」、及び「コード出力部」と捉えることもできる。
【００２６】
図４は、図３に示したコンパイル処理中のコード生成（ステップＳ５）の詳細を示すフローチャートである。このコード生成の処理はＣＰＵ１１によって実行される。
【００２７】
まず、中間コード最適化（ステップＳ４）により最適化された中間コードから基本ブロックを作成する（ステップＳ１１）。中間コードは、高水準言語(例えば、Ｃ言語)と機械語の中間的言語からなる。中間コードは、高水準言語で書かれたプログラムを単一の処理に分割したものである。基本ブロックは、分岐や関数呼び出しで区切られた、処理が途中で途切れない連続する中間コードで構成されるブロックをさす。
【００２８】
次に、基本ブロックから流れグラフを作成する（ステップＳ１２）。流れグラフは、基本ブロックをつないだものである。流れグラフによりデータアクセスの流れを追うことができる。
【００２９】
次に、流れグラフ内の中間コードに対してダミーリードチェックを実行する（ステップＳ１３）。ダミーリードチェックは、基本ブロックと流れグラフの情報を必要とするため、流れグラフの作成後に実行する。ダミーリードチェックの詳細については後述する。
【００３０】
次に、レジスタの割り当てを実行する（ステップＳ１４）。ここでは、仮想レジスタがＣＰＵ１１の有するレジスタに割り当てられる。さらに、基本ブロック及び流れグラフに基づいてオブジェクトコードを生成する（ステップＳ１５）。
【００３１】
なお、ダミーリードチェックの実行は、流れグラフの作成後であればよく、レジスタ割り当ての後、あるいはオブジェクトコード生成の後であってもよい。
【００３２】
１．２．１  ダミーリードチェック
第１実施形態では、基本ブロック単位で中間コードを解析し、ダミーリードの挿入漏れをチェックする。以下に、基本ブロック内でダミーリードの挿入漏れをチェックする手順を説明する。ソースプログラム作成時のダミーリード挿入やその確認を容易にするために、ダミーリードは、ライト命令の直後に置くのが適しており、実際にライトの直後に置かれる場合が多い。このため、基本ブロック単位でダミーリードの挿入漏れをチェックするのが有効である。
【００３３】
図５は、図４に示したコード生成処理中のダミーリードチェックの処理を示すフローチャートである。図６は、ダミーリードチェックの処理で生成されるテーブル例を示す図である。このダミーリードチェックの処理はＣＰＵ１１によって実行される。
【００３４】
ダミーリードチェックが開始されると、まず、ダミーリードのチェックに使用するテーブルＰ３を初期化する（ステップＳ１０１）。テーブルＰ３には、図６に示すように、ライト処理（ライト命令）の中間コード、ライト先のアドレス、リード回数、及び次のテーブルへのポインタなどの情報が格納される。テーブルＰ３はＲＡＭ１２に生成される。
【００３５】
次に、基本ブロック内の中間コードを順に探索し、中間コードがライト処理（ライト命令）か否かを判定する（ステップＳ１０２）。中間コードがライト処理である場合、ライト先のアドレスと同一の（あるいは一致する）アドレスを記録したテーブルが既にあるか否かを判定する（ステップＳ１０３）。
【００３６】
ステップＳ１０３にて、同一のアドレスを記録したテーブルが既にある場合、そのテーブル内のアドレスのリード回数を“０”にする（ステップＳ１０４）。一方、同一のアドレスを記録したテーブルがない場合、新たなテーブル内にそのアドレスを保存する（ステップＳ１０５）。その後、ステップＳ１０６に進む。
【００３７】
ステップＳ１０４に示したように、同一アドレスに対して複数回のライトがあるときは、最後のライトの後にダミーリードがあるかを確認する必要がある。例えば、ライト１回目→リード１回目→ライト２回目の場合、リード１回目はライト２回目のダミーリードにはならない。このため、ライト時にもテーブルを探索し、同一アドレスへのライトがあるとき、リード回数を“０”にクリアする。
【００３８】
次に、ステップＳ１０２にて中間コードがライト処理でない場合、中間コードがリード処理（リード命令）か否かを判定する（ステップＳ１０７）。中間コードがリード処理である場合、リード先のアドレスが、テーブル内に保存されているライト先のアドレスと同一か否かを判定する（ステップＳ１０８）。
【００３９】
ステップＳ１０８にて、アドレスが同一の場合は、リード回数を“１”加算する、すなわち、リード回数をインクリメントする。（ステップＳ１０９）。その後、ステップＳ１０６に進む。一方、アドレスが同一でない場合は、次の中間コードへ移り（ステップＳ１１０）、ステップＳ１０２へ戻る。
【００４０】
また、ステップＳ１０７で中間コードがリード処理でない場合、ステップＳ１０６へ進む。
【００４１】
ステップＳ１０６では、基本ブロック内の全ての中間コードを調べたか否かを判定する。全ての中間コードを調べていない場合は、次の中間コードへ移り（ステップＳ１１０）、ステップＳ１０２へ戻る。その後、ステップＳ１０２以降の処理を繰り返す。
【００４２】
一方、ステップＳ１０６にて、全ての中間コードの調査が終了した場合は、ダミーリードの挿入漏れがあるか否かをチェック（以下、リード漏れチェックと記す）する（ステップＳ１１１）。リード漏れチェックでは、ライト先のアドレスを保存したテーブルＰ３を順に参照する。テーブルを参照した結果、リード回数が“０”のものはダミーリードの挿入漏れがあると判定され、警告信号が出力される。このリード漏れチェックの詳細については後述する。その後、ダミーリードチェックが終了する。
【００４３】
図７は、ダミーリードチェック処理中のリード漏れチェックの詳細を示すフローチャートである。このリード漏れチェックでは、図５の処理で記録したテーブルＰ３を順に参照する。
【００４４】
まず、図５の処理で記録した全てのテーブルＰ３を参照したか否かを判定する（ステップＳ１２１）。すなわち、参照対象のテーブルＰ３が終わりか否かを判定する。テーブルＰ３が終わりでない場合、そのテーブルＰ３内のリード回数を判定する（ステップＳ１２２）。
【００４５】
ステップＳ１２２にて、リード回数が０回である場合、ダミーリードの挿入漏れがあると判定して警告信号を出力する（ステップＳ１２３）。その後、ステップＳ１２４に進む。一方、リード回数が１回以上である場合、必要なダミーリードが挿入されていると判定し、ステップＳ１２４に進む。
【００４６】
ステップＳ１２４では、参照対象を次のテーブルへ移し、ステップＳ１２１に戻る。そして、ステップＳ１２１以降の処理を繰り返す。
【００４７】
ステップＳ１２１にて、全てのテーブルＰ３の参照が終了した場合、リード漏れチェックの処理を終了する。
【００４８】
図５に示したダミーリードチェックの処理において、ライトのアドレスとリードのアドレスとが同一か否かの判定は以下のように扱う。ライトとリードのアドレスの数値が同じ場合は、同一アドレスと判定する。また、ライトとリードのアドレスが同じ変数であれば、同一アドレスと判定する。また、ライトとリードのアドレスが同じ配列の異なる要素であれば、同一アドレスと判定する。さらに、ライトとリードのアドレスが同じ構造体、共用体、ビットフィールドの異なるメンバであれば、同一アドレスと判定する。
【００４９】
また、図６に示したテーブルＰ３は、「ライト処理の中間コードへのポインタ」を保持してもよい。ライト処理の中間コードへのポインタは、その中間コードからソースプログラム上の行番号を導出し、それを警告メッセージとするために必要な情報である。しかし、警告メッセージ中に行番号を出力しないのであれば、不要である。
【００５０】
また、テーブルＰ３内の「ライト先のアドレス」は、ライト先及びリード先のアドレスとの比較のために必要である。しかし、このためであれば、「ライト処理の中間コードへのポインタ」から導出可能であるため、「ライト処理の中間コードへのポインタ」あるいは「ライト先のアドレス」のどちらか一方のみを保持してもよい。
【００５１】
１．２．２  ダミーリードチェックの変形例１
前述した第１実施形態では、ライト先及びリード先を示す同一変数へのアクセスは同一領域へのアクセスであると判定した。実際は、同じターゲット（プロセッサ毎に定義されるアクセス単位）内へのアクセスは同一領域へのアクセスであると判定する。コンパイル装置としては、同じターゲットであるかどうかは、同じセクション（データをメモリに割り当てる単位）かどうかとして判定する。
【００５２】
変形例１では、ライト先の変数とリード先の変数とが同じセクションに配置されれば、同一領域へのアクセスであるとみなす。変形例１では第１実施形態と異なる点について主に説明する
図８は、変形例１のダミーリードチェックの処理を示すフローチャートである。図９は、変形例１が適用されるプログラム例を示す図である。図１０は、ダミーリードチェックの処理で生成されるテーブル例を示す図である。
【００５３】
図８に示すフローチャートにおいて、中間コードがライト処理か否かを判定する（ステップＳ１０２）。中間コードがライト処理である場合、ライト先の変数が配置されるセクションと同一のセクションを記録したテーブルＰ４が既にあるか否かを判定する（ステップＳ１０３Ａ）。
【００５４】
ステップＳ１０３Ａにて、同一のセクションを記録したテーブルＰ４が既にある場合、そのテーブル内のリード回数を０にする（ステップＳ１０４）。一方、同一のセクションを記録したテーブルがない場合、新たなテーブル内にそのセクションを保存する（ステップＳ１０５Ａ）。その後、ステップＳ１０６に進む。
【００５５】
また、ステップＳ１０２にて中間コードがライト処理でない場合、中間コードがリード処理か否かを判定する（ステップＳ１０７）。中間コードがリード処理である場合、リード先の変数が配置されるセクションが、テーブルＰ４内に保存されているライト先のセクションと同一か否かを判定する（ステップＳ１０８Ａ）。
【００５６】
ステップＳ１０８Ａにて、リード先とライト先のセクションが同一の場合は、リード回数を“１”加算する、すなわち、リード回数をインクリメントする。（ステップＳ１０９）。その後、ステップＳ１０６に進む。一方、セクションが同一でない場合は、次の中間コードへ移り（ステップＳ１１０）、ステップＳ１０２へ戻る。その他の処理は図５に示した処理と同様である。
【００５７】
図９に示すプログラム例を参照すると、変数ary1と変数ary2は同じセクションに配置される。同じセクションに配置される変数へのライトの後にリードがあるため、このプログラム例では、ダミーリードがある、すなわちダミーリードの挿入漏れがないと判定する。この判定処理のために、図１０に示すテーブルＰ４では、図６に示した「ライト先のアドレス」を「配置セクション名」に変更する。
【００５８】
変形例１では、ライト命令に対応するダミーリードの挿入漏れ判定をセクション単位で行えるため、第１実施形態よりもダミーリード挿入漏れの誤判定を減らすことができる。これにより、変形例１のコンパイル装置が出力する警告に対してプログラム開発者による対応工数を低減できる。
【００５９】
１．２．３  ダミーリードチェックの変形例２
変形例２は、変数ary1と変数ary2が異なるセクションに配置される例である。この場合、変形例１ではダミーリードの挿入漏れがある（ダミーリードが無い）と判定されるが、ダミーリードの挿入漏れがない（ダミーリードがある）と判定してよい場合がある。
【００６０】
図１１は、変形例２が適用されるプログラム例を示す図である。図１２は、ダミーリードチェックの処理で生成されるテーブル例を示す図である。
【００６１】
図１１に示すプログラム例を参照すると、変数ary1と変数ary2は異なるセクションに配置される。このままでは、変形例１のダミーリードチェックではダミーリードが無いと判定される。
【００６２】
そこで、セクションDATA_SEC1とセクションDATA_SEC2とが同一のメモリ領域に割り当てられるように指定する。例えば、「＃pragma same_region」でセクションDATA_SEC1とセクションDATA_SEC2とを指定する。
【００６３】
コンパイラプログラムにおいては、セクションDATA_SEC1とセクションDATA_SEC2とを同一のメモリ領域に割り当てる指定がソースプログラム内にあるか否かを判定する処理を備える。この判定により、前記２つのセクションを同一のメモリ領域に割り当てる指定があることを判定できれば、変数ary1と変数ary2は同一のメモリ領域と分かる。これにより、変数ary2の読み出しが変数ary1の書き込みに対応するダミーリードであると判定できる。
【００６４】
１．３  第１実施形態の効果
第１実施形態によれば、ソースプログラムのコンパイル時にライト命令に対応するダミーリードの挿入漏れを検出することができるコンパイル装置を提供できる。
【００６５】
以下に、第１実施形態の効果について詳述する。
【００６６】
ソースプログラムにおいてライト命令の後、ダミーリードが挿入されていない場合、プロセッサ上で動作するプログラムが正常に動作しない場合がある。一方でプロセッサの仕様が複雑でありダミーリードの挿入が必要な箇所が分かりにくいために、ダミーリードの挿入が漏れたり、不要なダミーリードを挿入することでプログラムの性能が低下する場合がある。
【００６７】
本実施形態では、ソースプログラムにおけるダミーリードの挿入漏れを検出できるため、ソースプログラムの品質を向上させることができる。さらに、ソースプログラムからアプリケーションソフト完成までの開発効率を改善することができる。
【００６８】
また、プログラム開発者は必要なダミーリードの挿入漏れを容易に確認することができ、出荷後のダミーリードの挿入漏れによるトラブルを防止できる。
【００６９】
また、本実施形態では、以下のダミーリードの挿入漏れを検出可能である。例えば、メモリへのライト後、セマフォ解放のための関数呼び出し前のダミーリードの挿入漏れ、あるいは、ダミーリード処理にvolatile修飾が無く最適化で削除されることに起因するダミーリード漏れ、あるいは、メモリへのライト直後に関数の処理が終了することによるダミーリードの挿入漏れなどである。
【００７０】
２．第２実施形態
第２実施形態のコンパイル装置について説明する。第１実施形態では基本ブロック毎にダミーリードの挿入漏れをチェックしたが、第２実施形態では全ての基本ブロックを探索した後、ダミーリードの挿入漏れをチェックする。第２実施形態の構成は、図２、図３、図４に示した第１実施形態の構成と同様であるため、記載を省略する。以下に、第１実施形態と異なる点について主に説明する。
【００７１】
２．１  ダミーリードチェック
図１３は、第２実施形態のダミーリードチェックの処理を示すフローチャートである。この処理では、基本ブロックごとに作成したテーブルＰ３をＲＡＭ１２に記憶しておく。
【００７２】
ダミーリードチェックが開始されると、まず、ダミーリードのチェックに使用するテーブルＰ３を初期化する（ステップＳ１０１）。
【００７３】
次に、基本ブロック内の中間コードを順に探索し、中間コードがライト処理（ライト命令）か否かを判定する（ステップＳ１０２）。中間コードがライト処理である場合、ライト先のアドレスと同一のアドレスを記録したテーブルが既にあるか否かを判定する（ステップＳ１０３）。
【００７４】
ステップＳ１０３にて、同一のアドレスを記録したテーブルＰ３が既にある場合、そのテーブル内のアドレスのリード回数を“０”にする（ステップＳ１０４）。一方、同一のアドレスを記録したテーブルがない場合、新たなテーブル内にそのアドレスを保存する（ステップＳ１０５）。その後、ステップＳ１０６に進む。
【００７５】
次に、ステップＳ１０２にて中間コードがライト処理でない場合、中間コードがリード処理（リード命令）か否かを判定する（ステップＳ１０７）。中間コードがリード処理である場合、リード先のアドレスが、テーブル内に保存されているライト先のアドレスと同一か否かを判定する（ステップＳ１０８）。
【００７６】
ステップＳ１０８にて、アドレスが同一の場合はリード回数を“１”加算する、すなわち、リード回数をインクリメントする。（ステップＳ１０９）。その後、ステップＳ１０６に進む。一方、アドレスが同一でない場合は、次の中間コードへ移り（ステップＳ１１０）、ステップＳ１０２へ戻る。
【００７７】
また、ステップＳ１０７で中間コードがリード処理でない場合、ステップＳ１０６へ進む。
【００７８】
ステップＳ１０６では、基本ブロック内の全ての中間コードを調べたか否かを判定する。全ての中間コードを調べていない場合は、次の中間コードへ移り（ステップＳ１１０）、ステップＳ１０２へ戻る。その後、ステップＳ１０２以降の処理を繰り返す。
【００７９】
一方、ステップＳ１０６にて、全ての中間コードの調査が終了した場合は、全ての基本ブロックを調べたか否かを判定する（ステップＳ２０１）。全ての基本ブロックを調べていない場合は、次の基本ブロックへ移り（ステップＳ２０２）、ステップＳ１０２へ戻る。その後、ステップＳ１０２以降の処理を繰り返す。
【００８０】
ステップＳ２０１にて、全ての基本ブロックの調査が終了した場合は、リード漏れチェック、すなわちダミーリードの挿入漏れがあるか否かをチェックする（ステップＳ１１１）。このリード漏れチェックの詳細については後述する。その後、ダミーリードチェックが終了する。
【００８１】
図１４は、ダミーリードチェック処理中のリード漏れチェックの詳細を示すフローチャートである。このリード漏れチェックでは、図１３の処理で記録したテーブルを順に参照する。
【００８２】
まず、図１３の処理で記録した全ての支配節の基本ブロックのテーブルＰ３を参照したか否かを判定する（ステップＳ２１１）。すなわち、参照対象のテーブルが終わりか否かを判定する。参照対象のテーブルが終わりでない場合、そのテーブル内のリード回数を判定する（ステップＳ２１２）。なお、支配節は、ある基本ブロックを通る際、その後に必ず通ることが保証される基本ブロックをさす。
【００８３】
ステップＳ２１２にてリード回数が０回である場合、その基本ブロックの支配節である基本ブロックに関数呼び出しがあるか否かを判定する。関数呼び出しがある場合、ステップＳ２１５に進む。一方、関数呼び出しがない場合、支配節の基本ブロックのテーブル内のリード回数を判定する（ステップＳ２１４）。リード回数が０回である場合、ステップＳ２１５に進む。
【００８４】
ステップＳ２１５では、その支配節が最後の支配節か否かを判定する。最後の支配節である場合、ダミーリードの挿入漏れがあると判定して警告信号を出力する（ステップＳ２１７）。その後、ステップＳ２１１に戻り、ステップＳ２１１以降の処理を繰り返す。
【００８５】
一方、ステップＳ２１５にて最後の支配節でない場合、次の支配節へ移り（ステップＳ２１６）、ステップＳ２１３へ戻り、ステップＳ２１３以降の処理を繰り返す。
【００８６】
また、ステップＳ２１２及びＳ２１４にて、リード回数が１回以上である場合、次の基本ブロックのテーブルへ移り（ステップＳ２１８）、ステップＳ２１１へ戻り、ステップＳ２１１以降の処理を繰り返す。
【００８７】
そして、ステップＳ２１１にて、全ての支配節の基本ブロックのテーブルの調査が終了した場合、リード漏れチェックの処理を終了する。
【００８８】
前述したように、第２実施形態におけるリード漏れチェックは以下のように実行される。
【００８９】
ある基本ブロックにおいてダミーリードの挿入漏れがあるか否かをチェックする場合、その基本ブロックのテーブルをまずチェックする。その基本ブロックにダミーリードがなければ、その基本ブロックの支配節となる基本ブロックのテーブルをチェックする。
【００９０】
ライト先のアドレスと同じアドレスのリードがある場合、ダミーリードの挿入漏れがない、すなわち、ダミーリードがあると判定する。ライト先のアドレスと同じアドレスのリードがない場合（テーブルがない場合、またはテーブル内のリード回数が０回の場合）、ダミーリードの挿入漏れがある、すなわち、ダミーリードがないと判定する。
【００９１】
また、その基本ブロックの支配節に関数呼び出しがある場合、ダミーリードがあるか不明であるため、次の支配節に移る。その基本ブロックの全ての支配節の基本ブロックを探索し、リード回数が“０”であれば、ダミーリードがないと判定する。
【００９２】
２．２  ダミーリードチェックの変形例
第２実施形態のダミーリードチェックでは、支配節に関数呼び出しがある場合、必ずダミーリードの挿入漏れがあると判定したが、この変形例では、関数呼び出しにより呼び出される関数がアクセスする領域が、ソースプログラムにより指定されているものとする。これにより、ライト先のアクセス領域（メモリ領域）と、呼び出される関数のアクセス領域とが同一か否かを第１実施形態に示した構成で判定できる。
【００９３】
図１５は、変形例が適用されるプログラム例を示す図である。アクセスする領域の指定方法としては、例えば、関数修飾子や#pragma指令がある。図１５に示すプログラム例を参照すると、関数func1は、セクションDATA_SEC1のデータを読み、関数func2はセクションDATA_SEC2のデータを読む。その後、関数func1の呼び出しにより、セクションDATA_SEC1に置かれる変数ary1への書き込みに対応するダミーリードがあると判定される。同様に、関数func2の呼び出しにより、セクションDATA_SEC2に置かれる変数ary2への書き込みに対応するダミーリードがあると判定される。
【００９４】
前述したように、変形例では、アプリケーションのソースプログラム中の呼び出し関数がアクセスする領域を、ソースプログラム中にプログラム文によって明示する。そして、それをコンパイル装置が解釈することにより、ダミーリードの挿入漏れを、すなわちダミーリードの有無をチェックする。
【００９５】
この変形例では、ダミーリードの挿入対策として用意した関数（例えば、前記関数修飾子や#pragma指令）がライト命令の直後に呼ばれる場合、ダミーリードが挿入されていると判定し、警告出力の対象にしない。これにより、ダミーリード挿入漏れの誤判定を減らすことができるため、変形例のコンパイル装置が出力する警告に対してプログラム開発者による対応工数を低減できる。
【００９６】
２．３  第２実施形態の効果
第２実施形態によれば、ソースプログラムのコンパイル時にライト命令に対応するダミーリードの挿入漏れを検出することができるコンパイル装置を提供できる。
【００９７】
さらに、基本ブロック内にライト命令に対応するダミーリードがない場合、その基本ブロックの支配節となる基本ブロックまでダミーリードの探索範囲を広げることができる。このため、ダミーリード挿入漏れの検出精度を向上させることができる。
【００９８】
３．第３実施形態
プログラム言語規格で定められているライブラリ関数には、例えば「memcpy」や「memset」のように、メモリに書き込む機能を持った関数がある。第３実施形態は、「memcpy」や「memset」のようなメモリに書き込む機能を持つ関数を使用した場合に、関数呼び出しの直後の基本ブロック（及びその支配節）に対してダミーリードチェックを行う例である。第３実施形態の構成は、図２、図３、図４に示した第１実施形態の構成と同様であるため、記載を省略する。以下に、第１実施形態と異なる点について主に説明する。
【００９９】
３．１  ダミーリードチェック
ソースプログラムの書き込み機能を持つライブラリ関数に対して、コンパイル装置は規格で定められる引数がメモリ書き込み先のポインタであることを認識することができる。第３実施形態では、ライブラリ関数のメモリ書き込み先に対してダミーリードの挿入漏れがないか否かをチェックする。
【０１００】
ライブラリ関数が書き込むメモリ領域に対して、ダミーリードを探索する基本ブロックは、関数呼び出し直後の基本ブロックとその支配節である。
【０１０１】
第１引数が書き込み先であることは言語規格で定められているため、第１引数をライト先としてテーブルに定義する。その他のテーブル定義は第１実施形態と同様である。
【０１０２】
図１６は、第３実施形態のダミーリードチェックの処理を示すフローチャートである。図１７は、ダミーリードチェックの処理で生成されるテーブル例を示す図である。
【０１０３】
ステップＳ１０２Ａにて、基本ブロック内の中間コードが書き込み機能を持つ関数か否かを判定する。中間コードが書き込み機能を持つ関数である場合、ライト先の引数と同一の引数を記録したテーブルＰ５が既にあるか否かを判定する（ステップＳ１０３Ｂ）。
【０１０４】
ステップＳ１０３Ｂにて、同一の引数を記録したテーブルが既にある場合、そのテーブル内の引数のリード回数を“０”にする（ステップＳ１０４）。一方、同一の引数を記録したテーブルがない場合、新たなテーブル内にその引数を保存する（ステップＳ１０５Ｂ）。その後、ステップＳ１０６に進む。
【０１０５】
一方、ステップＳ１０２Ａにて、中間コードが書き込み機能を持つ関数でない場合、中間コードがリード処理（リード命令）か否かを判定する（ステップＳ１０７）。中間コードがリード処理である場合、リード先のアドレスが、テーブルＰ５内に保存されているライト先の第１引数が示すアドレスと同一か否かを判定する（ステップＳ１０８Ｂ）。
【０１０６】
ステップＳ１０８Ｂにて、アドレスが同一の場合はリード回数を“１”加算する、すなわち、リード回数をインクリメントする。（ステップＳ１０９）。その後、ステップＳ１０６に進む。一方、引数が同一でない場合は、次の中間コードへ移り（ステップＳ１１０）、ステップＳ１０２へ戻る。
【０１０７】
その他の処理は図５に示した処理と同様である。
【０１０８】
３．２  第３実施形態の効果
第３実施形態によれば、ソースプログラムのコンパイル時にライト命令に対応するダミーリードの挿入漏れを検出することができるコンパイル装置を提供できる。
【０１０９】
さらに、言語規格で定められている関数については、その関数の仕様に応じたダミーリードの挿入漏れチェックができる。これにより、第１実施形態で検出できなかったダミーリードの挿入漏れを検出することができる。
【０１１０】
４．第４実施形態
第４実施形態では、前述した第１〜第３実施形態におけるダミーリードチェックを実行するか否かを選択できるようにした例である。
【０１１１】
図１８は、第４実施形態の処理を示すフローチャートである。図示するように、ダミーリードチェックの処理（ステップＳ１３）の前に、ダミーリードチェックを実行するか否かの判定処理（ステップＳ１６）を設ける。ダミーリードチェックを実行する場合は、そのままダミーリードチェックへ進む。一方、ダミーリードチェックを実行しない場合は、ダミーリードチェックをパスしてレジスタ割り当ての処理（ステップＳ１４）に進む。
【０１１２】
４．２  第４実施形態の効果
第４実施形態よれば、ダミーリードチェックを実行するか否かを選択することができる。これにより、コンパイル処理の自由度が向上する。さらに、ダミーリードチェックを実行しない場合は、コンパイル処理に要する時間を短縮することが可能である。
【０１１３】
５．その他変形例等
本発明のいくつかの実施形態を説明したが、これらの実施形態は、例として提示したものであり、発明の範囲を限定することは意図していない。これら新規な実施形態は、その他の様々な形態で実施されることが可能であり、発明の要旨を逸脱しない範囲で、種々の省略、置き換え、変更を行うことができる。これら実施形態やその変形は、発明の範囲や要旨に含まれるとともに、特許請求の範囲に記載された発明とその均等の範囲に含まれる。
【符号の説明】
【０１１４】
１０…コンパイル装置、１１…ＣＰＵ、１２…ＲＡＭ、１３…ＲＯＭ、１４…入出力部、１５…バス。
【図１】
2018156568.tif 000003
【図２】
2018156568.tif 000004
【図３】
2018156568.tif 000005
【図４】
2018156568.tif 000006
【図５】
2018156568.tif 000007
【図６】
2018156568.tif 000008
【図７】
2018156568.tif 000009
【図８】
2018156568.tif 000010
【図９】
2018156568.tif 000011
【図１０】
2018156568.tif 000012
【図１１】
2018156568.tif 000013
【図１２】
2018156568.tif 000014
【図１３】
2018156568.tif 000015
【図１４】
2018156568.tif 000016
【図１５】
2018156568.tif 000017
【図１６】
2018156568.tif 000018
【図１７】
2018156568.tif 000019
【図１８】
2018156568.tif 000020