(57)【要約】      （修正有）【課題】分岐予測ミスの発生を抑止可能なオブジェクトコードを生成する。【解決手段】本コード生成装置１は、最適化の対象である最適化対象コードから、分岐条件が成立した場合に最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定する特定部と、特定部により特定された第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、ループインデックスの変化値について符号の正負を反転し、第１のループコードの外部のコードから参照される第１の変数への代入命令を分岐条件が成立した場合に第１の変数に代入する命令に変換し、且つ条件分岐命令を削除する処理を実行する最適化部１２０とを有する。【選択図】図２
2018067167.tif 000002
【特許請求の範囲】
【請求項１】
最適化の対象である最適化対象コードから、分岐条件が成立した場合に前記最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定する特定部と、
前記特定部により特定された前記第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、前記ループインデックスの変化値について符号の正負を反転し、前記第１のループのコードの外部のコードから参照される第１の変数への代入命令を前記分岐条件が成立した場合に前記第１の変数に代入する命令に変換し、且つ前記条件分岐命令を削除する処理を実行する最適化部と、
を有するコード生成装置。
【請求項２】
前記第１のループコードは、前記第１のループコードに含まれる条件分岐命令の数が１であるという第１の条件と、異なるループインデックス間でのデータ依存が無いという第２の条件と、前記第１のループコードの種別が所定の種別であるという第３の条件と、前記第１の変数への値の代入についての第４の条件とを満たす、
請求項１記載のコード生成装置。
【請求項３】
前記第４の条件は、代入先のアドレスが不変であるという第５の条件と、前記第１の変数への代入が前記条件分岐命令より前に行われるという第６の条件と、ループからの脱出が発生しない場合に前記第１の変数に代入される値を計算できるという第７の条件とを含む、
請求項２記載のコード生成装置。
【請求項４】
前記最適化部は、
前記第１のループコードによるループからの脱出が発生しない場合に前記第１の変数に代入される値を前記第１の変数に代入する命令を、前記第１のループコードの直前に追加する、
処理をさらに実行する請求項１乃至３のいずれか１つ記載のコード生成装置。
【請求項５】
前記代入命令を変換する処理において、
前記第１の変数への代入命令を一時変数への代入命令に変換し、前記分岐条件が成立した場合に前記第１の変数に前記一時変数の値を代入する命令を追加する、
請求項１乃至４のいずれか１つ記載のコード生成装置。
【請求項６】
コンピュータが、
最適化の対象である最適化対象コードから、分岐条件が成立した場合に前記最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定し、
特定された前記第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、前記ループインデックスの変化値について符号の正負を反転し、前記第１のループコードの外部のコードから参照される第１の変数への代入命令を前記分岐条件が成立した場合に前記第１の変数に代入する命令に変換し、且つ前記条件分岐命令を削除する処理を実行する、
ことを特徴とするコード生成方法。
【請求項７】
コンピュータに、
最適化の対象である最適化対象コードから、分岐条件が成立した場合に前記最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定させ、
特定された前記第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、前記ループインデックスの変化値について符号の正負を反転し、前記第１のループコードの外部のコードから参照される第１の変数への代入命令を前記分岐条件が成立した場合に前記第１の変数に代入する命令に変換し、且つ前記条件分岐命令を削除する処理を実行させる、
ことを特徴とするコード生成プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コード生成装置、コード生成方法及びコード生成プログラムに関する。
【背景技術】
【０００２】
ＣＰＵ（Central Processing Unit）は、プログラムの実行中に条件分岐命令について分岐予測及び実行すると予測した命令についての投機実行を行うことで命令制御パイプラインの効果を維持し、処理性能を高めることができる。しかし、分岐予測ミスが発生した場合には、パイプラインのフラッシュ処理（すなわちパイプラインフラッシュ）によって数十クロックサイクル程度の処理遅延が生じ、プログラムの実行完了までの時間が長くなる。
【０００３】
分岐予測ミスの発生を抑止する技術として、命令ループからの脱出の発生を管理するためのフラグを使用する技術が知られている。但し、この技術を利用する場合、新たに導入するフラグを格納するレジスタを定義するための命令及び参照するための命令が追加されるので、プログラムの命令数が増加する。また、必要なレジスタ数が増えるため、レジスタのスピル及びフィルによって数十から数百クロックサイクル程度の処理遅延が生じる可能性がある。さらに、脱出分岐を取り除くためループの繰り返しの回数が最大値で固定され、無駄な処理が発生する。
【０００４】
分岐予測ミスの発生の抑止に関して、プレディケイトレジスタを使用する方法も知られている。但し、この技術はプロセッサに専用の回路を導入することを前提としているので、汎用的な技術ではない。
【０００５】
また、両技術を利用する場合、平均実行時間の短縮に有効なＳＩＭＤ（Single Instruction Multiple Data）化及び並列化等の技術を利用することができない。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】米国特許出願公開第２０１５／２７７９１０号明細書
【特許文献２】特開２００１−１７５６１７号公報
【非特許文献】
【０００７】
【非特許文献１】サンマイクロシステムズ  インコーポレーテッド、外１社、“SPARC Joint Programming Specification (JPS1): Commonality”、［online］、平成１４年５月３１日、［平成２８年１０月５日検索］、インターネット＜URL：https://www.fujitsu.com/hk/Images/JPS1-R1.0.4-Common-pub.pdf＞
【発明の概要】
【発明が解決しようとする課題】
【０００８】
本発明の目的は、１つの側面では、分岐予測ミスの発生を抑止可能なオブジェクトコードを生成するための技術を提供することである。
【課題を解決するための手段】
【０００９】
本発明に係るコード生成装置は、最適化の対象である最適化対象コードから、分岐条件が成立した場合に最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定する特定部と、特定部により特定された第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、ループインデックスの変化値について符号の正負を反転し、第１のループコードの外部のコードから参照される第１の変数への代入命令を分岐条件が成立した場合に第１の変数に代入する命令に変換し、且つ条件分岐命令を削除する処理を実行する最適化部とを有する。
【発明の効果】
【００１０】
１つの側面では、分岐予測ミスの発生を抑止可能なオブジェクトコードを生成可能なコード生成装置、コード生成方法及びコード生成プログラムを提供できる。
【図面の簡単な説明】
【００１１】
【図１】図１は、リニアコード生成装置のハードウエア構成図である。
【図２】図２は、リニアコード生成装置の機能ブロック図である。
【図３】図３は、プログラム解析部により生成されるデータのデータ構造を示す図である。
【図４】図４は、プログラム解析部により生成されるデータのデータ構造を示す図である。
【図５】図５は、プログラム解析部が実行する処理の処理フローを示す図である。
【図６】図６は、プログラム解析部が実行する処理の処理フローを示す図である。
【図７】図７は、プログラム最適化部が実行する処理の処理フローを示す図である。
【図８】図８は、最適化処理の処理フローを示す図である。
【図９】図９は、最適化処理の処理フローを示す図である。
【図１０】図１０は、最適化処理の処理フローを示す図である。
【図１１】図１１は、ソースプログラムの一例を示す図である。
【図１２】図１２は、初期値についてのデータの一例を示す図である。
【図１３】図１３は、終値についてのデータの一例を示す図である。
【図１４】図１４は、増分値についてのデータの一例を示す図である。
【図１５】図１５は、プロローグについてのデータの一例を示す図である。
【図１６】図１６は、カーネルについてのデータの一例を示す図である。
【図１７】図１７は、置換表に登録されるエントリの一例を示す図である。
【図１８】図１８は、カーネルについてのデータの一例を示す図である。
【図１９】図１９は、カーネルについてのデータの一例を示す図である。
【図２０】図２０は、最適化により生成されるデータの一例を示す図である。
【図２１】図２１は、最適化により生成されるデータの一例を示す図である。
【図２２】図２２は、ループ回転の反転及び外部変数への代入について説明するための図である。
【図２３】図２３は、ループ回転の反転及び外部変数への代入について説明するための図である。
【図２４】図２４は、本実施の形態の最適化によって生成された中間コードを通常の最適化によって生成する場合におけるソースプログラムのイメージ図である。
【図２５】図２５は、コンパイラにより出力されるコードの一例を示す図である。
【図２６】図２６は、並列化が適用されたプログラムのイメージ図である。
【図２７】図２７は、ソースプログラムに対してアーキテクチャに依存しない最適化を実行した場合にコンパイラが出力する命令列の一例を示す図である。
【図２８】図２８は、脱出の発生を管理するためのフラグを利用して最適化を行った場合に出力される命令列の一例を示す図である。
【図２９】図２９は、プレディケイトレジスタを使用して最適化を行った場合に出力される命令列の一例を示す図である。
【図３０】図３０は、脱出の発生を管理するためのフラグを利用する技術及びプレディケイトレジスタを利用する技術の問題点を説明するための図である。
【発明を実施するための形態】
【００１２】
図１に、本実施の形態のリニアコード生成装置１のハードウエア構成図を示す。リニアコード生成装置１は、ＣＰＵ１１と、メモリ１２と、ＨＤＤ（Hard Disk Drive）１３とを有する。メモリ１２は、例えばＤＲＡＭ（Dynamic Random Access Memory）である。各ハードウエアコンポーネントはバスを介して互いに接続される。
【００１３】
本実施の形態の処理を実行するためのプログラムは、例えばＨＤＤ１３に格納されており、ＣＰＵ１１によってメモリ１２にロードされて実行されることで、図２に示すような各種機能を実現する。図２に、リニアコード生成装置１の機能ブロック図を示す。リニアコード生成装置１は、コンパイラ１００と、リンカ１４０と、データ格納部１６０とを含む。データ格納部１６０は、例えば、メモリ１２上或いはＨＤＤ１３上に設けられる。
【００１４】
コンパイラ１００は、入力処理部１１０と、最適化部１２０と、出力部１３０と、入出力制御部１５０とを含む。入力処理部１１０は、ソースプログラム入力処理部１１１と、字句解析部１１２と、意味解析部１１３と、第１中間コード出力部１１４とを含む。最適化部１２０は、第１中間コード入力処理部１２１と、プログラム解析部１２２と、プログラム最適化部１２３と、第２中間コード出力部１２４とを含む。出力部１３０は、第２中間コード入力処理部１３１と、オブジェクト生成部１３２とを含む。データ格納部１６０には、ソースプログラム１６１と、中間コード１６２と、中間コード１６３と、オブジェクトファイル１６４と、実行可能プログラム１６５とが格納される。
【００１５】
ソースプログラム入力処理部１１１は、データ格納部１６０に格納されているソースプログラム１６１を読み込み、ソースプログラム１６１に含まれる文字列を字句解析部１１２に渡す。字句解析部１１２は、ソースプログラム入力処理部１１１から受け取った文字列を解析し、トークンに分割して意味解析部１１３に渡す。意味解析部１１３は、字句解析部１１２から受け取ったトークン間の関係を解析し、中間コード１６２を生成する。第１中間コード出力部１１４は、生成された中間コード１６２を含むファイルをデータ格納部１６０に格納する。
【００１６】
第１中間コード入力処理部１２１は、データ格納部１６０に格納されたファイルから中間コード１６２を読み込み、プログラム解析部１２２に渡す。プログラム解析部１２２は、第１中間コード入力処理部１２１から受け取った中間コード１６２を解析し、命令情報、ブロック情報、ループ情報、制御グラフ及びデータ依存グラフ等を含む解析結果を生成する。プログラム最適化部１２３は、解析結果に基づき、中間コード１６２を最適化して中間コード１６３を生成する。第２中間コード出力部１２４は、生成された中間コード１６３を含むファイルをデータ格納部１６０に格納する。
【００１７】
第２中間コード入力処理部１３１は、データ格納部１６０に格納されたファイルから中間コード１６３を読み込み、オブジェクト生成部１３２に渡す。オブジェクト生成部１３２は、中間コード１６３からオブジェクトコードを生成し、生成したオブジェクトコードを含むオブジェクトファイル１６４をデータ格納部１６０に格納する。リンカ１４０は、オブジェクトファイル１６４に含まれるオブジェクトコードと他のオブジェクトコードとをリンクすることで実行可能プログラム１６５を生成し、生成した実行可能プログラム１６５をデータ格納部１６０に格納する。入出力制御部１５０は、コンパイラ１００とデータ格納部１６０との間でのデータ入出力を制御する。
【００１８】
次に、図３乃至図６を用いて、プログラム解析部１２２が実行する処理を説明する。プログラム解析部１２２は、以下で説明する処理を開始するにあたって、図３及び図４に示すようなデータ構造を有するデータをループごとに生成してデータ格納部１６０に格納しておく。図３及び図４の例では、ループ番号と、ループのタイプと、制御変数（ループインデックスとも呼ばれる）と、制御変数の初期値と、制御変数の終値と、制御変数の増分値（制御変数の変化量に相当する）と、ループの直前に位置するブロックであるプロローグと、ループ本体のブロックであるカーネルと、ループの直後に位置するブロックであるエピローグと、ループ外部で定義又は参照される変数名のリストである外部変数リストと、ループ回転を跨いだデータ依存がある変数名のリストと、本実施の形態の最適化の対象であるか否かを表す最適化対象フラグとについてデータが格納される。命令コード、入力オペランド及び出力オペランドは、ＳＰＡＲＣ命令セットのアセンブリ言語規則に従っている。メモリアドレスについては、ソースプログラム１６１中の変数名を使用して表記されている。以降、特に断りが無い限り、コンパイラ１００の出力命令列は同様の方法で記述される。ｖａｒ（ｘ）は、変数名がｘであるオペランドのオペランド番号を表す。頭文字がｔである変数名は、コンパイラ１００が内部的に生成した新規変数である。本例では増分値が使用されているが、減分値であってもよい。ＳＰＡＲＣ命令セットについては、例えば非特許文献１を参照のこと。
【００１９】
なお、レジスタＲに関して、Ｒを定義する命令の後にＲを参照する命令が実行される必要があることを、両命令の間に「ＲＡＷ（Read After Write）のデータ依存がある」という。特に、Ｒを定義する命令とＲを参照する命令とが同一ループ中にあり且つＲを定義する命令がＲを参照する命令よりも１つ以上前の繰り返しで実行される場合、「ループ回転を跨いだＲＡＷのデータ依存がある」という。つまり「ループ回転を跨いだＲＡＷのデータ依存がある」とは、異なるループインデックス間でのデータ依存があることを意味する。例えば、ｉ＝２のときにＲを定義する命令が実行され且つその後のｉ＝３のときにＲを参照する命令が実行されるようなケースが該当する。逆に、Ｒを参照する命令の後にＲを定義する命令が実行される必要があることを、両命令の間に「ＷＡＲ（Write After Read）のデータ依存がある」という。
【００２０】
本実施の形態においては、変数及び定数を表現するデータ構造をオペランドと呼ぶ。オペランドについては、以下のようなデータ構造で管理される。具体的には、オペランドごとに割り振られる一意の識別子であるオペランド番号と、オペランド種別（本実施の形態においては、定数、変数またはブロック）と、オペランド種別が定数の場合に設定される定数値と、オペランド種別が変数の場合に設定される変数名と、オペランド種別がブロックである場合に設定され且つブロックの識別に使用されるブロック番号とを使用して管理される。定数値は、コンパイル時点で決定可能な値である。変数名は、実装によってはレジスタ番号などが使用されてもよい。
【００２１】
命令は、以下のようなデータ構造で管理される。具体的には、命令ごとに割り振られる一意の識別子である命令番号と、命令の内容を表す識別子と、命令の入力である入力オペランドと、命令の出力である出力オペランドとを使用して管理される。本実施の形態の説明では、基本的にはＳＰＡＲＣ命令セットの命令コードが用いられ、脱出分岐命令については、一般的な条件分岐命令とは異なる命令コードが与えられる。比較結果が等しい場合に最内ループを脱出する脱出分岐命令を「ｂｒｅａｋｅｑ」命令と定義する。入力オペランド及び出力オペランドは、オペランド番号の配列で表される。なお、脱出分岐命令とは、分岐条件が成立した場合にループからの脱出が行われる条件分岐命令である。
【００２２】
なお、脱出とは、ループ中の脱出分岐命令の分岐条件が成立した時に、ループコード（本実施の形態においては、カーネルと同義）の直後に制御が移ることである。脱出分岐命令を含むループコードをリニアコードに変換する最適化はリニアライズと呼ばれる。リニアコードとは、脱出が行われないループコードのことである。
【００２３】
コンパイラ１００は、命令の集合をブロックと呼ばれるデータ構造で管理する。具体的には、ブロックごとに割り振られる一意な識別子であるブロック番号と、実行順に並べられたブロック内の１又は複数の命令を含む命令列とを使用して管理される。命令列は、命令番号の配列で表される。ブロックは条件分岐命令を単位として分割され、命令列の最終要素以外に条件分岐命令が出現することはない。但し、脱出分岐命令はブロックを分割しない特殊な命令として取り扱われ、命令列の最終要素以外にも出現することがある。
【００２４】
図３及び図４に示すようなデータがデータ格納部１６０に格納された場合に、プログラム解析部１２２は、当該データを用いて、以下のような処理を実行する。具体的には、プログラム解析部１２２は、中間コード１６２内のループのうち未処理のループを１つ特定する（図５：ステップＳ１）。以下では、ステップＳ１において特定されたループを対象のループと呼ぶ。
【００２５】
プログラム解析部１２２は、対象のループのタイプが所定のタイプであるか判定する（ステップＳ３）。所定のタイプとは、例えばＤＯ＿ＬＯＯＰ又はＷＨＩＬＥであり、脱出を考慮しない場合のループ回転数（すなわち、制御変数がとりうる値の数）は制御変数の初期値、終値及び増分値によって決まり、それらの値はループ中で変更されない。
【００２６】
対象のループのタイプが所定のタイプではない場合（ステップＳ３：Ｎｏルート）、処理はステップＳ２１に移行する。一方、対象のループのタイプが所定のタイプである場合（ステップＳ３：Ｙｅｓルート）、変数「脱出分岐命令数」に０を設定する（ステップＳ５）。
【００２７】
プログラム解析部１２２は、対象のループから未処理の命令を１つ特定し（ステップＳ７）（以下では、ステップＳ７において特定された命令を対象の命令と呼ぶ）、対象の命令が脱出分岐命令であるか判定する（ステップＳ９）。
【００２８】
対象の命令が脱出分岐命令ではない場合（ステップＳ９：Ｎｏルート）、処理は端子Ａを介して図６のステップＳ３１に移行する。
【００２９】
図６の説明に移行し、プログラム解析部１２２は、対象の命令から未処理の出力オペランドを１つ特定する（図６：ステップＳ３１）。以下では、ステップＳ３１において特定された出力オペランドを対象の出力オペランドと呼ぶ。
【００３０】
プログラム解析部１２２は、対象の出力オペランドについて、ループ回転を跨いだＲＡＷのデータ依存およびループ回転を跨いだＷＡＲのデータ依存が無いか判定する（ステップＳ３３）。ステップＳ３３においては、ループ回転を跨いだデータ依存がある変数名のリストを用いて判定が行われる。
【００３１】
対象の出力オペランドについて、ループ回転を跨いだＲＡＷのデータ依存又はループ回転を跨いだＷＡＲのデータ依存が有る場合（ステップＳ３３：Ｎｏルート）、処理は端子Ｃを介して図５のステップＳ２１に移行する。
【００３２】
対象の出力オペランドについて、ループ回転を跨いだＲＡＷのデータ依存およびループ回転を跨いだＷＡＲのデータ依存が無い場合（ステップＳ３３：Ｙｅｓルート）、プログラム解析部１２２は、以下の処理を実行する。具体的には、プログラム解析部１２２は、対象の出力オペランドの変数名が外部変数リストに含まれるか判定する（ステップＳ３５）。
【００３３】
対象の出力オペランドの変数名が外部変数リストに含まれない場合（ステップＳ３５：Ｎｏルート）、処理はステップＳ３９に移行する。
【００３４】
一方、対象の出力オペランドの変数名が外部変数リストに含まれる場合（ステップＳ３５：Ｙｅｓルート）、プログラム解析部１２２は、対象の出力オペランドである変数（すなわち、外部変数）への代入が、外部変数への代入についての条件を満たすか判定する（ステップＳ３７）。外部変数への代入についての条件は、詳細には以下のとおりである。
【００３５】
（１．１）代入先のアドレスがループ内で不変である（出力オペランドが、例えば単純変数、添え字が定数である配列要素或いは不変なポインタ変数実態等である）。
（１．２）代入はループ内で脱出分岐命令よりも前に実行される。
（１．３）ループからの脱出が発生しない場合に代入される値（終値）を計算できる。
【００３６】
なお、ループからの脱出が発生しない場合に代入される値の計算については、例えば特許文献２を参照されたい。
【００３７】
対象の出力オペランドである変数への代入が、外部変数への代入についての条件を満たさない場合（ステップＳ３７：Ｎｏルート）、処理は端子Ｃを介して図５のステップＳ２１に移行する。
【００３８】
対象の出力オペランドである変数への代入が、外部変数への代入についての条件を満たす場合（ステップＳ３７：Ｙｅｓルート）、プログラム解析部１２２は、対象の命令に未処理の出力オペランドが有るか判定する（ステップＳ３９）。
【００３９】
未処理の出力オペランドが有る場合（ステップＳ３９：Ｙｅｓルート）、処理はステップＳ３１に戻る。一方、未処理の出力オペランドが無い場合（ステップＳ３９：Ｎｏルート）、処理は端子Ｂを介して図５のステップＳ１５に移行する。
【００４０】
図５の説明に戻り、対象の命令が脱出分岐命令である場合（ステップＳ９：Ｙｅｓルート）、プログラム解析部１２２は、脱出分岐命令数を１インクリメントする（ステップＳ１１）。
【００４１】
プログラム解析部１２２は、脱出分岐命令数が１以下であるか判定する（ステップＳ１３）。脱出分岐命令数が１以下ではない場合（ステップＳ１３：Ｎｏルート）、処理はステップＳ２１に移行する。脱出分岐命令数が１以下である場合（ステップＳ１３：Ｙｅｓルート）、プログラム解析部１２２は、対象のループに未処理の命令が有るか判定する（ステップＳ１５）。
【００４２】
未処理の命令が有る場合（ステップＳ１５：Ｙｅｓルート）、処理はステップＳ７に戻る。一方、未処理の命令が無い場合（ステップＳ１５：Ｎｏルート）、プログラム解析部１２２は、脱出分岐命令数が１であるか判定する（ステップＳ１７）。
【００４３】
脱出分岐命令数が１ではない場合（ステップＳ１７：Ｎｏルート）、処理はステップＳ２１に移行する。一方、脱出分岐命令数が１である場合（ステップＳ１７：Ｙｅｓルート）、プログラム解析部１２２は、最適化対象フラグを「ｔｒｕｅ」に設定する（ステップＳ１９）。
【００４４】
プログラム解析部１２２は、中間コード１６２に未処理のループが有るか判定する（ステップＳ２１）。未処理のループが有る場合（ステップＳ２１：Ｙｅｓルート）、処理はステップＳ１に戻る。一方、未処理のループが無い場合（ステップＳ２１：Ｎｏルート）、処理は終了する。
【００４５】
以上のように、プログラム解析部１２２の処理によって、以下の４つの条件を満たすループが特定される。
【００４６】
（１）外部変数への代入についての条件
（２）ループ中に唯一つの脱出分岐命令を含むという条件
（３）脱出を考慮しない場合のループ回転数は、制御変数の初期値、終値及び増分値によって決まり、それらの値はループ中で変更されないという条件
（４）ループ回転を跨いだデータ依存が存在しないという条件
【００４７】
条件（１）はステップＳ３７にて判定される。条件（２）はステップＳ１３にて判定される。条件（３）はステップＳ３にて判定される。条件（４）はステップＳ３３にて判定される。
【００４８】
以上のような処理を実行すれば、本実施の形態の最適化に適したループが特定されるようになる。
【００４９】
次に、図７乃至図１０を用いて、プログラム最適化部１２３が実行する処理を説明する。
【００５０】
まず、プログラム最適化部１２３は、中間コード１６２内のループのうち未処理のループを１つ特定する（図７：ステップＳ４１）。以下、ステップＳ４１において特定されたループを対象のループと呼ぶ。
【００５１】
プログラム最適化部１２３は、対象のループの最適化対象フラグが「ｔｒｕｅ」に設定されているか判定する（ステップＳ４３）。
【００５２】
対象のループの最適化対象フラグが「ｔｒｕｅ」に設定されていない場合（ステップＳ４３：Ｎｏルート）、処理はステップＳ４７に移行する。一方、対象のループの最適化対象フラグが「ｔｒｕｅ」に設定されている場合（ステップＳ４３：Ｙｅｓルート）、プログラム最適化部１２３は、最適化処理を実行する（ステップＳ４５）。最適化処理については、図８乃至図１０を用いて説明する。
【００５３】
まず、プログラム最適化部１２３は、対象のループの制御変数の初期値、終値及び増分値を、所定のルールに従って変更する（図８：ステップＳ５１）。ステップＳ５１においては、元の初期値がｓである場合には（ｓ＋ｒｏｕｎｄ＿ｔｏｗａｒｄｓ＿ｚｅｒｏ（（ｅ−ｓ）／ｄ）＊ｄ）に変更され、元の終値がｅである場合にはｓに変更され、元の増分値がｄである場合には−ｄに変更される。このような変更により、制御変数の値は元の終値（但し、厳密には終値ではない場合がある）から元の初期値までｄずつ変化することになる。本実施の形態においては、このような操作を「ループの回転方向を反転する」操作と呼ぶ。なお、初期値及び増分値を計算するための命令はループブロックの直前に挿入される。
【００５４】
プログラム最適化部１２３は、脱出分岐命令の検出フラグを「ｆａｌｓｅ」に設定する（ステップＳ５３）。脱出分岐命令の検出フラグは、脱出分岐命令が検出された場合に「ｔｒｕｅ」に設定される。
【００５５】
プログラム最適化部１２３は、対象のループから未処理の命令を１つ特定する（ステップＳ５５）。以下では、ステップＳ５５において特定された命令を対象の命令と呼ぶ。
【００５６】
プログラム最適化部１２３は、対象の命令から未処理の入力オペランドを１つ特定する（ステップＳ５７）。以下では、ステップＳ５７において特定された入力オペランドを対象の入力オペランドと呼ぶ。
【００５７】
プログラム最適化部１２３は、対象の入力オペランドが置換表のｋｅｙ［］のいずれかに一致するか判定する（ステップＳ５９）。置換表には、ｋｅｙ［］とｖａｌｕｅ［］とのセットを含むエントリが１又は複数登録される。括弧内にはオペランド番号が格納される。置換表へのエントリの登録については、後で説明する。
【００５８】
対象の入力オペランドが置換表のｋｅｙ［］のいずれにも一致しない場合（ステップＳ５９：Ｎｏルート）、処理はステップＳ６３に移行する。一方、対象の入力オペランドが置換表のｋｅｙ［］のいずれかに一致する場合（ステップＳ５９：Ｙｅｓルート）、プログラム最適化部１２３は、以下の処理を実行する。具体的には、プログラム最適化部１２３は、該当するｋｅｙ［］に対応するｖａｌｕｅ［］を置換表から読み出し、読み出したｖａｌｕｅ［］で対象の入力オペランドを置換する（ステップＳ６１）。
【００５９】
プログラム最適化部１２３は、未処理の入力オペランドが有るか判定する（ステップＳ６３）。未処理の入力オペランドが有る場合（ステップＳ６３：Ｙｅｓルート）、処理はステップＳ５７に戻る。一方、未処理の入力オペランドが無い場合（ステップＳ６３：Ｎｏルート）、処理は端子Ｄを介して図９のステップＳ６５に移行する。
【００６０】
図９の説明に移行し、プログラム最適化部１２３は、対象の命令は脱出分岐命令であるか判定する（図９：ステップＳ６５）。
【００６１】
対象の命令は脱出分岐命令である場合（ステップＳ６５：Ｙｅｓルート）、処理は端子Ｅを介して図１０のステップＳ９１に移行する。
【００６２】
図１０の説明に移行し、プログラム最適化部１２３は、脱出分岐命令の検出フラグを「ｔｒｕｅ」に設定する（図１０：ステップＳ９１）。
【００６３】
プログラム最適化部１２３は、置換表から未処理のエントリを１つ特定する（ステップＳ９３）。
【００６４】
プログラム最適化部１２３は、ステップＳ９３において特定されたエントリに含まれるｋｅｙ［］を代入先とし、ｖａｌｕｅ［］を代入元とし且つ対象の命令（すなわち、脱出分岐命令）の分岐条件を条件とする条件付代入命令を生成する。そして、プログラム最適化部１２３は、生成した条件付代入命令を、対象の命令の直前に追加する（ステップＳ９５）。条件付代入命令とは、条件が成立した場合に代入を行うための命令である。
【００６５】
プログラム最適化部１２３は、置換表に未処理のエントリが有るか判定する（ステップＳ９７）。未処理のエントリが有る場合（ステップＳ９７：Ｙｅｓルート）、処理はステップＳ９３に戻る。一方、未処理のエントリが無い場合（ステップＳ９７：Ｎｏルート）、プログラム最適化部１２３は、以下の処理を実行する。具体的には、プログラム最適化部１２３は、対象の命令（すなわち、脱出分岐命令）を削除する（ステップＳ９９）。処理は端子Ｆを介して図９のステップＳ８３に移行する。
【００６６】
図９の説明に戻り、対象の命令は脱出分岐命令ではない場合（ステップＳ６５：Ｎｏルート）、プログラム最適化部１２３は、脱出分岐命令の検出フラグが「ｔｒｕｅ」に設定されているか判定する（ステップＳ６７）。
【００６７】
脱出分岐命令の検出フラグが「ｔｒｕｅ」に設定されている場合（ステップＳ６７：Ｙｅｓルート）、処理はステップＳ８３に移行する。一方、脱出分岐命令の検出フラグが「ｔｒｕｅ」に設定されていない場合（ステップＳ６７：Ｎｏルート）、プログラム最適化部１２３は、対象の命令から未処理の出力オペランドを１つ特定する（ステップＳ６９）。以下、ステップＳ６９において特定された出力オペランドを対象の出力オペランドと呼ぶ。
【００６８】
プログラム最適化部１２３は、対象の出力オペランドは外部変数リストに含まれるか判定する（ステップＳ７１）。
【００６９】
対象の出力オペランドは外部変数リストに含まれない場合（ステップＳ７１：Ｎｏルート）、処理はステップＳ８１に移行する。一方、対象の出力オペランドは外部変数リストに含まれる場合（ステップＳ７１：Ｙｅｓルート）、プログラム最適化部１２３は、対象のループに対応するプロローグに、終値の代入命令を追加する（ステップＳ７３）。ステップＳ７３における終値とは、ループからの脱出が発生しない場合に外部変数に代入される値である。場合によってはループからの脱出が発生しないこともあるので、このような処理を実行することで、ループからの脱出が発生しない場合にも外部変数に値を代入しておくことができるようになる。
【００７０】
プログラム最適化部１２３は、対象の出力オペランドについて一時変数ｔｍｐを生成する（ステップＳ７５）。なお、一時変数ｔｍｐは、ステップＳ７５の処理が行われる度に異なるものが生成される。
【００７１】
プログラム最適化部１２３は、ｋｅｙ［］が対象の出力オペランドであり且つｖａｌｕｅ［］がｔｍｐであるエントリを置換表に追加する（ステップＳ７７）。そして、プログラム最適化部１２３は、対象の出力オペランドをｔｍｐで置換する（ステップＳ７９）。
【００７２】
プログラム最適化部１２３は、対象の命令に未処理の出力オペランドが有るか判定する（ステップＳ８１）。未処理の出力オペランドが有る場合（ステップＳ８１：Ｙｅｓルート）、処理はステップＳ６９に戻る。
【００７３】
一方、未処理の出力オペランドが無い場合（ステップＳ８１：Ｎｏルート）、プログラム最適化部１２３は、対象のループに未処理の命令が有るか判定する（ステップＳ８３）。
【００７４】
対象の命令に未処理の命令が有る場合（ステップＳ８３：Ｙｅｓルート）、処理は端子Ｇを介して図８のステップＳ５５に移行する。
【００７５】
一方、対象の命令に未処理の命令が無い場合（ステップＳ８３：Ｎｏルート）、プログラム最適化部１２３は、コピー伝播及び無用コードの除去を実行する（ステップＳ８５）。ステップＳ８５の処理によって、一時変数の定義及び参照は無くなり、代入命令が条件付代入命令で置換されたことになる。そして処理は呼び出し元に戻る。
【００７６】
図７の説明に戻り、プログラム最適化部１２３は、中間コード１６２に未処理のループがあるか判定する（ステップＳ４７）。未処理のループが有る場合（ステップＳ４７：Ｙｅｓルート）、処理はステップＳ４１に戻る。一方、未処理のループが無い場合（ステップＳ４７：Ｎｏルート）、処理は終了する。
【００７７】
以上のような処理を実行すれば、ループ回転を跨いだＲＡＷのデータ依存を有する変数を作ることなく、脱出分岐命令を含むループをリニアライズすることができるようになる。これにより、ＳＩＭＤ化及び並列化といった最適化を適用することができるようになり、また、並列度を上げることによって処理にかかる時間を短縮することができるようになる。また、分岐条件が成立したか否かを示すフラグが保持するレジスタ並びにそのレジスタを定義するための命令及び参照するための命令が不要になる。さらに、汎用的な命令だけを用いて実現することができるので、特殊なハードウエアを導入しなくてもよい。
【００７８】
以上のような本実施の形態の処理について、具体例を用いて説明を追加する。ここでは、図３及び図４に示したデータを例として説明する。ソースプログラム１６１は、図１１に示すプログラムであるとする。図１１に示すように、ソースプログラム１６１にはループコードが含まれ、ループコードには脱出分岐命令が含まれる。
【００７９】
ループが最適化の対象である場合、図４における最適化対象フラグは「ｆａｌｓｅ」から「ｔｒｕｅ」に変更される。
【００８０】
初期値についてのデータは図１２（ａ）に示すデータから図１２（ｂ）に示すデータに変更される。終値についてのデータは図１３（ａ）に示すデータから図１３（ｂ）に示すデータに変更される。増分値についてのデータは図１４（ａ）に示すデータから図１４（ｂ）に示すデータに変更される。
【００８１】
カーネルにおける命令「ｍｏｖ    ｖａｒ（ｉ），ｖａｒ（ｉｎｄｅｘ）」は、出力オペランドが外部変数リストに含まれるので、一時変数（ｔ３とする）が生成され、プロローグに対して終値の代入処理が追加される。プロローグについてのデータは、終値の代入命令が追加されたことによって、例えば図１５（ａ）に示すデータから図１５（ｂ）に示すデータに変更される。また、カーネルについては、図１６（ａ）に示すデータが図１６（ｂ）に示すデータに変更される。すなわち、カーネルにおけるｖａｒ（ｉｎｄｅｘ）はｖａｒ（ｔ３）で置換される。置換表には、例えば図１７に示すようなエントリが追加される。
【００８２】
カーネルにおける命令「ｌｄ    ［ｖａｒ（ｘ）＋ｖａｒ（ｉ）］，ｖａｒ（ｔ２）」及び「ｃｍｐ    ｖａｒ（ｔ２），ｖａｒ（ａ）」は、脱出分岐命令ではないこと、入力オペランドｖａｒ（ｘ）及びｖａｒ（ｉ）は置換表にｋｅｙとして登録されていないこと、並びに出力オペランドｖａｒ（ｔ２）は外部変数リストに含まれないので、これらの命令に対する置換等は行われない。
【００８３】
カーネルにおける命令「ｂｒｅａｋｅｑ  ％ｉｃｃ」は、脱出分岐命令であるので、以下の処理が行われる。具体的には、置換表に存在する各エントリについて、条件付代入命令が脱出分岐命令「ｂｒｅａｋｅｑ  ％ｉｃｃ」の直前に挿入される。また、脱出分岐命令「ｂｒｅａｋｅｑ  ％ｉｃｃ」が削除される。このような処理によって、カーネルについては、図１８（ａ）に示すデータが図１８（ｂ）に示すデータに変更される。すなわち、命令「ｍｏｖｅ    ％ｉｃｃ，ｖａｒ（ｔ３），ｖａｒ（ｉｎｄｅｘ）」が命令「ｂｒｅａｋｅｑ  ％ｉｃｃ」の直前に追加され、命令「ｂｒｅａｋｅｑ  ％ｉｃｃ」は削除される。
【００８４】
コピー伝播及び無用コードの除去によって一時変数ｖａｒ（ｔ３）は削除されるので、カーネルについてのデータは、図１９（ａ）に示すデータから図１９（ｂ）に示すデータに変更される。
【００８５】
以上のような最適化によって、図３及び図４に示したデータは、図２０及び図２１に示すデータに変更される。最適化の完了後、最適化対象フラグは「ｆａｌｓｅ」から「ｔｒｕｅ」に変更される。
【００８６】
図２２及び図２３を用いて、ループ回転の反転及び外部変数への代入について説明を追加する。図２２に、脱出の発生を管理するためのフラグを利用する技術を適用した場合について説明する。図２２の例では、制御変数ｉの初期値が０であり、増分値は１である。ｉ＝２の場合に分岐条件が成立し、外部変数に値が代入される。このとき、フラグは０から１に変更される。ｉ＝６の場合にも分岐条件が成立するが、フラグが１であるため、値は変数に代入されずに破棄される。このような方法により、最初に分岐条件が成立したときの値を外部変数の値とすることができる。
【００８７】
図２３に、本実施の形態の場合について説明する。ループ回転が反転されているので、・・・ｉ＝６，ｉ＝５、・・・ｉ＝０というように処理は実行される。ｉ＝６のとき分岐条件が成立し、外部変数に値が代入される。ｉ＝２のときも分岐条件が成立し、外部変数に値が代入される。このような方法により、フラグを格納するためのレジスタを別途用意することなく、もともとの実行順序であれば最初に分岐条件が成立したときに代入される値を外部変数の値とすることができる。
【００８８】
図２４に、本実施の形態の最適化によって生成された中間コード１６２を通常の最適化によって生成する場合におけるソースプログラム１６１のイメージを示す。なお、実際に図２４に示すようなプログラムが本実施の形態の処理により生成されるわけではない。ノンフォルティングロード命令については、例えば特許文献１を参照されたい。
【００８９】
図２５に、本実施の形態のコンパイラ１００により出力されるコードの一例を示す。後で説明する図２８と比較すると、ループ中の命令数が８から６に減少し、使用レジスタ数が５から４に減少しており、効率がよいプログラムが生成されている。また、特殊なハードウエアを必要とする命令を使用しておらず、制御変数以外の変数については、ループ回転を跨いだＲＡＷのデータ依存が無い。
【００９０】
命令アドレス０ｘ００２８の命令によって、脱出分岐命令の分岐条件が満たされていれば値が代入（上書きの場合もある）される。命令アドレス０ｘ００２ｃの命令によって、元のプログラムでループ脱出の直前に外部変数に保持されていた値が、最終的に保持される値になる。命令アドレス０ｘ００３０の命令によって、ループの回転方向が反転される。
【００９１】
元のプログラムとの等価性は、以下の３点により保証されている。
（１）外部変数には、脱出分岐命令の分岐条件が満たされた場合にのみ値が代入される。
（２）ループの回転方向が反転されているため、最後に書き込まれる値が元のプログラムでループの脱出直前に外部変数に保持されている値である。
（３）脱出分岐命令の分岐条件が満たされない場合、ループ前に代入された終値が使用される。
【００９２】
図２５に示したコードにおいては、制御変数以外の変数について、ループ回転を跨いだＲＡＷのデータ依存が無いため、ＳＩＭＤ化及び並列化を適用することができる。図２６に、並列度２で並列化されたプログラムのイメージを示す。図２６に示すように、コード２６１によって、配列ｘ［］の前半分と後半分とが別々のプロセスで処理されるようになる。コード２６２によって、後半分の結果がｉｎｄｅｘに反映されるようになる。コード２６３によって、前半分のどこかで脱出分岐命令の分岐条件が成立していれば前半分の結果がｉｎｄｅｘに反映されるようになる。なお、並列化の詳細及び並列化とデータ依存との関係については、例えば"A.V.エイホ, R.セシィ, J.D.ウルマン, その他, "コンパイラ―原理・技法・ツール (Information & Computing)", サイエンス社, 第２版"を参照されたい。
【００９３】
なお、同様の原理でＳＩＭＤ化も可能である。ＳＩＭＤ化の詳細及びＳＩＭＤ化とデータ依存との関係については、例えば"Martin Kong, Richard Veras, Kevin Stock, Franz Franchetti, Louis-Noel Pouchet, P.Sadayappan, "When Polyhedral Transformations Meet SIMD Code Generation", Proceedings of the 34th ACM SIGPLAN Conference on Programming Language Design and Implementation, Pages 127-138"を参照されたい。
【００９４】
ＳＩＭＤ化及び並列化を適用した場合、最適化後のループ回転数Ｎoptは、最適化前のループ回転数Ｎ、ＳＩＭＤ長Ｌ（≧１）及び並列度Ｐ（≧１）を用いて、Ｎopt＝Ｎ／（Ｌ＊Ｐ）で表わされる。例えば、Ｌ＝１６であり（例えば、４バイト整数演算を５１２バイトのＳＩＭＤレジスタを使用してＳＩＭＤ化する場合）且つＰ＝１６（例えば、１６コアのプロセッサの場合）である場合、ＬＰ＝２５６であり、脱出分岐命令の分岐条件が成立する制御変数の値が一様乱数である場合には、平均実行時間は最適化前の１／１２８になる。
【００９５】
但し、分岐条件が成立する制御変数の値が一様乱数ではなく偏りがあり且つ値が比較的小さい場合、又は、回転数Ｎが少なく１回転あたりの処理命令数が多い場合、さらにプロファイル最適化等を併用し、リニアライズ最適化そのものを抑止した方がよい。プロファイル最適化については、例えば"Pohua P. Chang, Scott A. Mahlke, Wen-mei W. Hwu, "Using Profile Information to Assist Classic Code Optimizations", Software-Practice & Experience archive, Volume 21 Issue 12, Dec. 1991, Pages 1301-1321"を参照されたい。
【００９６】
以上本発明の一実施の形態を説明したが、本発明はこれに限定されるものではない。例えば、上で説明したリニアコード生成装置１の機能ブロック構成は実際のプログラムモジュール構成に一致しない場合もある。
【００９７】
また、上で説明したデータ構成は一例であって、上記のような構成でなければならないわけではない。さらに、処理フローにおいても、処理結果が変わらなければ処理の順番を入れ替えることも可能である。さらに、並列に実行させるようにしても良い。
【００９８】
［付録］
本付録においては、背景技術の欄において述べた２つの技術の説明を追加する。
【００９９】
例えば、図１１に示したソースプログラム１６１に対してアーキテクチャに依存しない最適化を実行した場合にコンパイラが出力する命令列を図２７に示す。アーキテクチャに依存しない最適化とは、どのようなアーキテクチャの汎用プロセッサであってもサポートされている命令（例えば、四則演算、条件分岐命令及びメモリアクセス命令など）だけを使用して実現できる最適化である。
【０１００】
図１１に示したソースプログラム１６１のループが複数回実行され、実行される度に脱出時のループインデックス（すなわちｉ）が異なるような場合、図２７における命令アドレス０ｘ００２４の脱出分岐命令において分岐予測ミスが多発する可能性がある。背景技術の欄で述べたように、分岐予測ミスの発生は、パイプラインのフラッシュ処理により数十クロックサイクル程度の処理遅延を発生させる。
【０１０１】
分岐予測ミスの発生を抑止するため、脱出の発生を管理するためのフラグを利用する場合、例えば図２８に示すような命令列が出力される。図２８においては、分岐条件が成立したか否かを示すフラグが命令アドレス０ｘ００１８の命令によって設定される。命令アドレス０ｘ００２０の命令によれば、フラグがセットされている場合には％ｏ４の値が更新されない。従って、命令アドレス０ｘ００２４の命令によって同じ値が同じ場所に書き込み続けられることになる（すなわち、実質的に空ループになる）。命令アドレス０ｘ００３０の命令によって、分岐条件が成立した場合にはフラグがセットされる。条件付代入命令は、ハードウエアの設計上、少数の基本論理回路の組合せによって実装することが可能であり分岐予測ミスが発生しないので、命令アドレス０ｘ００３０の命令はＯＲ（ＡＮＤ（ＮＯＴ（％ｉｃｃ．ｚ），％ｏ３），ＡＮＤ（％ｉｃｃ．ｚ，１））と等価である。この技術においては、元のループコードから脱出分岐命令を削除する代わりに「現在実行している命令が、元のループで本来実行されない、脱出分岐命令以降の命令である」ことを示すフラグが設けられる。メモリにデータを書き込む前にフラグが参照され、条件付代入命令を用いて「現在メモリ上にあるデータ」と「更新されたデータ」とのどちらを書き込むか決定することで、脱出と等価な処理が実現される。
【０１０２】
分岐予測ミスの発生を抑止するため、プレディケイトレジスタを使用する技術の場合、例えば図２９に示すような命令列が出力される。図２９においては、分岐条件が成立したか否かを示すフラグが命令アドレス０ｘ００１８の命令によって設定されており、プレディケイトレジスタを備えるプロセッサは、プレディケイトレジスタに値が設定されている場合に一部の命令の実行をスキップすることができる。図２９においては、太線枠２９１によって囲まれた部分の命令列がスキップされる。太線枠２９１に含まれる、命令アドレス０ｘ００２ｃの命令によって、プレディケイトレジスタに値が設定される。
【０１０３】
但し、脱出分岐命令が無くなることでループの回転数が最大値で固定され、無駄な処理を実行することになる。特に、ループの回転数が多く、比較的早期にループから脱出する場合、最適化前と比べると実行時間が長くなる。例えば、前者の技術の場合、最適化前のループ回転数をＮ、分岐条件がＸ回転目で成立するとして、Ｘが１からＮの一様乱数をとる場合、ループの平均回転数はＮ／２からＮに増加する。ループ１回転あたりの処理時間をＴbodyとし、分岐予測ミスによる時間損失をＴbntとすると、（Ｔbody＊Ｎ／２≧Ｔbnt）の場合に実行時間が長くなる。
【０１０４】
また、背景技術の欄で述べたように、ループ回転を跨いだＲＡＷのデータ依存があり、そのために、ＳＩＭＤ化や並列化等の技術を適用することができないので、先に述べた、ループ回転数が多くなるという問題を解決できない。
【０１０５】
また、フラグを使用する方式については、フラグを保持するためのレジスタが必要であり、必要なレジスタ数が増加する。また、レジスタを定義するための命令及び参照するための命令を追加することになるため、命令数が増加する。必要なレジスタ数がプロセッサに搭載されている実レジスタ数を超えると、一時的にレジスタ上のデータをメモリ上に退避する処理（すなわちスピル）及びメモリ上に退避されたデータをレジスタ上に復元する処理（すなわちフィル）が行われる。スピル及びフィルに要する時間はアーキテクチャによって異なるが、一般的に、数サイクルから数百サイクルを要するため、性能を大きく低下させる原因になりうる。
【０１０６】
また、後者の技術の場合、プロセッサに大規模な回路を搭載することを前提としており、汎用的な技術ではない。前者の方法で使用される条件付代入命令やノンフォルティングロード命令は、既存の回路に数個の論理ゲートを付け加えれば実現できる単純な命令であり、多くのアーキテクチャで採用されている（例えば、ＳＰＡＲＣ、ｘ８６＿６４、ＩＡ−６４など）。これに対し、後者の方法の命令制御を実現するためにはパイプライン制御部に複雑な回路を組み込まなければならず、後者の方法を採用するアーキテクチャは稀である。
【０１０７】
以上の４つの問題点のうち最後の問題点以外の問題点の具体例を、図３０を用いて説明する。図３０に示したコードは、図２８に示したコードと同じである。図３０の例において、ループの回転数はｎであり、ループの回転数は最大値で固定されている。また、命令アドレス０ｘ００１ｃの命令及び命令アドレス０ｘ００３０の命令は、ループ回転を跨いだＲＡＷのデータ依存に該当する。さらに、命令アドレス０ｘ００１８の命令、命令アドレス０ｘ００１ｃの命令及び命令アドレス０ｘ００３０の命令は、新たに導入されたフラグを定義するための命令及び参照するための命令である。
【０１０８】
なお、分岐予測については、例えば"Hisa Ando, "コンピュータアーキテクチャ技術入門 高速化の追求×消費電力の壁 (WEB+DB PRESS plus)", 技術評論社, 2014年05月01日"を参照されたい。
【０１０９】
以上で本付録を終了する。
【０１１０】
以上述べた本発明の実施の形態をまとめると、以下のようになる。
【０１１１】
本実施の形態の第１の態様に係るコード生成装置は、（Ａ）最適化の対象である最適化対象コードから、分岐条件（例えば、実施の形態における脱出分岐条件）が成立した場合に最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定する特定部（例えば、実施の形態におけるプログラム解析部１２２）と、（Ｂ）特定部により特定された第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、ループインデックスの変化値について符号の正負を反転し、第１のループコードの外部のコードから参照される第１の変数への代入命令を分岐条件が成立した場合に第１の変数に代入する命令に変換し、且つ条件分岐命令を削除する処理を実行する最適化部（例えば、実施の形態におけるプログラム最適化部１２３）とを有する。
【０１１２】
このような処理によって生成されるコードであれば、ループからの脱出が発生しないような形で、元のコードに基づく処理と等価な処理を実現することができるようになる。これにより、分岐予測ミスの発生を抑止可能なオブジェクトコードを生成することができるようになる。また、上記処理によって生成されるコードに対してはＳＩＭＤ化や並列化といった技術を適用することができるので、実行時間を短縮することができるようになる。さらに、レジスタ数が増えることがなく、特殊なハードウエアを導入することもない。
【０１１３】
また、第１のループコードは、第１のループコードに含まれる条件分岐命令の数が１であるという第１の条件と、異なるループインデックス間でのデータ依存が無いという第２の条件と、第１のループコードの種別が所定の種別であるという第３の条件と、第１の変数への値の代入についての第４の条件とを満たしてもよい。最適化部による最適化が有効なループコードを特定できるようになる。
【０１１４】
また、第４の条件は、代入先のアドレスが不変であるという第５の条件と、第１の変数への代入が条件分岐命令より前に行われるという第６の条件と、ループからの脱出が発生しない場合に第１の変数に代入される値を計算できるという第７の条件とを含んでもよい。最適化部による最適化が有効なループコードを特定できるようになる。
【０１１５】
また、最適化部は、（ｂ１）第１のループコードによるループからの脱出が発生しない場合に第１の変数に代入される値を第１の変数に代入する命令を、第１のループコードの直前に追加する処理をさらに実行してもよい。場合によってはループからの脱出が発生しないこともあるので、このような処理を実行することで、ループからの脱出が発生しない場合にエラーとなることを防ぐことができるようになる。
【０１１６】
また、代入命令の変換処理において、（ｂ２）第１の変数への代入命令を一時変数への代入命令に変換し、分岐条件が成立した場合に第１の変数に一時変数の値を代入する命令を追加してもよい。
【０１１７】
また、最適化部は、（ｂ３）特定部により特定された第１のループコードに対して、コピー伝播と不要なコードの削除とを実行してもよい。
【０１１８】
また、本コード生成装置は、（Ｃ）最適化部の処理によって生成されたコードからオブジェクトコードを生成する生成部（例えば、実施の形態におけるオブジェクト生成部１３２）をさらに有してもよい。
【０１１９】
本実施の形態の第２の態様に係るコード生成方法は、（Ｄ）最適化の対象である最適化対象コードから、分岐条件が成立した場合に最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定し、（Ｅ）特定された第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、ループインデックスの変化値について符号の正負を反転し、第１のループコードの外部のコードから参照される第１の変数への代入命令を分岐条件が成立した場合に第１の変数に代入する命令に変換し、且つ、条件分岐命令を削除する処理を実行する処理を含む。
【０１２０】
なお、上記方法による処理をプロセッサに行わせるためのプログラムを作成することができ、当該プログラムは、例えばフレキシブルディスク、ＣＤ−ＲＯＭ、光磁気ディスク、半導体メモリ、ハードディスク等のコンピュータ読み取り可能な記憶媒体又は記憶装置に格納される。尚、中間的な処理結果はメインメモリ等の記憶装置に一時保管される。
【０１２１】
以上の実施例を含む実施形態に関し、さらに以下の付記を開示する。
【０１２２】
（付記１）
最適化の対象である最適化対象コードから、分岐条件が成立した場合に前記最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定する特定部と、
前記特定部により特定された前記第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、前記ループインデックスの変化値について符号の正負を反転し、前記第１のループのコードの外部のコードから参照される第１の変数への代入命令を前記分岐条件が成立した場合に前記第１の変数に代入する命令に変換し、且つ前記条件分岐命令を削除する処理を実行する最適化部と、
を有するコード生成装置。
【０１２３】
（付記２）
前記第１のループコードは、前記第１のループコードに含まれる条件分岐命令の数が１であるという第１の条件と、異なるループインデックス間でのデータ依存が無いという第２の条件と、前記第１のループコードの種別が所定の種別であるという第３の条件と、前記第１の変数への値の代入についての第４の条件とを満たす、
付記１記載のコード生成装置。
【０１２４】
（付記３）
前記第４の条件は、代入先のアドレスが不変であるという第５の条件と、前記第１の変数への代入が前記条件分岐命令より前に行われるという第６の条件と、ループからの脱出が発生しない場合に前記第１の変数に代入される値を計算できるという第７の条件とを含む、
付記２記載のコード生成装置。
【０１２５】
（付記４）
前記最適化部は、
前記第１のループコードによるループからの脱出が発生しない場合に前記第１の変数に代入される値を前記第１の変数に代入する命令を、前記第１のループコードの直前に追加する、
処理をさらに実行する付記１乃至３のいずれか１つ記載のコード生成装置。
【０１２６】
（付記５）
前記代入命令を変換する処理において、
前記第１の変数への代入命令を一時変数への代入命令に変換し、前記分岐条件が成立した場合に前記第１の変数に前記一時変数の値を代入する命令を追加する、
付記１乃至４のいずれか１つ記載のコード生成装置。
【０１２７】
（付記６）
前記最適化部は、
前記特定部により特定された前記第１のループコードに対して、コピー伝播と不要なコードの削除とを実行する、
処理をさらに実行する付記１乃至５のいずれか１つ記載のコード生成装置。
【０１２８】
（付記７）
前記最適化部の処理によって生成されたコードからオブジェクトコードを生成する生成部
をさらに有する付記１乃至６のいずれか１つ記載のコード生成装置。
【０１２９】
（付記８）
コンピュータが、
最適化の対象である最適化対象コードから、分岐条件が成立した場合に前記最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定し、
特定された前記第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、前記ループインデックスの変化値について符号の正負を反転し、前記第１のループコードの外部のコードから参照される第１の変数への代入命令を前記分岐条件が成立した場合に前記第１の変数に代入する命令に変換し、且つ前記条件分岐命令を削除する処理を実行する、
ことを特徴とするコード生成方法。
【０１３０】
（付記９）
コンピュータに、
最適化の対象である最適化対象コードから、分岐条件が成立した場合に前記最適化対象コードに含まれるループから脱出することを規定する条件分岐命令を含む第１のループコードを特定させ、
特定された前記第１のループコードに対して、ループインデックスの開始値と終了値とを交換し、前記ループインデックスの変化値について符号の正負を反転し、前記第１のループコードの外部のコードから参照される第１の変数への代入命令を前記分岐条件が成立した場合に前記第１の変数に代入する命令に変換し、且つ前記条件分岐命令を削除する処理を実行させる、
ことを特徴とするコード生成プログラム。
【符号の説明】
【０１３１】
１  リニアコード生成装置    １１  ＣＰＵ
１２  メモリ    １３  ＨＤＤ
１００  コンパイラ    １１０  入力処理部
１１１  ソースプログラム入力処理部    １１２  字句解析部
１１３  意味解析部    １１４  第１中間コード出力部
１２０  最適化部    １２１  第１中間コード入力処理部
１２２  プログラム解析部    １２３  プログラム最適化部
１２４  第２中間コード出力部
１３０  出力部    １３１  第２中間コード入力処理部
１３２  オブジェクト生成部    １４０  リンカ
１５０  入出力制御部    １６０  データ格納部
１６１  ソースプログラム    １６２，１６３  中間コード
１６４  オブジェクトファイル    １６５  実行可能プログラム
【図１】
2018067167.tif 000003
【図２】
2018067167.tif 000004
【図３】
2018067167.tif 000005
【図４】
2018067167.tif 000006
【図５】
2018067167.tif 000007
【図６】
2018067167.tif 000008
【図７】
2018067167.tif 000009
【図８】
2018067167.tif 000010
【図９】
2018067167.tif 000011
【図１０】
2018067167.tif 000012
【図１１】
2018067167.tif 000013
【図１２】
2018067167.tif 000014
【図１３】
2018067167.tif 000015
【図１４】
2018067167.tif 000016
【図１５】
2018067167.tif 000017
【図１６】
2018067167.tif 000018
【図１７】
2018067167.tif 000019
【図１８】
2018067167.tif 000020
【図１９】
2018067167.tif 000021
【図２０】
2018067167.tif 000022
【図２１】
2018067167.tif 000023
【図２２】
2018067167.tif 000024
【図２３】
2018067167.tif 000025
【図２４】
2018067167.tif 000026
【図２５】
2018067167.tif 000027
【図２６】
2018067167.tif 000028
【図２７】
2018067167.tif 000029
【図２８】
2018067167.tif 000030
【図２９】
2018067167.tif 000031
【図３０】
2018067167.tif 000032