(57)【特許請求の範囲】
【請求項１】
プログラミング言語で記述されたプログラムのソース・コードを機械語に変換し、プログラムの最適化を行うコンパイラにおいて、
処理対象であるプログラムから命令のＤＡＧを構築し、解析するＤＡＧ解析部と、
前記ＤＡＧ解析部による解析結果に基づいて、前記命令が使用する変数間における干渉の有無を示す干渉グラフを構築する干渉グラフ構築部と、
前記干渉グラフ構築部により構築された干渉グラフに基づいて、前記命令に対するレジスタ割付を行うグラフ識別部とを備え、
前記干渉グラフ構築部は、所定の複数の命令が並列に実行されないと前記プログラム全体の実行時間が延びてしまう場合に、当該複数の命令が使用する変数の干渉を反映させて干渉グラフを構築すること
を特徴とするコンパイラ。
【請求項２】
前記干渉グラフ構築部は、前記ＤＡＧのノードに対して、前記プログラムの実行時間が最小になるように位相整列順序を決定し、当該位相整列順序における各命令の変数の生存区間が重なる場合に、当該変数間の干渉を前記干渉グラフに反映させる、請求項１に記載のコンパイラ。
【請求項３】
前記干渉グラフ構築部は、前記プログラムにおいて並列に実行される可能性のある複数の命令に関して、当該複数の命令を並列に実行しない場合であっても当該プログラム全体の実行時間への影響がない場合、当該複数の命令が定義する変数が干渉しない干渉グラフを構築する、請求項１に記載のコンパイラ。
【請求項４】
前記ＤＡＧ解析部は、
前記ＤＡＧを構成するノードである命令を深さ優先で探索し、
探索結果のリバースポストオーダーを生成し、
前記干渉グラフ構築部は、
前記ＤＡＧ解析部にて生成された前記リバースポストオーダーに基づいて命令を順次取り出し、
取り出した前記命令で使用されている変数と他の変数との間の干渉を決定し、決定結果を前記干渉グラフに反映させることにより、前記干渉グラフを段階的に構築する、
請求項１に記載のコンパイラ。
【請求項５】
前記ＤＡＧ解析部は、
前記ＤＡＧを構成するノードである各命令について、実行開始時刻を変更できる自由度と、最早実行開始時刻とを算出し、
前記干渉グラフ構築部は、
前記ＤＡＧ解析部にて算出された各命令の自由度及び最早実行開始時刻とに基づいて、各命令の実行開始時刻を決定し、
決定された各命令の前記実行開始時刻に基づいて、各命令で使用されている変数の間の干渉を決定し、決定結果を前記干渉グラフに反映させることにより、前記干渉グラフを構築する、
請求項１に記載のコンパイラ。
【請求項６】
前記グラフ識別部は、前記ＤＡＧ解析部にて構築されたＤＡＧにおける同じパス上で定義される変数に対して同一のレジスタを割り付ける、請求項１に記載のコンパイラ。
【請求項７】
入力されたプログラムのソース・コードをコンパイルするコンパイラを備えたコンピュータ装置において、
前記コンパイラは、
処理対象であるプログラムから命令のＤＡＧを構築し、解析するＤＡＧ解析部と、
前記ＤＡＧ解析部による解析結果に基づいて、前記ＤＡＧのノードに対して前記プログラムの実行時間が最小になるように位相整列順序を決定し、当該位相整列順序において生存区間が重なる変数間の干渉を反映させた干渉グラフを構築する干渉グラフ構築部と、
前記干渉グラフ構築部により構築された干渉グラフに基づいて、前記命令に対するレジスタ割付を行うレジスタ割付実行部とを備えたこと
を特徴とするコンピュータ装置。
【請求項８】
前記レジスタ割付実行部によるレジスタ割付の結果を前記干渉グラフに記述し、当該干渉グラフを出力する出力手段をさらに備えた、請求項７に記載のコンピュータ装置。
【請求項９】
プログラミングの処理効率を向上させるための最適化として、コンピュータが処理対象のプログラムの各命令に対し、グラフカラーリングによるレジスタ割付を行うレジスタ割付方法において、
前記コンピュータのＤＡＧ解析部が、処理対象であるプログラムから命令のＤＡＧを構築し、解析するステップと、
前記コンピュータの干渉グラフ構築部が、前記ＤＡＧにおける並列化できない最も長い命令列を基準とし、前記解析の結果に基づいて、所定の複数の命令が並列に実行されないと当該命令列が延長されてしまう場合に、当該複数の命令が使用する変数の干渉を反映させて干渉グラフを構築するステップと、
前記コンピュータのレジスタ割付実行部が、構築された前記干渉グラフに基づいて、前記命令に対するレジスタ割付を行うステップと
を含むことを特徴とするレジスタ割付方法。
【請求項１０】
前記ＤＡＧを構築し解析するステップは、
前記コンピュータが、前記ＤＡＧを構成するノードである命令を深さ優先で探索するステップと、
前記コンピュータが、探索結果のリバースポストオーダーを生成するステップとを含み、
前記干渉グラフを構築するステップは、
前記コンピュータが、生成された前記リバースポストオーダーに基づいて前記ＤＡＧから命令を順次取り出し、取り出した前記命令で使用されている変数と他の変数との間の干渉を決定するステップと、
前記コンピュータが、決定された変数間の干渉を前記干渉グラフに反映させることにより、前記干渉グラフを段階的に構築するステップとを含む、
請求項９に記載のレジスタ割付方法。
【請求項１１】
前記ＤＡＧを構築し解析するステップでは、
前記コンピュータが、前記ＤＡＧを構成するノードである各命令について、実行開始時刻を変更できる自由度と、最早実行開始時刻とを算出し、
前記干渉グラフを構築するステップでは、
前記コンピュータが、前記リバースポストオーダーに基づいて前記ＤＡＧから取り出した命令に関して、算出された各命令の前記自由度及び前記最早実行開始時刻とに基づいて、各命令の実行開始時刻を決定し、決定された各命令の前記実行開始時刻に基づいて、各命令で使用されている変数の間の干渉を決定する、
請求項１０に記載のレジスタ割付方法。
【請求項１２】
前記各命令の実行開始時刻を決定するステップでは、前記コンピュータが、前記命令の前記自由度及び前記最早実行開始時刻に基づき、プログラム全体の実行時間を延ばさない範囲で前記命令の実行開始時刻を遅らせた場合に、当該命令で使用する関数における他の関数との干渉の数が減るならば、当該干渉の数が最も少なくなる時刻を当該命令の実行開始時刻に決定する、請求項１１に記載のレジスタ割付方法。
【請求項１３】
前記レジスタ割付を行うステップでは、前記コンピュータが、前記ＤＡＧの同じパス上で定義される変数に対して同一のレジスタを割り付ける、請求項９に記載のレジスタ割付方法。
【請求項１４】
コンピュータに実行させるプログラムを当該コンピュータの入力手段が読取可能に記憶した記憶媒体において、
処理対象であるプログラムから命令のＤＡＧを構築し、解析する処理と、
前記ＤＡＧにおける並列化できない最も長い命令列を基準とし、前記解析の結果に基づいて、所定の複数の命令が並列に実行されないと当該命令列が延長されてしまう場合に、当該複数の命令が使用する変数の干渉を反映させて干渉グラフを構築する処理と、
構築された前記干渉グラフに基づいて、前記命令に対するレジスタ割付を行う処理と
を前記コンピュータに実行させるプログラムを記憶した記憶媒体。
【請求項１５】
コンピュータに、
処理対象であるプログラムから命令のＤＡＧを構築し、解析する処理と、前記ＤＡＧにおける並列化できない最も長い命令列を基準とし、前記解析の結果に基づいて、所定の複数の命令が並列に実行されないと当該命令列が延長されてしまう場合に、当該複数の命令が使用する変数の干渉を反映させて干渉グラフを構築する処理と、構築された前記干渉グラフに基づいて、前記命令に対するレジスタ割付を行う処理とを実行させるプログラムを記憶する記憶手段と、
前記記憶手段から前記プログラムを読み出して当該プログラムを送信する送信手段と
を備えたプログラム伝送装置。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、コンピュータの命令レベル並列アーキテクチャを対象としたレジスタ割付に関する。
【０００２】
【従来の技術】
通常、プログラミング言語で記述されたプログラムのソース・コードをコンパイルする際、当該プログラムの最適化を行っており、その最適化の手法の一つとして、当該プログラムにおける命令を実行するレジスタの割付を行っている。このレジスタ割付の手法として、各レジスタに異なる色を割り当て、プログラムの各命令を色分けするイメージでレジスタ割付を実行するカラーリングと呼ばれる手法がある。
【０００３】
ところで、今日、コンピュータにおけるハードウェアの高性能化に伴い、マルチプログラミングによる並列処理が一般的となっている。そして、上述したコンパイル時のレジスタ割付においても、プログラムの並列性を反映したレジスタ割付の手法が提案されている。この種の命令レベル並列アーキテクチャを対象としたレジスタ割付では、逆依存の生成による命令間の並列性の低下を抑えることが重要である。
従来のこの種のレジスタ割付手法として、S. S. Pinterらによる並列化干渉グラフを用いたカラーリングの手法がある。本手法は、下記の文献に詳細に記載されている。
文献  S. S. Pinter, Register allocation with Instruction Scheduling: A New Approach, SIGPLAN '93 Conference on PLDI
【０００４】
この並列化干渉グラフを用いたグラフカラーリングの手法では、並列に実行される可能性のある命令で用いられる変数間に干渉があるものとみなし、それらの干渉のある変数に異なったレジスタが割り付けられるようにする。この方法によって、並列に実行される命令間の逆依存が除去され、コードの並列性が保証されることとなる。
【０００５】
【発明が解決しようとする課題】
上述したように、プログラムの並列性を反映したレジスタ割付の手法として、並列化干渉グラフを用いたグラフカラーリングが存在する。この従来の手法は、並列に実行される可能性のある命令が異なるレジスタを使用するように、すなわち、並列に実行される可能性のある命令で参照される変数どうしに干渉があるものとみなして、グラフカラーリングを行っていた。
【０００６】
しかし、この方法では、並列化干渉グラフを用いたグラフカラーリングでは、処理対象であるプログラムにおける命令間の潜在的な並列実行可能性がくまなく考慮されてしまうため、変数間の干渉が莫大になってしまう。そして、変数間の干渉が増大すると、
１．コンパイルに要する時間が増加すること
２．干渉度が実レジスタの数を超えてしまい、スピルコードが必要となること
という問題が発生する。
【０００７】
グラフカラーリングにおいて、干渉度が実レジスタの数を超えた場合の対処法としては、スピルコードを生成した後にもう一度干渉グラフを作成してカラーリングをやり直す方法が一般的である。したがって、干渉度が実レジスタの数を超える場合におけるカラーリングの処理コストは非常に大きい。また、プログラムの並列性を考慮したスピルデシジョンは困難である。
【０００８】
図１９は、上記従来のグラフカラーリングの手法により構築された干渉グラフの例を示す図である。図１９（Ａ）に示すＤＡＧ（Directed Acyclic Graph）に基づいて、図１９（Ｂ）の干渉グラフが構築されている。図１９（Ｂ）に示すように、干渉グラフは、変数間の干渉が膨大となっており、効率的なレジスタ割付の処理が困難となっている。
【０００９】
そこで、本発明は、グラフカラーリングにおいて、命令の並列実行可能性を保証したまま、変数間の干渉数を減少させることを目的とする。
また、これにより、命令間の並列性を保証したグラフカラーリングにおいて、コンパイルに要する時間の増大や無駄なスピルコードの生成を回避することを目的とする。
【００１０】
【課題を解決するための手段】
かかる目的のもと、本発明は、プログラミング言語で記述されたプログラムのソース・コードを機械語に変換し、プログラムの最適化を行うコンパイラにおいて、処理対象であるプログラムから命令のＤＡＧを構築し、解析するＤＡＧ解析部と、この解析結果に基づいて、この命令が使用する変数間における干渉の有無を示す干渉グラフを構築する干渉グラフ構築部と、構築された干渉グラフに基づいて、この命令に対するレジスタ割付を行うグラフ識別部とを備え、この干渉グラフ構築部は、所定の複数の命令が並列に実行されないとこのプログラム全体の実行時間が延びてしまう場合に、この複数の命令が使用する変数を干渉するとみなして干渉グラフを構築する。
これにより、プログラムの並列性を保証する最低限の変数の干渉を干渉グラフに反映させることができる。
【００１１】
ここで、この干渉グラフ構築部は、ＤＡＧのノードに対して、プログラムの実行時間が最小になるように位相整列順序を決定し、この位相整列順序における各命令の変数の生存区間が重なる場合に、この変数間の干渉を干渉グラフに反映させる。
【００１２】
あるいは、この干渉グラフ構築部は、プログラムにおいて並列に実行される可能性のある複数の命令に関して、この複数の命令を並列に実行しない場合であってもこのプログラム全体の実行時間への影響がない場合、この複数の命令が定義する変数は干渉しないものとして前記干渉グラフに反映させる。
【００１３】
また、このコンパイラにおいて、ＤＡＧ解析部は、ＤＡＧのノードである命令を深さ優先で探索し、探索結果のリバースポストオーダーを生成し、干渉グラフ構築部は、このリバースポストオーダーに基づいて命令を順次取り出し、取り出した命令で使用されている変数と他の変数との間の干渉を決定し、決定結果を干渉グラフに反映させることにより、干渉グラフを段階的に構築する構成とすることができる。
【００１４】
さらに、このコンパイラにおいて、ＤＡＧ解析部は、ＤＡＧを構成するノードである各命令について、実行開始時刻を変更できる自由度と、最早実行開始時刻とを算出し、干渉グラフ構築部は、各命令の自由度及び最早実行開始時刻とに基づいて、各命令の実行開始時刻を決定し、この実行開始時刻に基づいて、各命令で使用されている変数の間の干渉を決定し、決定結果を前記干渉グラフに反映させることにより、干渉グラフを構築する構成とすることができる。
【００１５】
さらにまた、このコンパイラにおけるグラフ識別部は、ＤＡＧ解析部にて構築されたＤＡＧにおける同じパス上で定義される変数に対して同一のレジスタを割り付ける。
【００１６】
また、本発明は、入力されたプログラムのソース・コードをコンパイルするコンパイラを備えたコンピュータ装置において、コンパイラは、処理対象であるプログラムから命令のＤＡＧを構築し、解析するＤＡＧ解析部と、この解析結果に基づいて、このプログラム全体の実行時間を延ばさないことを条件として、このプログラムの並列性を保証するために必要な、このプログラムの各命令が使用する変数間の干渉を示す干渉グラフを構築する干渉グラフ構築部と、この干渉グラフに基づいて、命令に対するレジスタ割付を行うレジスタ割付部とを備えたことを特徴とする。
【００１７】
さらに、このコンピュータ装置は、レジスタ割付部によるレジスタ割付の結果を干渉グラフに記述し、この干渉グラフを出力する出力手段をさらに備える構成とすることができる。
【００１８】
また、本発明は、プログラミングの処理効率を向上させるための最適化として、プログラムの各命令に対し、グラフカラーリングによるレジスタ割付を行うレジスタ割付方法において、処理対象であるプログラムから命令のＤＡＧを構築し、解析するステップと、ＤＡＧにおける並列化できない最も長い命令列（クリティカルパス）を基準とし、ＤＡＧの解析結果に基づいて、所定の複数の命令が並列に実行されないとこのクリティカルパス列が延長されてしまう場合に、この複数の命令が使用する変数を干渉するとみなして干渉グラフを構築するステップと、構築された干渉グラフに基づいて、この命令に対するレジスタ割付を行うステップとを含むことを特徴とする。
【００１９】
ここで、ＤＡＧを構築し解析するステップは、ＤＡＧを構成するノードである命令を深さ優先で探索するステップと、探索結果のリバースポストオーダーを生成するステップとを含む。
また、干渉グラフを構築するステップは、生成されたリバースポストオーダーに基づいてこのＤＡＧから命令を順次取り出し、取り出した命令で使用されている変数と他の変数との間の干渉を決定するステップと、決定された変数間の干渉を干渉グラフに反映させることにより、干渉グラフを段階的に構築するステップとを含む。
【００２０】
さらに詳しくは、ＤＡＧを構築し解析するステップは、ＤＡＧを構成するノードである各命令について、実行開始時刻を変更できる自由度と、最早実行開始時刻とを算出を算出するステップをさらに含む。
また、干渉グラフを構築するステップは、リバースポストオーダーに基づいてこのＤＡＧから取り出した命令に関して、算出された各命令の自由度及び最早実行開始時刻とに基づいて、各命令の実行開始時刻を決定するステップをさらに含む。そして、決定された各命令の実行開始時刻に基づいて、各命令で使用されている変数の間の干渉を決定する。
【００２１】
さらにここで、各命令の実行開始時刻を決定するステップは、この命令の自由度及び最早実行開始時刻に基づき、プログラム全体の実行時間を延ばさない範囲でこの命令の実行開始時刻を遅らせた場合に、この命令で使用する関数における他の関数との干渉の数が減るならば、この干渉の数が最も少なくなる時刻をこの命令の実行開始時刻に決定するステップを含む。
【００２２】
また、本発明は、上記のレジスタ割付方法を処理対象であるプログラムのコンパイル時における最適化としてコンピュータに実行させるプログラムとして作成し、記憶媒体に格納したり、プログラム伝送装置で配信したりすることにより提供することができる。
【００２３】
【発明の実施の形態】
以下、添付図面に示す実施の形態に基づいてこの発明を詳細に説明する。
まず、本発明の概要について説明する。本発明は、コンパイルの対象であるプログラムから命令を実行する順番を示す有指向性グラフであるＤＡＧ（Directed Acyclic Graph）を作成し、当該ＤＡＧに基づいて各命令が実行時間に影響する度合いを計算する。そして、この情報に基づいて命令を整列し、命令どうしの実行順序を考慮しながら干渉グラフを構築する。すなわち、プログラム全体の実行時間を延ばさないことを条件として最低限度必要な並列性を保証するための干渉を加えた干渉グラフを作成する。
【００２４】
これを実現するために、本発明では、ＤＡＧのノード（プログラムの各命令）に対して、プログラムの実行時間が最小になるように位相整列順序を決定し、この順序において各命令における変数の生存区間が重なる場合に、その変数間の干渉だけを干渉グラフに反映させるようにする。なお、変数の生存区間とは、当該変数を定義する命令から当該定義において最後に使用する命令までの区間を意味する。例えば、命令Ａが変数ａを使用し、命令Ｂが変数ｂを使用する場合であって、命令Ａ、Ｂが並列に実行される可能性があるものとする。このとき、所定の位相整列の結果において、命令Ｂが変数ａの生存区間の終了後に実行されるならば、その位相整列順序を用い、変数ａ、ｂ間の干渉はないものとして干渉グラフを構築する。
【００２５】
また、本発明では、プログラム全体の実行時間に影響がない範囲で並列性を放棄する。すなわち、プログラムの重要な部分の並列性を保証するための干渉だけを干渉グラフに反映させるようにする。
【００２６】
以上の手法により、本発明では考慮すべき変数間の干渉の数を最小化する。すなわち、プログラム全体の実行速度を落とさないことを考慮しながら命令をソートして実行順序を決定することにより、プログラムの並列性に伴い各命令が持つ実行順序の自由度に基づいて発生する推移的な干渉可能性を除去することが可能になる。これにより、命令間の並列性を保証しながら、干渉の数を大幅に削減することができる。この結果、構成要素のより少ない干渉グラフでグラフカラーリングを行うことができることとなり、計算にようする時間コストを改善することができる。
【００２７】
図１は、本発明の実施の形態によるコンパイラにおけるレジスタ割付部の構成を説明する図である。
図１を参照すると、本実施の形態におけるレジスタ割付部１０は、ＤＡＧ解析部１１と、干渉グラフ構築部１２と、グラフカラーリング部１３とを備え、プログラムにおける命令のレジスタ割付を行う。ＤＡＧ解析部１１は、処理対象であるプログラムからＤＡＧを作成し、干渉グラフを作成するために必要な解析を行う。干渉グラフ構築部１２は、ＤＡＧ解析部１１の解析結果に基づいて干渉グラフを構築する。グラフカラーリング部１３は、干渉グラフ構築部１２により構築された干渉グラフをカラーリングしてレジスタの割付を実行する。
【００２８】
図１に示すレジスタ割付部１０の各構成要素は、コンピュータプログラムにより制御されたＣＰＵにて実現される仮想的なソフトウェアブロックである。ＣＰＵを制御する当該コンピュータプログラムはＣＤ−ＲＯＭやフレキシブルディスクなどの記憶媒体に格納したり、ネットワークを介して伝送したりすることにより提供される。
【００２９】
上記構成において、ＤＡＧ解析部１１は、処理対象であるプログラムからＤＡＧを作成し、ノードである各命令の自由度及び最早実行開始時刻を計算し、さらにＤＡＧを構成するノードに対して深さ優先探索を行い、探索結果に対するリバースポストオーダーを生成する。
図２は、ＤＡＧ解析部１１の動作を説明するフローチャートである。
図２を参照すると、ＤＡＧ解析部１１は、まず処理対象のプログラムからＤＡＧを作成する（ステップ２０１）。図７にＤＡＧの例を示す。図７において、命令ａ＝ｆ（）乃至命令ｉ＝ｆ（ｈ）の命令列は、並列化できない最も長い命令列であり、当該ＤＡＧのクリティカルパスである。また、命令ｊ＝ｆ（ａ）乃至命令ｌ＝ｆ（ｋ）のサブパスは、クリティカルパスにおける命令ｂ＝ｆ（ａ）乃至命令ｅ＝ｆ（ｄ）と並列に実行できる命令列である。同様に、命令ｍ＝ｆ（ｂ）乃至命令ｏ＝ｆ（ｎ）のサブパスは、クリティカルパスにおける命令ｃ＝ｆ（ｂ）乃至命令ｆ＝ｆ（ｅ，ｌ）と並列に実行できる命令列である。また、命令ｐ＝ｆ（ｋ）乃至命令ｑ＝ｆ（ｐ）のサブパスは、命令ｋ＝ｆ（ｊ）乃至命令ｇ＝ｆ（ｆ，ｏ）と並列に実行できる命令列である。
【００３０】
次に、作成されたＤＡＧの各ノード（命令）の自由度を計算する（ステップ２０２）。自由度とは、ＤＡＧのクリティカルパスを延ばさずに、当該命令をＤＡＧ上でどれだけ移動できるかを表す指標である。言い換えれば、当該命令の実行開始時刻を変更できる度合いである。自由度が低ければ低いほど、命令の位置が固定化されるため、その命令が重要であるとみなすことができる。
各ノードの自由度は、各ノードのトップレベル値とボトムレベル値から計算される。ノードをｖ、トップレベル値をｌｔ（ｖ）、ボトムレベル値をｌｂ（ｖ）とすると、自由度ｓｌ（ｖ）は、
ｓｌ（ｖ）＝（グラフのクリティカルパスの長さ）−ｌｔ（ｖ）−ｌｂ（ｖ）
で求められる。なお、各ノードのトッブレベル値ｌｔ（ｖ）は、ノードｖの実行サイクル数をｃｙ（ｖ）とすると、
0003651774.tif 000002
で求められる。ここで、ｐｒｅｄ（ｖ）は、ノードｖのプレデセサーの集合である。また、各ノードのボトムレベル値ｌｂ（ｖ）は、
0003651774.tif 000003
で求められる。ここで、ｓｕｃｃ（ｖ）は、ノードｖのサクセサーの集合である。
【００３１】
図８は図７に示したＤＡＧにおいて、上式に基づいて算出された各命令の自由度を示す図である。図８を参照すると、クリティカルパスである命令ａ＝ｆ（）乃至命令ｉ＝ｆ（ｈ）の各命令は自由度が０である。また、命令ｊ＝ｆ（ａ）乃至命令ｌ＝ｆ（ｋ）の各命令は自由度が１である。また、命令ｍ＝ｆ（ｂ）乃至命令ｏ＝ｆ（ｎ）の各命令は自由度が１である。さらにまた、命令ｐ＝ｆ（ｋ）乃至命令ｑ＝ｆ（ｐ）の各命令は自由度が２である。
【００３２】
次に、ＤＡＧの各ノード（命令）の最早実行開始時刻を計算する（ステップ２０３）。最早実行開始時刻とは、最初に実行する命令ａ＝ｆ（）から順に命令を実行する場合に、当該命令を実行可能な最も早い時刻（サイクル）である。図９に図７のＤＡＧにおける各ノードの最早実行開始時刻を示す。図９を参照すると、例えば、命令ｂ＝ｆ（ａ）と命令ｊ＝ｆ（ａ）とは、最も早い場合で、命令ａ＝ｆ（）の直後に実行されるため、最早実行開始時刻は２である。また、命令ｍ＝ｆ（ｂ）は、最も早い場合で、命令ｂ＝ｆ（ａ）の直後に実行できるため、最早実行開始時刻は３である。
【００３３】
次に、ＤＡＧに対して深さ優先探索を行い、探索結果のリバースポストオーダーを求める（ステップ２０４）。探索経路が分岐して複数存在する場合は、自由度の高い方向を優先して探索する。すなわち、図９において、命令ｂ＝ｆ（ａ）と命令ｊ＝ｆ（ａ）とは、共に命令ａ＝ｆ（）の直後に位置しているが、命令ｊ＝ｆ（ａ）の方が自由度が高いため、優先される。これにより、本ステップで得られるリバースポストオーダーでは、自由度の低いノード（すなわち、より重要な命令）が先に出現することとなる。図１０は、図７のＤＡＧを深さ優先で探索して得られたリバースポストオーダーを示す図である。図１０の各命令に付された数字は、リバースポストオーダーにおいて出現するノード（命令）の順番を示す。
【００３４】
干渉グラフ構築部１２は、ＤＡＧ解析部１１により生成されたＤＡＧにおけるノード（命令）のリバースポストオーダー、各命令の自由度及び最早実行開始時刻を用いて、段階的に干渉グラフを構築する。
すなわち、ＤＡＧを深さ優先で探索した探索結果のリバースポストオーダーによってソートされた順番で、命令を取り出し、その命令で使用されている変数とその命令よりも前に並んでいる命令で使用されている変数との干渉を調べ、順番に干渉グラフに付け加える。これにより、ＤＡＧのノードに対して、プログラムの実行時間が最小になるように各ノードの相対的な順序を示す位相整列順序を決定し、この順序において各命令における変数の生存区間が重なる場合に、その変数間の干渉だけを干渉グラフに反映させることが実現される。
また、所定の命令で使用されている変数とそれ以前に現れた変数との間の干渉を干渉グラフに加える場合に、プログラム全体の実行時間を遅らせない範囲において当該命令の実行開始時間を遅らせることによって、当該命令で定義されている変数と他の変数との生存区間の重なりが減少するならば、当該命令の実行開始時間を遅らせて干渉を削減する。これにより、プログラムの重要な部分の並列性を保証するための干渉だけを干渉グラフに反映させ、プログラム全体の実行時間に影響がない範囲で並列性を放棄することが実現される。
【００３５】
図３は、干渉グラフ構築部１２の動作を説明するフローチャートである。
図３を参照すると、干渉グラフ構築部１２は、まず、ＤＡＧ解析部１１により得られたリバースポストオーダーからノード（命令）を順番に取り出す（ステップ３０１）。そして、取り出した命令の実行開始時刻を決定し、この決定された実行開始時刻に基づいて、変数間の干渉を決定し、干渉グラフを段階的に作っていく（ステップ３０２、３０３）。以上の動作を、リバースポストオーダーにしたがって全ての命令について順次実行する（ステップ３０２）。
【００３６】
図４は、図３のフローチャートにおけるステップ３０３の動作を詳細に説明するフローチャートである。
図４を参照すると、干渉グラフ構築部１２は、ＤＡＧのリバースポストオーダーから取り出した命令の実行開始時刻の遅延範囲を計算する（ステップ４０１）。この命令の実行開始時刻の遅延範囲の計算方法を、図５のフローチャートを参照して説明する。
図５を参照すると、まず、取り出した命令で使用されている変数が、これまでに構築された干渉グラフに既に現れており、その生存区間が決定されているかどうかを判定する（ステップ５０１）。そして、当該変数の生存区間が決定されていたならば、当該命令の自由度とその生存区間の小さい方を、当該命令における実行開始時刻の遅延範囲とする（ステップ５０２）。一方、当該変数の生存区間が決定されていない場合は、当該命令の自由度を当該命令における実行開始時刻の遅延範囲とする（ステップ５０３）。すなわち、変数の生存区間が既に決定されている場合には、その生存区間を延ばさない範囲で当該命令の実行開始時刻を決定することとなる。
【００３７】
図４に戻り、干渉グラフ構築部１２は、ステップ４０１で決定された、当該命令における実行開始時刻の遅延範囲において、これまでに決定された変数間の干渉度が減る部分があるかどうかを調べる（ステップ４０２）。具体的な手法としては、例えば、これまでに構築された干渉グラフに現れている変数に関して生存区間図表を作成しておき、この生存区間図表における該当変数の生存区間と当該命令における実行開始時刻の遅延範囲とを比較する。そして、最早実行開始時刻よりも実行開始時刻を遅らせることによって、生存区間図表に記載された他の変数との干渉が削減されるかどうかを調べる。
【００３８】
そして、干渉が減る部分がない場合は、最早実行開始時刻を当該命令の実行開始時刻とする（ステップ４０３、４０４）。
一方、干渉が減る部分がある場合は、その時刻を当該命令の実行開始時刻とする（ステップ４０３、４０５）。ステップ４０５において、命令の実行開始時刻を最早実行開始時刻よりも遅らせた場合、当該命令から到達可能であり、かつ当該命令よりも高い自由度を持っている命令に関して、自由度及び最早実行開始時刻を再計算する。この処理は、当該命令を指定してＤＡＧ解析部１１に処理を渡して行わせても良いし、この再計算を行う機能を干渉グラフ構築部１２に設けて行っても良い。
以上のようにして、ＤＡＧのリバースポストオーダーから命令を取り出すごとに、その実行開始時刻を決定する。これにより、当該命令が使用している変数と他の変数との干渉を決定し、その結果を干渉グラフに反映させることができる。
【００３９】
図１１乃至図１７は、図１０に示したＤＡＧのリバースポストオーダーの順番にノード（命令）を取り出して生存区間図表を作成し、干渉グラフを構築する様子を説明する図である。
図１１は、図１０の１番目から５番目までの命令が取り出されて処理された結果を示す。ここでは、変数の干渉がないので、全ての命令の実行開始時刻は最早実行開始時刻となる。
【００４０】
図１２は、図１０の６番目から８番目までの命令が取り出されて処理された結果を示す。ここで、６番目から８番目までの各命令は、図５のフローチャートに基づき、自由度１に応じた１サイクル分の実行開始時刻の遅延範囲を持つ。しかしながら、これらの命令の実行開始時刻を遅らせても他の変数との干渉の数は減らないので、各命令の実行開始時刻は最早実行開始時刻となる。
【００４１】
図１３は、図１０の９番目の命令が取り出されて処理された結果を示す。この命令は、図１２（ａ）の全ての変数の生存区間の終了後に実行されるため、変数の干渉はないものとして扱う。したがって、この命令の実行開始時刻は最早実行開始時刻となる。
【００４２】
図１４は、図１０の１０番目から１２番目までの命令が取り出されて処理された結果を示す。ここでは、１０番目乃至１２番目の命令は、自由度１に応じた１サイクル分の実行開始時刻の遅延範囲を持つ。しかしながら、１０番目及び１１番目の命令に関しては、これらの命令の実行開始時刻を遅らせても他の変数との干渉の数は減らないので、各命令の実行開始時刻は最早実行開始時刻となる。一方、１２番目の命令に関しては、実行開始時刻を１サイクル遅延させると、変数ｏの干渉数を削減することができる（図１４（ｂ）に示すように、変数ｆとのみ干渉することとなる）。そこで、当該１２番目の命令の実行開始時刻は、最早実行開始時刻よりも１サイクル遅延させる。
【００４３】
図１５は、図１０の１３番目の命令が取り出されて処理された結果を示す。この命令が使用する変数は、図１４（ｂ）の干渉グラフに現れていないので、変数ｇと干渉する変数はない。したがって、この命令の実行開始時刻は最早実行開始時刻となる。
【００４４】
図１６は、図１０の１４番目と１５番目の命令が取り出されて処理された結果を示す。ここでは、１４番目の命令は、変数ｐと干渉する変数ｌ、ｎの生存区間に応じた１サイクル分の実行開始時刻の遅延範囲を持つ。しかしながら、これらの命令の実行開始時刻を遅らせても他の変数との干渉の数は減らないので、各命令の実行開始時刻は最早実行開始時刻となる。一方、１５番目の命令は、自由度２及び変数ｑと干渉する他の変数の生存区間とに応じて１サイクル分の実行開始時刻の遅延範囲を持つ。そして、この命令の実行開始時刻を１サイクル遅延させると、変数ｑの干渉数を削減することができる。（図１６（ｂ）に示すように、変数ｇとのみ干渉することとなる）。そこで、当該１５番目の命令の実行開始時刻は、最早実行開始時刻よりも１サイクル遅延させる。
なお、当該１５番目の命令から到達可能で、この命令よりも大きな自由度を持つ命令は存在しないので、ここでは、自由度の再計算は行わない。
【００４５】
図１７は、図１０の１６番目と１７番目の命令が取り出されて処理された結果を示す。これらの命令は、図１６（ａ）の全ての変数の生存区間の終了後に順次実行されるため、変数の干渉はないものとして扱う。したがって、この命令の実行開始時刻は最早実行開始時刻となる。
以上のようにして、プログラム全体の実行時間を延ばすことなく、最低限度必要な並列性を保証した上で、変数間の干渉を極力削減した干渉グラフが構築される。
【００４６】
グラフカラーリング部１３は、グラフ識別部として、上述のようにして干渉グラフ構築部１２により構築された干渉グラフを解析し、ノードの識別を行う。そして、この識別結果に基づいてレジスタの割付を実行する。本実施の形態では、レジスタ割付の手法として、各レジスタに割り当てられた色で干渉グラフを彩色（色分け）するイメージで割付を行うグラフカラーリングを行う。グラフカラーリングを行う際には、ＤＡＧのサブパスにまたがる逆依存をなるべく少なくする。すなわち、ＤＡＧのサブパスへの分岐情報を利用して、同じサブパス上で定義される変数には同じ色が割り当てられるようにする。なお、レジスタ割付の手法としては、本実施の形態に示すグラフカラーリング以外の手法により干渉グラフのノードの識別を行い、レジスタ割付を行う態様を取ることも可能である
【００４７】
本実施の形態では、干渉グラフ構築部１２により構築された干渉グラフは、上述したように、並列に実行される可能性はあるが、仮に並列に実行されなくてもプログラム全体の実行時間への影響はないような命令における変数の干渉を削減している。これにより、扱うべき変数の干渉度が減少するため高速なグラフカラーリングが可能となっている。しかしながら、干渉度が減少した結果、異なる変数に同じ色を割り当てる（同じレジスタを割り付ける）ことによる逆依存が発生しやすくなっている。この逆依存の発生は、レジスタ割付の後に実行される命令スケジューラの自由度を制限してしまう可能性がある。例えば、高度な中間言語に対する最適化において、低レベルでの命令スケジューラの自由度を残しながらグラフカラーリングによるレジスタの割付を行い、その後に細かなハードウェアリソースを考慮した命令スケジューラを行う場合、逆依存の発生は命令スケジューラにおいて障害となる。
そこで、上記のように、ＤＡＧのパス情報（サブパスへの分岐情報）を利用して彩色を行うことにより、逆依存の発生を最低限に抑え、プログラムのコンパイルにおいて、本実施の形態によるレジスタ割付の後に行われる命令スケジューラの自由度を保持することができる。
【００４８】
図６は、グラフカラーリング部１３の動作を説明するフローチャートである。図６を参照すると、グラフカラーリング部１３は、まず干渉グラフ構築部１２にて構築された干渉グラフにおける各ノード対の干渉類似度を計算する（ステップ６０１）。ここで、干渉類似度の計算方法としては、従来からグラフカラーリングにおいて用いられている既存の手法を用いることができる。
【００４９】
次に、干渉グラフのノード対における二つのノードがＤＡＧ上の同じパスに合ったかどうかをマークする（ステップ６０２）。そして、干渉グラフにおける各ノード対を類似度によりソートする（ステップ６０３）。同じ類似度のノード対があった場合は、ステップ６０２でマークした結果に基づき、ＤＡＧ上の同じパスにあったものを優先してソートする。
【００５０】
次に、ソートされたノード対を先頭から順番に取り出し、ノードどうしのマージを行う（ステップ６０４）。ここで、ノードマージの手法としては、従来からグラフカラーリングにおいて用いられている既存の手法を用いることができる。
【００５１】
最後に、ノード対のマージが行われた干渉グラフに対して、グラフカラーリングを行う（ステップ６０５）。グラフカラーリングの手法としては、従来から用いられている既存の手法を用いることができる。なお、上述したように、ＤＡＧにおける同じサブパス上で定義される変数には同じ色を割り当てる。
【００５２】
図１８は、図１７（ｂ）に示した干渉グラフを対象として、上記のグラフカラーリングによりレジスタ（ｒ１、ｒ２、ｒ３、ｒ４）の割付を行った結果を示す図である。図１８において、各ノードに括弧書きで添えられた記号が割り付けられたレジスタを示す。
図１８の干渉グラフと、図１９に示す従来のグラフカラーリングの手法において構築された干渉グラフとを比較すると、本実施の形態による図１８の干渉グラフは、命令の並列実行可能性は十分に保証されながら、変数間の干渉数が劇的に減少していることがわかる。
【００５３】
【発明の効果】
以上説明したように、本発明によれば、グラフカラーリングにおいて、命令の並列実行可能性を保証したまま、変数間の干渉数を減少させることができる。
また、これにより、命令間の並列性を保証したグラフカラーリングにおいて、コンパイルに要する時間の増大や無駄なスピルコードの生成を回避することができる。
【図面の簡単な説明】
【図１】  本発明の実施の形態によるコンパイラにおけるレジスタ割付部の構成を説明する図である。
【図２】  本実施の形態におけるＤＡＧ解析部の動作を説明するフローチャートである。
【図３】  本実施の形態における干渉グラフ構築部の動作を説明するフローチャートである。
【図４】  図３のフローチャートにおけるステップ３０３の動作を詳細に説明するフローチャートである。
【図５】  図４のフローチャートにおけるステップ４０１の動作を詳細に説明するフローチャートである。
【図６】  本実施の形態におけるグラフカラーリング部の動作を説明するフローチャートである。
【図７】  本実施の形態で用いるＤＡＧの構成例を示す図である。
【図８】  図７に示したＤＡＧにおける各命令の自由度を示す図である。
【図９】  図７に示したＤＡＧにおける各命令の最早実行開始時刻を示す図である。
【図１０】  図７に示したＤＡＧを深さ優先で探索して得られたリバースポストオーダーを示す図である。
【図１１】  図１０に示したＤＡＧのリバースポストオーダーから生存区間図表と干渉グラフとを作成する様子を説明する図であり、１番目から５番目までの命令が取り出されて処理された結果を示す図である。
【図１２】  図１０に示したＤＡＧのリバースポストオーダーから生存区間図表と干渉グラフとを作成する様子を説明する図であり、６番目から８番目までの命令が取り出されて処理された結果を示す図である。
【図１３】  図１０に示したＤＡＧのリバースポストオーダーから生存区間図表と干渉グラフとを作成する様子を説明する図であり、９番目の命令が取り出されて処理された結果を示す図である。
【図１４】  図１０に示したＤＡＧのリバースポストオーダーから生存区間図表と干渉グラフとを作成する様子を説明する図であり、１０番目から１２番目までの命令が取り出されて処理された結果を示す図である。
【図１５】  図１０に示したＤＡＧのリバースポストオーダーから生存区間図表と干渉グラフとを作成する様子を説明する図であり、１３番目の命令が取り出されて処理された結果を示す図である。
【図１６】  図１０に示したＤＡＧのリバースポストオーダーから生存区間図表と干渉グラフとを作成する様子を説明する図であり、１４番目と１５番目の命令が取り出されて処理された結果を示す図である。
【図１７】  図１０に示したＤＡＧのリバースポストオーダーから生存区間図表と干渉グラフとを作成する様子を説明する図であり、１６番目と１７番目の命令が取り出されて処理された結果を示す図である。
【図１８】  図１７に示した干渉グラフを対象としてレジスタ割付を行った結果を示す図である。
【図１９】  従来のグラフカラーリングの手法により構築された干渉グラフの例を示す図である。
【符号の説明】
１０…レジスタ割付部、１１…ＤＡＧ解析部、１２…干渉グラフ構築部、１３…グラフカラーリング部
【図１】
0003651774.tif 000004
【図２】
0003651774.tif 000005
【図３】
0003651774.tif 000006
【図４】
0003651774.tif 000007
【図５】
0003651774.tif 000008
【図６】
0003651774.tif 000009
【図７】
0003651774.tif 000010
【図８】
0003651774.tif 000011
【図９】
0003651774.tif 000012
【図１０】
0003651774.tif 000013
【図１１】
0003651774.tif 000014
【図１２】
0003651774.tif 000015
【図１３】
0003651774.tif 000016
【図１４】
0003651774.tif 000017
【図１５】
0003651774.tif 000018
【図１６】
0003651774.tif 000019
【図１７】
0003651774.tif 000020
【図１８】
0003651774.tif 000021
【図１９】
0003651774.tif 000022