(57)【要約】【課題】  複数のループを対象とするループ融合を行うコンパイラにおいて、ユーザの意図に従ったループ融合を適用してプログラム実行の高速化を図る。【解決手段】  ループ融合の対象とするループとネストレベルをプログラム中の指示文（４０１）で指定する。ループ融合指示文解析（１０２）で指示文情報をループ表（２１０）に登録し、ループ融合（１０３）では、登録情報に従って変換を行う。【選択図】  図１
2005222262.tif 000002
【特許請求の範囲】
【請求項１】
プログラム中の複数のループネストを対象にした、ループ変換方法であって、
メモリ上に読み込まれた対象プログラム内のループ融合対象とするループネスト範囲を指示する指示文をＣＰＵにより解釈するステップと、
上記指示されたループネスト範囲において、ループ融合対象とするネストレベルを指示する指示文をＣＰＵにより解釈するステップと、
上記指示されたループ範囲を対象にＣＰＵの処理によりループ融合を行うステップとを有することを特徴とするループ融合方法。
【請求項２】
請求項1のループ融合方法であって、
上記のループネスト範囲を指示する指示文と、上記ネストレベルを指示する指示文を１つの指示文で記述することを特徴とするループ融合方法。
【請求項３】
請求項1のループ融合方法であって、
ループ融合を行うネストレベルを指示する指示文を解釈するステップと、
上記指示されたネストレベルよりも浅いネストレベルまでのループ融合を行うステップとを有することを特徴とするループ融合方法。
【請求項４】
プログラムコードの生成方法であって、
メモリ上に読み込まれた対象プログラム内のループ融合対象とするループネスト範囲を指示する融合指示文をＣＰＵにより解釈するステップと、
上記指示されたループネスト範囲において、ループ融合対象とするネストレベルを指示する融合レベル指示文をＣＰＵにより解釈するステップと、
上記指示されたループ範囲を対象にＣＰＵの処理によりループ融合を行うステップと、
ループ融合された対象プログラムに基づいて、プログラムコードを生成するステップと、
を有することを特徴とするプログラムコードの生成方法。
【請求項５】
請求項４に記載のプログラムコードの生成方法であって、
上記融合指示と、上記融合レベル指示を１つの指示文で記述することを特徴とするプログラムコードの生成方法。
【請求項６】
請求項４に記載のプログラムコードの生成方法であって、
前記融合指示の有無と前記融合レベル指示のレベルに関する情報をループ毎に有するループ表をメモリ上に読み込むステップと、
前記ループ融合処理後に、前記ループ表のループ融合のされたループのデータを更新するステップと、
を有することを特徴とするプログラムコードの生成方法。
【請求項７】
プログラムコードを生成するコンパイラプログラムであって、
メモリ上に読み込まれた対象プログラム内のループ融合対象とするループネスト範囲を指示する融合指示文をＣＰＵにより解釈するステップと、
上記指示されたループネスト範囲において、ループ融合対象とするネストレベルを指示する融合レベル指示文をＣＰＵにより解釈するステップと、
上記指示されたループ範囲を対象にＣＰＵの処理によりループ融合を行うステップと、
ループ融合された対象プログラムに基づいて、プログラムコードを生成するステップと、
を実行可能とすることを特徴とするコンパイラプログラム。
【請求項８】
請求項７に記載のコンパイラプログラムであって、
上記融合指示と、上記融合レベル指示を１つの指示文で記述することを特徴とするコンパイラプログラム。
【請求項９】
請求項７に記載のコンパイラプログラムであって、
前記融合指示の有無と前記融合レベル指示のレベルに関する情報をループ毎に有するループ表をメモリ上に読み込むステップと、
前記ループ融合処理後に、前記ループ表のループ融合のされたループのデータを更新するステップと、
を実行可能とすることを特徴とするコンパイラプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、計算機の利用技術において、オブジェクトプログラムの実行時間を削減するコンパイル方法に関する。特に、ループを含むプログラムに対する最適化指示方法に関する。
【背景技術】
【０００２】
ループ融合とは複数のループを合わせて1つのループにまとめるループの変換手法である。このような変換はどのようなループに対しても適用できるわけではない。変換後のプログラムが変換前のプログラムと同じ意味を持ち、正しく実行されるためには、融合対象となるループが同じ形であることや、ループ間の依存関係に関する条件などの制約がある。これらの条件については、例えば非特許文献1に記載されている。
【０００３】
従来ループ融合においては、非特許文献2に記載されているように、ループをまとめることによるループオーバーヘッドの削減や、同じ配列要素参照を持つループの融合によるロード・ストアの削減を目的として行われてきた。このループオーバヘッドの削減や、ロード・ストアの削減について、図１０を用いて説明する。
【０００４】
図１０の(a)はループ融合前のソースプログラムであり、図１０の(b)はループ融合後のソースプログラムである。ループオーバヘッドはループ繰り返しにおける終了判定にほとんどの時間が費やされるため、ループの数が多くなればオーバーヘッドも増加し、ループの数が少なくなればオーバーヘッドが削減されることになる。ここで、図１０の(a)(b)のソースプログラムを見てみると、ループ融合前では4つのループ(L1001,L1002,L1003, L1004)があったが、ループ融合後は2つのループ(L1005,L1006)になっており、ループの数が少なくなっているため、ループ融合によってループオーバヘッドが削減されることが分かる。
【０００５】
次にロード・ストアの削減について説明する。ループ融合前の図１０の(a)のソースプログラムでは、ループL1002とループL1004のループ本体で配列bに対する参照が行われているため、ループL1002とループL1004のそれぞれのループ本体で配列bに対するロード命令が必要になる。ループ融合後の図１０の(b)のソースプログラムでは、配列bに対する参照はループL1006だけのため、ループL1006内の1010の参照でメモリからロードした値をレジスタに保持しておけば1011の参照ではそのレジスタの値を参照すれば良いため、ロード命令が削減されることが分かる。配列cについても同様にロード命令が削減される。
【０００６】
【非特許文献１】H.Zima: Supercompilers for Parallel and Vector Computers. ACM Press, 1990, pp.275-278
【０００７】
【非特許文献２】M.J.Wolfe: Optimizing Supercompilers for Supercomputers. MIT Press, 1989, pp.89-92
【発明の開示】
【発明が解決しようとする課題】
【０００８】
従来の技術によるループ融合処理の場合、ループ融合の対象とするループ間で参照されている配列要素に対し、ループ融合することのできない依存関係がある場合は、ループ融合が適用されなかった。つまり、従来技術ではループのすべてのネストレベルにおいて融合可能であると判定した場合のみループ融合を適用していた。このループ融合を完全融合と呼ぶ。例えば、図１１の(a)のソースプログラムは、ユーザによるループ融合指示1101が指定されている場合でも、ループ融合されない例を示している。ループ融合されない理由は、ループL1112の文S1102の配列aの定義と、ループL1114の文S1103の配列aの使用がループ間に跨る依存を持ちループ融合の制約条件を満たさないためである。したがってこの例の場合、ユーザによるループ融合指示があるにも係わらず、出力されるコードのソースイメージは図１１の(b)のように、ループ変換が何も行われていないコードとなる。
【０００９】
しかし、対象ループのすべてのネストレベルに対して融合ができない場合でも、一部のループに対するループ融合によって性能向上を図れる場合がある。例えば、外側ループを融合した場合の効果としては、データ局所性の向上が挙げられる。ここで、データ局所性の向上について図１０を用いて説明する。図１０の(a)のソースプログラムにおいて、配列の要素サイズを8バイトとすると、ループL1001の実行で各配列は8*N*Nバイトの値を参照し、配列a,b,cの合計参照サイズは24*N*Nバイトとなる。これがキャッシュサイズより十分大きい場合には、ループL1001の終了時にはb(1,1)のようにループの最初の方で参照されたデータはキャッシュから追い出されており、ループL1003で再度メモリからキャッシュ上へロードすることになる。これに対し、外側ループだけをループ融合した図１０の(c)では、ループL1008の実行で各配列8*Nバイト、合計で24*Nバイト分しか参照しないため、これがキャッシュサイズ以下ならば、ループL1009において配列bおよびcのデータをキャッシュ上で再利用することができ、性能向上が図れる。
【００１０】
また、従来技術では対象ループに対しループ融合が可能である場合、ループ融合が適用され1つのループにまとめられていたが、まとめられたループ内の文の数がある程度大きくなると、ループ内で参照される変数や配列要素などを格納するレジスタが不足してしまうという問題がある。例えば、図１２の(a)のソースプログラムでは、ループL1210内で変数b1,b2,b3,b4(1201)の値がループ不変なので、これらの値はループL1210の直前にメモリからレジスタに値が転送され、ループ内ではそのレジスタを参照するコードが生成される。同様にループL1211でも変数e1,e2,e3,e4(1202)はレジスタを参照するコードになる。ループ融合後の図１２の(b)のループL1212でもループ不変である変数b1,b2,b3,b4,e1,e2,e3, e4(1203)はレジスタを参照するコードになるが、その数はループ融合前が各ループ(L1210,L1211)で４個であったものが、ループL1212では８個に増えることになる。そのため、ループ不変である変数の数が利用可能なレジスタの数を超えてしまう場合は、ループ不変の値をレジスタに転送することができないため、ループ内で毎回ロード命令が必要になる。つまり、レジスタの数は有限個であるため、ループ融合後に必要なレジスタ数が、プロセッサの持つレジスタの数を超えてしまった場合は、その値をレジスタ以外であるメモリなどの場所に保持しなければならない。しかし、メモリなどの場所に値を保存する場合、その値の読み書きはレジスタからの読み書きにくらべ十数倍から数百倍のコストがかかる。そのため、ループ融合によってループオーバヘッドなどの削減効果よりも、レジスタ不足による実行時間の増加割合が大きい場合は、必ずしもループ融合によって実行時間が削減できると言うわけではない。
【００１１】
本発明の目的は、完全融合できないループに対して部分的にループ融合するのと、ループ融合による最内側ループの肥大化を防ぐために、ループ融合のネストレベルを指示文によりプログラム中に指定する手段を設け、ユーザの意図に従ったループ融合方法を提供することである。
【課題を解決するための手段】
【００１２】
本発明の目的は、プログラム中に指示されたループ融合に関する指示文を解釈し情報を登録するループ融合指示解析ステップ（１０２）と、指示文の解析結果に基づきループ融合を実施するループ融合ステップ（１０３）とにより達成される。
【発明の効果】
【００１３】
本発明によれば、ループ融合のネストレベルをユーザが指示する手段を設けることにより、ユーザの意図に従ったループ融合を適用することができる。本発明のループ融合方法により、外側ループ融合によるデータ局所性の向上と、ループ融合による最内側ループの肥大化を防ぐことが可能になるという効果が得られ、プログラムの実行性能向上が図れる。
【発明を実施するための最良の形態】
【００１４】
ソースプログラム中のループに対し、ユーザの意図に従ったループ融合を提供するという目的を、ループ融合のネストレベルを指示できる指示文を設けることにより実現した。
【実施例１】
【００１５】
以下、図面を用いて本発明の実施の形態について説明する。
【００１６】
図２は、本発明によるコンパイラが稼動する計算機システムの構成図である。この計算機システムは、ＣＰＵ２０１、ディスプレイ装置２０２、キーボード２０３、主記憶装置２０４、および外部記憶装置２０５より構成されている。キーボード２０３により、ユーザからのコンパイラ起動命令を受け付ける。コンパイラ終了メッセージやエラーメッセージは、ディスプレイ装置２０２に表示される。外部記憶装置２０５には、ソースプログラム２０６とオブジェクトプログラム２０７が格納される。主記憶装置２０４には、コンパイラ２０８、コンパイル過程で必要となる中間コード２０９とループ表２１０が格納される。コンパイル処理はＣＰＵ２０１がコンパイラプログラム２０８を実行することにより行われる。
【００１７】
図３に、図２のシステムで稼動するコンパイラ２０８の処理手順を示す。
【００１８】
コンパイラの処理は、構文解析３０１、ループ融合最適化３０２、レジスタ割り付け３０３、コード生成３０４の順で行う。構文解析３０１では、ソースプログラム２０６を入力として構文解析を行い、中間コード２０９を出力する。ループ融合最適化３０２は、後で詳細に説明する。レジスタ割り付け３０３では、中間コード２０９の各ノードに対しレジスタ割り付けを行う。コード生成３０４では、中間コード２０９をオブジェクトプログラム２０７に変換し、出力する。図３に示す一連のコンパイル処理は、コンパイラプログラム２０８をＣＰＵ２０１で実行することで実現される。
【００１９】
図１に、ループ融合最適化３０２の処理手順を示す。ステップ１０１のループ解析により、プログラムに含まれるループの集合を求め、ループ表２１０に記録する。ループ解析の方法は非特許文献１の６７頁に記載されている。ステップ１０２でループ融合指示の解析を行い、ループ表２１０に追記する。ステップ１０３では、ループ表２１０の情報に基づき、ループ融合処理を行う。
【００２０】
図４(a)にループ融合指示文を付加したソースプログラムの例を示す。本プログラム例はFortran言語で記述してある。指示文４０１'*option fuse(1)'は、ループ融合対象とするループの直前に指定し、指定ループとその後続ループを融合対象とする。また、括弧内のパラメタは、外側の何重ループを融合対象とするかを指定するもので、本例では最外側一重ループの融合を指定している。
【００２１】
図５に、中間コード２０９の一例を示す。本中間コードは、図４(a)のソースプログラムに対応している。中間コードは基本ブロックＢ０〜Ｂ１４をエッジで結んだグラフで表現される。このようなグラフは制御フローグラフと呼ばれている。基本ブロックとは、連続した文の列で、実行が先頭から始まり、途中へ飛び込んだり途中から飛び出すことのないものである。エッジは基本ブロック間の遷移を表している。なお、ループ融合最適化の処理手順の説明の簡略化のために、ループ融合の対象ループとネストレベルを示す指示文を含む基本ブロック内には他の文が含まれないよう、前後の文との間で基本ブロックを分割した中間コードを生成するものとする。
【００２２】
図６にループ表２１０の一例を示す。ループ表は、ループ番号６０１、後続ループ番号６０２、子ループ番号６０３、ループプリヘッダ６０４、制御変数６０５、増分値６０６、初期値６０７、上限値６０８、処理済みフラグ６０９、融合指示文６１０、融合レベル指示６１１などの欄からなる。ループ番号はループを識別するための番号である。後続ループ番号は、自ループの直後にあるループのループ番号である。子ループ番号は、自ループの内側にあるループのループ番号である。ループプリヘッダは、ループ本体の直前に配置されている基本ブロックのことで、ループ表には基本ブロック番号を登録する。制御変数は、ループ制御変数を登録する。増分値、初期値、上限値はそれぞれ制御変数の増分値、初期値、上限値を登録する。処理済みフラグは、ループ融合処理が終了したかどうかを示す領域である。融合指示文は、そのループにループ融合指示文が指定されているかどうかを示す領域である。融合レベル指示は、ループ融合指示文が指定されている場合に、指示文で指定された融合レベルを登録する。ループ融合指示文が指定されてないループについてはその欄に何も記入しない。図６(a)のループ表は図５の中間コードに対応している。
【００２３】
ループ融合指示解析１０２の詳細な処理手順を図７に示す。
【００２４】
ステップ７０１では未処理の基本ブロックがあるかを調べ、ステップ７０２で次の処理対象基本ブロックを取り出す。
【００２５】
ステップ７０３で基本ブロックにループ融合を指示する指示文(fuse指示文)があるかどうかを調べる。なければステップ７０１に戻り、次の基本ブロックの処理へ進む。fuse指示文があればステップ７０４へ進む。
【００２６】
ステップ７０４では、fuse指示文の括弧内に指定されたループ融合レベルを取り出す。
【００２７】
ステップ７０５では、指示文を含む基本ブロックの次の基本ブロックがループプリヘッダとして登録されているループをループ表２１０から探す。
【００２８】
ステップ７０６では、ステップ７０５で探し出したループの融合指示文欄６１０に「あり」を、融合レベル指示欄６１１にステップ７０４で取り出した融合レベルを登録する。登録後ステップ７０１へ戻り次の基本ブロックの処理へ進む。
【００２９】
次に、ループ融合１０３の詳細な処理手順を図８、図９に示す。
【００３０】
ステップ８０１では、ループ表に融合指示文付きの未処理のエントリがあるかを調べる。未処理かどうかはループ表２１０の処理済みフラグ６０９が設定されているかどうかを調べれば分かる。
【００３１】
ステップ８０２、ステップ８０３では、ループ融合を行うネストレベルの設定を行う。ステップ８０２では、ループ融合を行う最大のネストレベルを保持する変数max_nest_levelに対象ループのネストレベルを設定する。対象ループのネストレベルはループ表２１０を利用して取得する。ネストレベルは初期値を１として、対象ループに子ループ番号６０３が設定されている場合にネストレベルに１を加える。そして、その子ループ番号に対応するループ情報からさらに子ループを辿るというように順じ子ループを辿り、子ループがなくなるまで辿ったときのネストレベルを対象ループのネストレベルとする。ステップ８０３では、融合レベル指示６１１と、その時点でのmax_nest_level（対象ループのネストレベル）のうち、よりネストレベル数が少ないものをmax_nest_levelに設定する。
【００３２】
ステップ８０４では、現在どのネストレベルの処理を行っているのかを示すnest_level変数の初期化を行う。本実施例では、初期値として１を設定する。
【００３３】
ステップ８０５では、対象ループのループ融合処理を行う。
【００３４】
次にループ融合処理８０５の詳細な処理手順を図９に示す。
【００３５】
ステップ９０１では、Ｌ１に処理対象ループを設定する。
【００３６】
ステップ９０２では、現在処理中のネストレベル(nest_level)が、最大ネストレベル(max_nest_level)以下かどうかを調べ、条件を満たす場合はステップ９０３に進み、大きい場合はステップ９１０に進みＬ１を処理済みとした後でループ融合処理を終了する。
【００３７】
ステップ９０３〜９０６では、ループ融合処理を行う。ステップ９０３では、ループ表２１０の後続ループ番号６０２を参照して、Ｌ１の後続ループがあるかどうかを調べる。後続ループがある場合はステップ９０４に進み、後続ループをＬ２とする。後続ループがない場合は、ステップ９１０に進む。ステップ９０５では、ループＬ１とＬ２の組がループ融合の制約条件を満たすかどうかを判定する。本ステップでは主として、２つのループの制御変数とその初期値、上限値、増分値が同一かどうかや、ループ間の依存関係を調べる。これらの制約条件については非特許文献１の２７５頁から２７８頁などに記載がある。条件を満たす場合はステップ９０６に進み、条件を満たさない場合はステップ９１０に進む。ステップ９０６では、ループＬ１とＬ２の融合処理を行う。本ステップでは中間コードの変換処理の他、ループ表の更新と、処理済みフラグの設定を行う。ループ表の更新は、新たなループをループ表２１０に登録し、ループプリヘッダ、制御変数、増分値、初期値、上限値を、ループＬ１のループ情報からコピーする。子ループ番号については、ループＬ１とループＬ２の子ループ番号を登録する。後続ループについては、ループＬ２の後続ループを登録する。さらに、Ｌ１ループに子ループが指定されている場合は、子ループの後続ループにＬ２の子ループを登録する。そして、新たに登録したループ情報の処理済みフラグ６０９をセットし、ループＬ１とＬ２に対応する情報をループ表２１０から削除する。
【００３８】
ステップ９０７では、ループ融合後のループに子ループかあるかどうかを調べる。子ループがあるかどうかは、ループ表２１０の子ループ番号６０３を調べれば分かる。子ループがある場合は、ステップ９０８に進み、子ループがない場合はループ融合処理を終了する。
【００３９】
ステップ９０８では、子ループのネストレベルの処理を行うために、ネストレベルに１を加える。
【００４０】
ステップ９０９では、子ループを対象にしたループ融合処理を行うために、図９のループ融合処理を呼び出す。子ループの融合処理が終了したら自ループの融合処理も終了する。
【００４１】
図８、図９に示したループ融合処理を行うことで、各ネストレベルごとにループ融合を適用するようになり、全ネストレベルに対して融合できない場合でも、一部のネストレベルに対しループ融合が適用され、データの局所性を向上させることができる。また、ループ融合により最内側ループ内の文の数が多くなる場合に、ユーザの指示文指定により最内側ループの融合を抑止できるため、レジスタ不足による性能劣化を避けることが可能になる。
【００４２】
図５の中間コードを例に、ループ融合指示解析１０２およびループ融合１０３の処理を説明する。
【００４３】
ステップ７０１，７０２で基本ブロックを順に取り出し、基本ブロックＢ１の処理において、ステップ７０３でfuse指示文ありと判定する。ステップ７０４では、fuse指示文の括弧内に指定されている融合レベルを取り出す。この例では、指示された融合レベルが１であり、ループ融合の対象となるループが２重ループであるため、外側ループだけループ融合するという指示をユーザが与えたことになる。ステップ７０５で、次の基本ブロックであるＢ２がループヘッダとして登録されているループをループ表２１０から探すとループ番号１のループであることが分かるので、ステップ７０６でループ表の融合指示文６１０欄に「あり」を、融合レベル指示６１１欄にステップ７０４で取り出した融合レベル１を設定する。図５の中間コードにはＢ２以外にfuse指示文が設定された基本ブロックがないため、これでループ融合指示解析処理を終了する。
【００４４】
次に、ループ融合処理を行う。ステップ８０１で融合指示文付きで未処理であるループ番号１のループが処理対象として選ばれる。ステップ８０２でループ番号１のネストレベルを求める。ループ番号１には子ループとしてループ番号２のループがあり、ループ番号２のループには子ループがないので、ネストレベルは２となる。ステップ８０３で指定融合レベルである１と、対象ループのネストレベルである２のうち、少ない数である１をmax_nest_levelに設定する。ステップ８０４で現在の処理ネストレベルを１にして、融合処理図９に進む。
【００４５】
ステップ９０１で処理対象であるループ番号１のループをＬ１として設定する。ステップ９０２でネストレベルのチェックを行うが、nest_level,max_nest_level共に１であるため、ステップ９０３に進む。ステップ９０３ではＬ１の後続ループを調べるが、Ｌ１であるループ番号１のループはループ表２１０より、後続ループとしてループ番号３のループを持っているため、ステップ９０４に進みループ番号３のループをＬ２として設定する。ステップ９０５では、Ｌ１（ループ番号１）とＬ２（ループ番号３）のループが融合可能かどうかを判定する。それぞれのループは、ループ制御変数、初期値、上限値、増分値が同じで、ループ間に跨る依存もないためステップ９０５でループ融合可能と判断され、ステップ９０６でループ融合が行われる。この融合処理でループ表２１０にループ番号５のループが登録される。さらに、ループ番号２の後続ループは、融合前のループ番号３の子ループである、ループ番号４のループを設定し、ステップ９０７に進む。ステップ９０７では、ループ番号５の子ループがないためループ融合処理は以上で終了する。ループ融合最適化後のループ表を図６(b)に示す。また、このループ融合後のコードをソースイメージで示したものが図４(b)になる。
【産業上の利用可能性】
【００４６】
ソースプログラムをオブジェクトコードに変換するコンパイラにおいて、ループに着目した最適化を行う用途に適用できる。
【図面の簡単な説明】
【００４７】
【図１】本発明によるループ融合最適化の処理手順を示す図である。
【図２】本発明に係る最適化方法を実施するコンパイラが稼動する計算機システムの構成図である。
【図３】本発明によるコンパイラの処理手順を示す。
【図４】ループ融合指示文を含むソースプログラムの例を示す。
【図５】中間コードの一例を示す。
【図６】ループ表の例である。
【図７】本発明によるループ融合ネストレベルを登録する処理手順を示す。
【図８】本発明によるループ融合の処理手順を示す。
【図９】本発明によるループ融合の処理手順を示す。
【図１０】ループ融合変換例を示す。
【図１１】従来技術のループ融合変換例を示す。
【図１２】従来技術のループ融合変換例を示す。
【符号の説明】
【００４８】
201・・・ＣＰＵ、202・・・ディスプレイ装置、203・・・キーボード、204・・・主記憶装置、205・・・外部記憶装置、206・・・ソースプログラム、207・・・オブジェクトプログラム、208・・・コンパイラ、209・・・中間コード、210・・・ループ表
【図１】
2005222262.tif 000003
【図２】
2005222262.tif 000004
【図３】
2005222262.tif 000005
【図４】
2005222262.tif 000006
【図５】
2005222262.tif 000007
【図６】
2005222262.tif 000008
【図７】
2005222262.tif 000009
【図８】
2005222262.tif 000010
【図９】
2005222262.tif 000011
【図１０】
2005222262.tif 000012
【図１１】
2005222262.tif 000013
【図１２】
2005222262.tif 000014