(57)【要約】【課題】マスク付きＳＩＭＤ命令がないＣＰＵについても条件分岐を含むループをＳＩＭＤ化すること。【解決手段】構文解析部１１が、ソースコード２を入力して構文解析を行い、ループを特定する。そして、最適化部１２に含まれるループＳＩＭＤ化部３０が、構文解析部１１により特定されたループのうち条件分岐を含むループに含まれる条件分岐文内で実行される演算のオペランドを該演算命令のアドレス毎に用意したスタックに積む命令列を生成する。そして、ループＳＩＭＤ化部３０は、演算を行うＳＩＭＤ命令が１度に演算する個数のオペランドがスタックに積まれているか否かをチェックする命令列を生成し、スタックから該個数のオペランドを取り出す命令列を生成する。そして、ループＳＩＭＤ化部３０は、スタックから取り出された該個数のオペランドに対して演算を実行するＳＩＭＤ命令を生成する。【選択図】図１
2019067117.tif 000002
【特許請求の範囲】
【請求項１】
コード生成装置において、
ソースコードの構文解析に基づいてループを特定する構文解析部と、
第１命令変更部とを有し、
前記第１命令変更部は、
前記構文解析部が特定したループに含まれる条件分岐文内で実行される演算のオペランドを該演算命令のアドレス毎に用意したスタックに積む命令列を生成する第１ｐｕｓｈ命令生成部と、
前記演算を行うＳＩＭＤ命令が１度に演算する個数のオペランドが前記スタックに積まれているか否かをチェックする命令列を生成する第１チェック命令生成部と、
前記スタックから前記個数のオペランドを取り出す命令列を生成する第１ｐｏｐ命令生成部と、
前記スタックから取り出された前記個数のオペランドに対して前記演算を実行するＳＩＭＤ命令を生成する第１ＳＩＭＤ命令生成部と
を有するコード生成装置。
【請求項２】
前記コード生成装置はさらに、
前記ループの実行後に前記スタックにオペランドが残されている場合、残されたオペランドについて前記演算を実行する命令列を生成する余り処理部を有する請求項１に記載のコード生成装置。
【請求項３】
前記余り処理部は、前記スタックに残されたオペランドの数と前記演算の種別からＳＩＭＤ化が有効か否かを判定する命令列と、前記スタックにＮＵＬＬオペランドを追加する命令列及び前記ＳＩＭＤ命令と、前記スタックに残されたオペランドの数の前記演算を行う命令列とを生成する請求項２に記載のコード生成装置。
【請求項４】
前記コード生成装置はさらに、
前記構文解析部により特定されたループのうちストライドアクセスのループについてＳＩＭＤ化を行うループＳＩＭＤ化部を有する請求項１に記載のコード生成装置。
【請求項５】
前記コード生成装置はさらに、
前記構文解析部により特定されたループのうち繰り返し回数が実行時まで不明な不明ループについてＳＩＭＤ化を行う第２命令変更部を有し、
前記第２命令変更部は、
前記不明ループに含まれる演算のオペランドを該演算命令のアドレス毎に用意したスタックに積む命令列を生成する第２ｐｕｓｈ命令生成部と、
前記演算を行うＳＩＭＤ命令が１度に演算する個数のオペランドが前記スタックに積まれているか否かをチェックする命令列を生成する第２チェック命令生成部と、
前記スタックから前記個数のオペランドを取り出す命令列を生成する第２ｐｏｐ命令生成部と、
前記スタックから取り出された前記個数のオペランドに対して前記演算を実行するＳＩＭＤ命令を生成する第２ＳＩＭＤ命令生成部と
を有する請求項１に記載のコード生成装置。
【請求項６】
前記第２命令変更部は、前記不明ループとして終了条件付きループ及び飛び出しを含むループについてＳＩＭＤ化を行う請求項５に記載のコード生成装置。
【請求項７】
コード生成方法において、
コンピュータが、
ソースコードの構文解析に基づいてループを特定し、
特定された前記ループに含まれる条件分岐文内で実行される演算のオペランドを該演算命令のアドレス毎に用意したスタックに積む命令列を生成し、
前記演算を行うＳＩＭＤ命令が１度に演算する個数のオペランドが前記スタックに積まれているか否かをチェックする命令列を生成し、
前記スタックから前記個数のオペランドを取り出す命令列を生成し、
前記スタックから取り出された前記個数のオペランドに対して前記演算を実行するＳＩＭＤ命令を生成するコード生成方法。
【請求項８】
コード生成プログラムにおいて、
コンピュータに、
ソースコードの構文解析に基づいてループを特定させ、
特定された前記ループに含まれる条件分岐文内で実行される演算のオペランドを該演算命令のアドレス毎に用意したスタックに積む命令列を生成させ、
前記演算を行うＳＩＭＤ命令が１度に演算する個数のオペランドが前記スタックに積まれているか否かをチェックする命令列を生成させ、
前記スタックから前記個数のオペランドを取り出す命令列を生成させ、
前記スタックから取り出された前記個数のオペランドに対して前記演算を実行するＳＩＭＤ命令を生成させるコード生成プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コード生成装置、コード生成方法及びコード生成プログラムに関する。
【背景技術】
【０００２】
コンパイラが行う最適化の一つにループのＳＩＭＤ（Single  Instruction  Multiple  Data）化がある。ここで、ＳＩＭＤ化とは、１つの命令で複数のデータを並列に演算するＳＩＭＤ命令を用いて複数の命令を当該複数の命令に対応する１つのＳＩＭＤ命令に変換することにより、プログラムを高速化することである。
【０００３】
ソースコードに含まれるループに条件分岐がない場合には、ループのＳＩＭＤ化はＳＩＭＤ命令を用いて行うことができる。一方、ループに条件分岐がある場合には、ＳＩＭＤ化のためにマスク付きＳＩＭＤ命令が用いられる。ここで、マスク付きＳＩＭＤ命令とは、本来は実行する必要のない演算の実行結果を演算後にメモリ又はレジスタに書き戻さないことで条件分岐をなくすことができるＳＩＭＤ命令である。
【０００４】
なお、ＳＩＭＤ化を用いて有効なプログラム最適化を行う方法がある。この方法は、最適化対象のオリジナルプログラムをコンピュータに実行させて実行時の分析結果を含むプロファイル情報を収集し、プロファイル情報に基づいて演算待ち時間を算出する。そして、この方法は、演算待ち時間が第１の閾値より長い場合、オリジナルプログラムのループ内のＳＩＭＤ命令率が第２の閾値より低い場合に、ループ内のＩＦ文の命令をＳＩＭＤ化するＳＩＭＤ化制御行をオリジナルプログラムのループに挿入する。
【０００５】
また、条件付きループをベクトル化する命令を有するプロセッサがある。この命令は、ｎ個の連続したベクトルエレメントを保持するために、ソースベクトルを特定するパラメータ、条件付きマスクレジスタを特定するパラメータ、及び、デスティネーションレジスタを特定するためのデスティネーションパラメータを有する。複数のｎ個の連続したベクトルエレメントのそれぞれは、ｍバイトの同じ可変パーティションサイズを有している。プロセッサ命令に呼応して、データがソースベクトルの連続したベクトルエレメントからコピーされ、特定されたデスティネーションベクトルのマスキングされていないベクトルエレメントにコピーされ、ｎは、実行されるプロセッサ命令に呼応して変化する。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２０１６−４０６９１号公報
【特許文献２】特開２０１４−１３０５８０号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
マスク付きＳＩＭＤ命令がないＣＰＵ（Central  Processing  Unit）については、条件分岐を含むループのＳＩＭＤ化ができないという問題がある。また、マスク付きＳＩＭＤ命令がある場合にも、ｗｈｉｌｅループ等回転数が実行するまで不明であるループをＳＩＭＤ化することはできない。また、マスク付きＳＩＭＤ化命令の実行効率はよくない。
【０００８】
本発明は、１つの側面では、マスク付きＳＩＭＤ命令がないＣＰＵについても条件分岐を含むループをＳＩＭＤ化することを目的とする。
【課題を解決するための手段】
【０００９】
１つの態様では、コード生成装置は、ソースコードの構文解析に基づいてループを特定する構文解析部と、第１命令変更部とを有する。第１命令変更部は、構文解析部が特定したループに含まれる条件分岐文内で実行される演算のオペランドを該演算命令のアドレス毎に用意したスタックに積む命令列を生成する第１ｐｕｓｈ命令生成部を有する。また、第１命令変更部は、演算を行うＳＩＭＤ命令が１度に演算する個数のオペランドがスタックに積まれているか否かをチェックする命令列を生成する第１チェック命令生成部を有する。また、第１命令変更部は、スタックから該個数のオペランドを取り出す命令列を生成する第１ｐｏｐ命令生成部と、スタックから取り出された該個数のオペランドに対して演算を実行するＳＩＭＤ命令を生成する第１ＳＩＭＤ命令生成部とを有する。
【発明の効果】
【００１０】
１つの側面では、本発明は、マスク付きＳＩＭＤ命令がないＣＰＵについても条件分岐を含むループをＳＩＭＤ化することができる。
【図面の簡単な説明】
【００１１】
【図１】図１は、実施例に係るコード生成装置の機能構成を示す図である。
【図２】図２は、ループＳＩＭＤ化部の機能構成を示す図である。
【図３】図３は、ＳＩＭＤ化可否判定部の機能構成を示す図である。
【図４】図４は、条件分岐ＳＩＭＤ化部の機能構成を示す図である。
【図５】図５は、不明ループＳＩＭＤ化部の機能構成を示す図である。
【図６】図６は、ループＳＩＭＤ化部による処理のフローを示すフローチャートである。
【図７】図７は、ループ中の条件分岐の内外で依存がある例を示す図である。
【図８】図８は、ＳＩＭＤ化可否判定部による処理のフローを示すフローチャートである。
【図９】図９は、条件分岐ＳＩＭＤ化部による処理のフローを示すフローチャートである。
【図１０】図１０は、余りループ生成部による処理のフローを示すフローチャートである。
【図１１】図１１は、不明ループＳＩＭＤ化部による処理のフローを示すフローチャートである。
【図１２】図１２は、条件分岐を含むループ（２−ＳＩＭＤの場合）の最適化例を示す図である。
【図１３】図１３は、条件分岐を含むループ（２−ＳＩＭＤの場合）に関して実施例に係る最適化による効果を説明するための図である。
【図１４】図１４は、ｗｈｉｌｅループ（２−ＳＩＭＤの場合）に関して実施例に係る最適化による効果を説明するための図である。
【図１５】図１５は、条件分岐を含むループ（４−ＳＩＭＤの場合）の最適化例を示す図である。
【図１６】図１６は、ベクトル長が異なる演算が混在している場合の最適化例を示す図である。
【図１７】図１７は、ストライドアクセスのループ（４−ＳＩＭＤの場合）の最適化例を示す図である。
【図１８】図１８は、ｗｈｉｌｅループ（４−ＳＩＭＤの場合）の最適化例を示す図である。
【図１９】図１９は、飛び出しのあるループ（飛び出しの判定に演算で用いる変数が使われない場合）の最適化例を示す図である。
【図２０】図２０は、実施例に係るコード生成プログラムを実行するコンピュータのハードウェア構成を示す図である。
【発明を実施するための形態】
【００１２】
以下に、本願の開示するコード生成装置、コード生成方法及びコード生成プログラムの実施例を図面に基づいて詳細に説明する。なお、この実施例は開示の技術を限定するものではない。
【実施例】
【００１３】
まず、実施例に係るコード生成装置の機能構成について説明する。図１は、実施例に係るコード生成装置の機能構成を示す図である。図１に示すように、コード生成装置１は、構文解析部１１と、最適化部１２と、コード生成部１３とを有する。
【００１４】
構文解析部１１は、ソースコード２をファイルから入力してソースコード２の構文解析を行う。構文解析部１１は、構文解析を行うことでソースコード２に含まれるループを特定する。また、構文解析部１１は、実行速度を向上するためのコードの最適化を指定する最適化オプション等のオプションを受け付ける。オプションは、例えば、コンパイル指示とともにキーボード又はマウスを用いてユーザにより入力される。
【００１５】
最適化部１２は、最適化オプションが指定された場合に、コードの最適化を行う。コード生成部１３は、最適化オプションが指定された場合には、最適化が行われたコードからオブジェクトコード３を生成し、ファイルに出力する。
【００１６】
最適化部１２は、汎用最適化部２０と、ループＳＩＭＤ化部３０と、固有最適化部４０とを有する。汎用最適化部２０は、コンパイル対象のＣＰＵのアーキテクチャに関係しない汎用的な最適化を行う。ループＳＩＭＤ化部３０は、ソースコード２に含まれるループのＳＩＭＤ化を行う。固有最適化部４０は、コンパイル対象のＣＰＵのアーキテクチャに依存する最適化を行う。
【００１７】
図２は、ループＳＩＭＤ化部３０の機能構成を示す図である。図２に示すように、ループＳＩＭＤ化部３０は、ＳＩＭＤ化可否判定部３１とＳＩＭＤ化ループ変換部３２とを有する。
【００１８】
ＳＩＭＤ化可否判定部３１は、ＳＩＭＤ化が可能か否かを判定する。ＳＩＭＤ化ループ変換部３２は、コードをＳＩＭＤ命令を用いるコードに変換する。ＳＩＭＤ化ループ変換部３２は、条件分岐ＳＩＭＤ化部５０と、不明ループＳＩＭＤ化部６０と、連続ＳＩＭＤ化部７０と、余りループ生成部８０とを有する。
【００１９】
条件分岐ＳＩＭＤ化部５０は、条件分岐を含むループのＳＩＭＤ化を行う。不明ループＳＩＭＤ化部６０は、ｗｈｉｌｅループや飛び出しのあるループのようにループの終了が実行するまで不明なループのＳＩＭＤ化を行う。連続ＳＩＭＤ化部７０は、演算のオペランドが連続した領域であるループのＳＩＭＤ化を行う。
【００２０】
余りループ生成部８０は、ループの終了時にＳＩＭＤ化するために必要な数に達していない余りのオペランドを処理するコードを生成する。余りループ生成部８０は、方式選択部８１と、スカラループ生成部８２と、ＮＵＬＬオペランド生成部８３と、ＳＩＭＤ命令生成部８４とを有する。
【００２１】
方式選択部８１は、余りのオペランドを処理する方式を選択するコードを生成する。余りのオペランドを処理する方式には、スカラループにより処理する方式とＳＩＭＤ化に必要なオペランド数になるようにＮＵＬＬオペランドを生成しＳＩＭＤ化する方式がある。方式選択部８１は、余りのオペランドの数に基づいて、いずれの方式の実行性能が高いかを判定し、実行性能が高い方の方式を選択する。
【００２２】
スカラループ生成部８２は、余りのオペランドをスカラループにより処理するコードを生成する。ＮＵＬＬオペランド生成部８３は、ＳＩＭＤ化に必要なオペランド数になるようにＮＵＬＬオペランドを生成するコードを生成する。ＳＩＭＤ命令生成部８４は、ＮＵＬＬオペランドを含むＳＩＭＤ命令を生成する。
【００２３】
図３は、ＳＩＭＤ化可否判定部３１の機能構成を示す図である。図３に示すように、ＳＩＭＤ化可否判定部３１は、依存解析チェック部３６と、連続性チェック部３７と、命令有無チェック部３８とを有する。
【００２４】
依存解析チェック部３６は、演算を並列実行すると引用すべきデータを引用する前に新たな値で上書きしてしまうか否かをを判定し、誤って上書きしてしまう可能性がある場合には、ＳＩＭＤ化が可能でないと判定し、正しく引用できる場合には、ＳＩＭＤ化が可能であると判定する。
【００２５】
連続性チェック部３７は、ループ内にある演算のオペランドの領域へのアクセスが、一定方向であるか否かを判定し、一定方向でない場合には、ＳＩＭＤ化が可能でないと判定し、一定方向である場合には、ＳＩＭＤ化が可能であると判定する。連続性チェック部３７は、飛び込みチェック部３９を有する。飛び込みチェック部３９は、ループ外からループ内への飛び込みの有無をチェックし、ループ外からループ内への飛び込みがある場合には、ループ内の演算のオペランドの領域へのアクセスが一定方向でないと判定する。
【００２６】
命令有無チェック部３８は、ループ内の演算を行うＳＩＭＤ命令があるか否かを判定し、ない場合には、ＳＩＭＤ化が可能でないと判定し、ある場合には、ＳＩＭＤ化が可能であると判定する。
【００２７】
図４は、条件分岐ＳＩＭＤ化部５０の機能構成を示す図である。図４に示すように、条件分岐ＳＩＭＤ化部５０は、ｐｕｓｈ命令生成部５１と、チェック命令生成部５２と、ｐｏｐ命令生成部５３と、ＳＩＭＤ命令生成部５４とを有する。
【００２８】
ｐｕｓｈ命令生成部５１は、条件分岐文内で実行される演算のオペランドを演算命令のアドレス毎に用意したオペランドスタックに積む命令列を生成する。ここで、条件分岐文内とは、条件分岐文の中である。例えば、条件分岐文の１つであるＩＦ文において、ＩＦ  条件  ＴＨＥＮ  Ａ  ＥＬＳＥ  Ｂ；の場合、Ａ及びＢが条件分岐文内で実行される演算である。なお、命令列には、命令が１つの場合も含まれる。チェック命令生成部５２は、ＳＩＭＤ命令が処理する数のオペランドがオペランドスタックに積まれているかをチェックする命令列を生成する。
【００２９】
ｐｏｐ命令生成部５３は、ＳＩＭＤ命令が処理するオペランドをオペランドスタックから取り出す命令列を生成する。ＳＩＭＤ命令生成部５４は、オペランドスタックから取り出されたオペランドを用いて演算を行うＳＩＭＤ命令を生成する。
【００３０】
図５は、不明ループＳＩＭＤ化部６０の機能構成を示す図である。図５に示すように、不明ループＳＩＭＤ化部６０は、ｐｕｓｈ命令生成部６１と、チェック命令生成部６２と、ｐｏｐ命令生成部６３と、ＳＩＭＤ命令生成部６４とを有する。
【００３１】
ｐｕｓｈ命令生成部６１は、ループ内で実行される演算のオペランドを演算命令のアドレス毎に用意したオペランドスタックに積む命令列を生成する。ｐｕｓｈ命令生成部５１が条件分岐文内で実行される演算のオペランドをオペランドスタックに積む命令列を生成するのとは異なり、ｐｕｓｈ命令生成部６１はループ内で実行される演算のオペランドをオペランドスタックに積む命令列を生成する。
【００３２】
チェック命令生成部６２は、ＳＩＭＤ命令が処理する数のオペランドがオペランドスタックに積まれているかをチェックする命令列を生成する。ｐｏｐ命令生成部６３は、ＳＩＭＤ命令が処理するオペランドをオペランドスタックから取り出す命令列を生成する。ＳＩＭＤ命令生成部６４は、オペランドスタックから取り出されたオペランドを用いて演算を行うＳＩＭＤ命令を生成する。
【００３３】
次に、ループＳＩＭＤ化部３０による処理のフローについて図６〜図１１を用いて説明する。図６は、ループＳＩＭＤ化部３０による処理のフローを示すフローチャートである。図６に示すように、ループＳＩＭＤ化部３０は、Ｃｕｒｒ＿ｌｏｏｐをソースコード２の任意のループとし（ステップＳ１）、Ｃｕｒｒ＿ｌｏｏｐをまだチェックしていないループに変更しながら、ステップＳ２〜ステップＳ９の処理を繰り返し行う。
【００３４】
すなわち、ループＳＩＭＤ化部３０は、Ｃｕｒｒ＿ｌｏｏｐのＳＩＭＤ化が可能か否かを判定し（ステップＳ２）、ＳＩＭＤ化が可能である場合には、ループ中に条件分岐があるか否かを判定する（ステップＳ３）。
【００３５】
そして、ループＳＩＭＤ化部３０は、ループ中に条件分岐がない場合には、ループ中の回転数をループより前に計算できるか否かを判定し（ステップＳ４）、計算できる場合には、連続領域にアクセスするループをＳＩＭＤ化する（ステップＳ５）。一方、ループ中の回転数をループより前に計算できない場合には、ループＳＩＭＤ化部３０は、ループの終了が実行するまで不明なループをＳＩＭＤ化する（ステップＳ６）。そして、ループＳＩＭＤ化部３０は、次のループを処理する。
【００３６】
また、ステップＳ３において、ループ中に条件分岐がある場合には、ループＳＩＭＤ化部３０は、ループ中の条件分岐文の内外で依存があるか否かを判定する（ステップＳ７）。図７は、ループ中の条件分岐文の内外で依存がある例を示す図である。図７に示すように、ループ中で定義されたａａ［ｉ］をｉｆ文の条件式に用いる場合は、ループのイテレーション毎に演算結果が必要となり、ループ中の条件分岐文の内外で依存がある。図７では、「（ａａ［ｉ］＝＝０．０）  ｂｒｅａｋ；」が条件分岐文の内であり、「ａａ［ｉ］＝ｓｑｒｔ（ｂｂ［ｉ］）；」、「ｉ＝ｉ＋１；」等が条件分岐文の外である。
【００３７】
ループＳＩＭＤ化部３０は、ループ中の条件分岐文の内外で依存がない場合には、条件分岐を含むループをＳＩＭＤ化し（ステップＳ８）、ループ中の条件分岐文の内外で依存がある場合には、ループをＳＩＭＤ化しない（ステップＳ９）。そして、ループＳＩＭＤ化部３０は、次のループを処理する。また、ステップＳ２において、ＳＩＭＤ化可否判定部３１がＳＩＭＤ化が可能でないと判定した場合には、ループＳＩＭＤ化部３０は、ステップＳ９へ移動する。
【００３８】
このように、ループＳＩＭＤ化部３０は、条件分岐を含むループ及びループの終了が実行するまで不明なループをＳＩＭＤ化するので、従来より多くのループをＳＩＭＤ化することができる。
【００３９】
図８は、ＳＩＭＤ化可否判定部３１による処理のフローを示すフローチャートである。図８に示すように、ＳＩＭＤ化可否判定部３１は、ループの処理を並列実行した場合に引用すべきデータを引用する前に新たな値で上書きしてしまう否かを判定し（ステップＳ１１）、変わらない場合には、ループへの飛び込みがあるか否かを判定する（ステップＳ１２）。
【００４０】
そして、ループへの飛び込みがない場合には、ＳＩＭＤ化可否判定部３１は、回転数は少ないか否か又は回転数は少ないと推測できるか否かを判定する（ステップＳ１３）。ここで、回転数が少ないとは、例えば回転数が所定の閾値以下である場合である。また、回転数が少ないと推測できるとは、例えば、過去の実行結果において回転数が所定の閾値以下である率が８０％以上である場合である。
【００４１】
そして、回転数は少なくない場合又は回転数は少ないと推測できない場合には、ＳＩＭＤ化可否判定部３１は、対応するＳＩＭＤ命令があるか否かを判定する（ステップＳ１４）。そして、ＳＩＭＤ化可否判定部３１は、対応するＳＩＭＤ命令がない場合には、ＳＩＭＤ化不可と判定し（ステップＳ１５）、対応するＳＩＭＤ命令がある場合には、ＳＩＭＤ化可能と判定する（ステップＳ１６）。
【００４２】
また、ステップＳ１３において回転数は少ない場合又は回転数は少ないと推測できる場合、又は、ステップＳ１２においてループへの飛び込みがある場合には、ＳＩＭＤ化可否判定部３１は、ＳＩＭＤ化不可と判定する（ステップＳ１５）。あるいは、ステップＳ１１においてループの処理が回転数に依存する場合には、ＳＩＭＤ化可否判定部３１は、ＳＩＭＤ化不可と判定する（ステップＳ１５）。
【００４３】
このように、ＳＩＭＤ化可否判定部３１がＳＩＭＤ化が可能か否かを判定することによって、ループＳＩＭＤ化部３０は、ＳＩＭＤ化の対象であるループを特定することができる。
【００４４】
図９は、条件分岐ＳＩＭＤ化部５０による処理のフローを示すフローチャートである。図９に示すように、条件分岐ＳＩＭＤ化部５０は、条件分岐時に実行される演算のオペランドを演算のアドレス毎に用意したオペランドスタックに積む命令列を生成する（ステップＳ２１）。
【００４５】
そして、条件分岐ＳＩＭＤ化部５０は、ＳＩＭＤ命令が１度に扱える分のオペランドがオペランドスタックに溜まったかをチェックする命令列を生成する（ステップＳ２２）。そして、条件分岐ＳＩＭＤ化部５０は、ＳＩＭＤ命令が１度に扱える分のオペランドがオペランドスタックに溜まった場合にオペランドをオペランドスタックから取り出す命令列を生成する（ステップＳ２３）。
【００４６】
そして、条件分岐ＳＩＭＤ化部５０は、オペランドがオペランドスタックから取り出された場合にＳＩＭＤ命令を実行する命令列を生成する（ステップＳ２４）。そして、条件分岐ＳＩＭＤ化部５０は、ループ終了後にオペランドスタックにオペランドが残るか否かを判定する（ステップＳ２５）。
【００４７】
そして、条件分岐ＳＩＭＤ化部５０は、ループ終了後にオペランドスタックにオペランドが残る場合に、余りループ生成部８０にオペランドスタックのオペランドを処理する命令列を生成させる余り処理を行う（ステップＳ２６）。
【００４８】
このように、条件分岐ＳＩＭＤ化部５０が条件分岐を含むループをオペランドスタックを用いてＳＩＭＤ化するので、ループＳＩＭＤ化部３０は、マスク付きＳＩＭＤ命令がない場合にも条件分岐を含むループをＳＩＭＤ化することができる。
【００４９】
図１０は、余りループ生成部８０による処理のフローを示すフローチャートである。図１０に示すように、余りループ生成部８０は、ＳＩＭＤ化対象の演算の中にオペランドをＮＵＬＬにすると例外を上げるものがあるか否かを判定する（ステップＳ３１）。
【００５０】
そして、例外を上げるものがない場合には、余りループ生成部８０は、ＳＩＭＤ化しきれなかったオペランドを演算するために、次のいずれかのループを実行するように１つの条件分岐の命令列と、２種類のループの命令列を生成する（ステップＳ３２）。
【００５１】
条件分岐の命令列としては、余りループ生成部８０は、まず、オペランドスタックに残っているオペランドの数と演算種別から、ＮＵＬＬオペランドを補ってＳＩＭＤ化したほうが実行性能面で得するか否かを判断する命令列を生成する。そして、余りループ生成部８０は、ＳＩＭＤ化したほうが得する場合には、“余りループＡ”を実行する命令列を生成し、ＳＩＭＤ化しても得しない場合には、“余りループＢ”を実行する命令列を生成する。
【００５２】
そして、余りループ生成部８０は、“余りループＡ”の命令列として、ＳＩＭＤ演算ユニットを全て満たすように、ＮＵＬＬオペランドを追加したＳＩＭＤ命令を生成する。そして、余りループ生成部８０は、“余りループＢ”の命令列として、ＳＩＭＤ化しきれなかったオペランドを演算するためのスカラループの命令列を生成する。
【００５３】
一方、ＳＩＭＤ化対象の演算の中にオペランドをＮＵＬＬにすると例外を上げるものがある場合には、ＳＩＭＤ化しきれなかったオペランドを演算するためのスカラループの命令列を生成する（ステップＳ３３）。
【００５４】
このように、余りループ生成部８０がオペランドスタックに残っているオペランドを演算する命令列を生成するので、ループＳＩＭＤ化部３０は、条件分岐中又はループ中で演算が実行される数によらずループをＳＩＭＤ化することができる。
【００５５】
図１１は、不明ループＳＩＭＤ化部６０による処理のフローを示すフローチャートである。図１１に示すように、不明ループＳＩＭＤ化部６０は、ループで実行される演算のオペランドを演算のアドレス毎に用意したオペランドスタックに積む命令列を生成する（ステップＳ４１）。
【００５６】
そして、不明ループＳＩＭＤ化部６０は、ＳＩＭＤ命令が１度に扱える分のオペランドがオペランドスタックに溜まったかをチェックする命令列を生成する（ステップＳ４２）。そして、不明ループＳＩＭＤ化部６０は、ＳＩＭＤ命令が１度に扱える分のオペランドがオペランドスタックに溜まった場合にオペランドをオペランドスタックから取り出す命令列を生成する（ステップＳ４３）。
【００５７】
そして、不明ループＳＩＭＤ化部６０は、オペランドがオペランドスタックから取り出された場合にＳＩＭＤ命令を実行する命令列を生成する（ステップＳ４４）。そして、不明ループＳＩＭＤ化部６０は、余りループ生成部８０にオペランドスタックのオペランドを処理する命令列を生成させる余り処理を行う（ステップＳ４５）。
【００５８】
このように、不明ループＳＩＭＤ化部６０がループの終了が実行するまで不明なループをオペランドスタックを用いてＳＩＭＤ化する。したがって、ループＳＩＭＤ化部３０は、ループの終了が実行するまで不明なループをＳＩＭＤ化することができる。
【００５９】
次に、ループＳＩＭＤ化部３０による最適化例及び効果について図１２〜図１９を用いて説明する。図１２は、条件分岐を含むループ（２−ＳＩＭＤの場合）の最適化例を示す図である。図１２に示すように、最適化前のコードには、ｆｏｒループの中にｉｆ文が含まれる。
【００６０】
ループＳＩＭＤ化部３０は、ｉｆ文の条件が成立した場合に、オペランドと演算結果の格納先のアドレスとをオペランドスタックに積む命令列（ａ）を生成する。ｓｉｍｄｉｚｅはオペランドスタックのポインタである。ｓ＿ｏｐ１、ｓ＿ｏｐ２、ｓ＿ｄｓｔはオペランドスタックである。
【００６１】
そして、ループＳＩＭＤ化部３０は、２つのオペランドがオペランドスタックに積まれたか否かを判定して２つのオペランドが積まれた場合に２つのオペランドをオペランドスタックから取り出してＳＩＭＤ命令ｓｉｍｄ＿ａｄｄを実行する命令列（ｂ）を生成する。
【００６２】
そして、ループＳＩＭＤ化部３０は、余りのオペランドを処理するために、ＮＵＬＬオペランドをオペランドスタックに積む命令列（ｃ）、２つのオペランドをオペランドスタックから取り出してＳＩＭＤ命令ｓｉｍｄ＿ａｄｄを実行する命令列（ｄ）を生成する。
【００６３】
なお、図１２は、例を簡単にするために、余りのオペランドを処理するためにループＳＩＭＤ化部３０がＳＩＭＤ命令を用いる場合を示す。
【００６４】
図１３は、条件分岐を含むループ（２−ＳＩＭＤの場合）に関して実施例に係る最適化による効果を説明するための図である。図１３（ａ）は従来手法の命令数を示し、図１３（ｂ）は実施例の命令数を示す。また、「Ｔ」はｃｏｎｄ［ｉ］（ｉ＝０〜９）がＴｒｕｅであることを示し、「Ｆ」はｃｏｎｄ［ｉ］がＦａｌｓｅであることを示す。また、ｎは１０である。
【００６５】
図１３（ａ）に示すように、従来手法では、回転数が１０であり２−ＳＩＭＤであるので、２つのオペランドをロードするためのＬＯＡＤ（ＳＩＭＤ）の数は２×５＝１０であり、ＳＩＭＤ演算の数は５である。また、ｃｏｎｄ［２］、ｃｏｎｄ［３］の値が共に「Ｆ」であるので、ａａ［２：３］へのストアはなく、ＳＴＯＲＥの数は４である。
【００６６】
一方、図１３（ｂ）に示すように、実施例の場合には、「Ｔ」の数が４であるので、２つのオペランドをロードするためのＬＯＡＤの数は２×４＝８であり、ＳＩＭＤ演算の数は２である。したがって、実施例の場合には、ＬＯＡＤ及びＳＩＭＤ演算の数が少なく実行効率がよい。
【００６７】
図１４は、ｗｈｉｌｅループ（２−ＳＩＭＤの場合）に関して実施例に係る最適化による効果を説明するための図である。図１４（ａ）に示すように、従来手法では、ｗｈｉｌｅループのＳＩＭＤ化は行われないので、Ｎ次元の配列の加算において、ＬＯＡＤの数は２Ｎであり、スカラ演算の数はＮであり、ＳＴＯＲＥの数はＮである。
【００６８】
一方、図１４（ｂ）に示すように、実施例の場合には、Ｎを奇数とし余りのオペランドにスカラ命令を用いると、ＬＯＡＤの数は２Ｎであり、ＳＩＭＤ演算及びＳＩＭＤ−ＳＴＯＲＥの数は（Ｎ−１）／２であり、スカラ演算及びＳＴＯＲＥの数は１である。スカラ演算及びＳＴＯＲＥは余りのオペランドに用いられる。したがって、実施例の場合には、演算数及びストア数をほぼ１／２にすることができ実行効率がよい。
【００６９】
図１５は、条件分岐を含むループ（４−ＳＩＭＤの場合）の最適化例を示す図である。図１５では、図１３と比較して、２つのオペランドの加算の代わりに１つのオペランドの平方根演算であるので、オペランドスタックにオペランドを積む命令が１つ減る。また、２個の代わりに４個のデータがＳＩＭＤ命令で処理されるので、オペランドスタックに積まれるオペランドの数が４になるとＳＩＭＤ命令ｓｉｍｄ＿ｓｑｒｔを実行する命令列が生成される。
【００７０】
図１６は、ベクトル長が異なる演算が混在している場合の最適化例を示す図である。ここで、ベクトル長とは、ＳＩＭＤ命令で演算するオペランドの数である。図１６に示すように、単精度（ｆｌｏａｔ）の配列ａ［Ｎ］及びｘ［Ｎ］のベクトル長を４とすると、倍精度（ｄｏｕｂｌｅ）の配列ｙ［Ｎ］のベクトル長は、倍精度のデータサイズは単精度のデータサイズの２倍であるので、２である。このため、ベクトル長が長い単精度に合わせてＳＩＭＤ命令が生成される。すなわち、１つの単精度ＳＩＭＤ命令ｓｉｍｄ＿ｓｑｒｔｆに対して２つの倍精度ＳＩＭＤ命令ｓｉｍｄ＿ｓｑｒｔが生成される（ａ）。
【００７１】
図１７は、ストライドアクセスのループ（４−ＳＩＭＤの場合）の最適化例を示す図である。ここで、ストライドアクセスのループとは、アクセスするデータが連続でなく飛び飛びであるループである。図１７では、外ループのｊが２以上になると、内ループにおけるｉが連続した値でなく飛び飛びの値となる。
【００７２】
図１７に示すように、実施例では、オペランドスタックにオペランドが積まれ、オペランドスタックのオペランドに対してＳＩＭＤ化演算が行われるため、ストライドアクセスのループのＳＩＭＤ化が可能となる。すなわち、ループＳＩＭＤ化部３０は、ストライドアクセスのループをＳＩＭＤ化することができる。
【００７３】
図１８は、ｗｈｉｌｅループ（４−ＳＩＭＤの場合）の最適化例を示す図である。図１８では、オペランドスタックｓ＿ｏｐ１及びｓ＿ｏｐ２にオペランドが積まれ、オペランドスタックｓ＿ｄｓｔに演算結果の格納先のアドレスが積まれる。
【００７４】
そして、４つのオペランドがオペランドスタックに積まれたか否かが判定され、４つのオペランドが積まれた場合に４つのオペランドがオペランドスタックから取り出されてＳＩＭＤ命令ｓｉｍｄ＿ａｄｄが実行される。
【００７５】
そして、余りのオペランドの処理用に、ＮＵＬＬオペランドがオペランドスタックに積まれ、ＮＵＬＬオペランドを含む４つのオペランドがオペランドスタックから取り出されてＳＩＭＤ命令ｓｉｍｄ＿ａｄｄが実行される。
【００７６】
図１９は、飛び出しのあるループ（飛び出しの判定に演算で用いる変数が使われない場合）の最適化例を示す図である。図１９では、２つのｂｒｅａｋ文によりループからの飛び出しが行われる。図１９に示すように、ループＳＩＭＤ化部３０は、飛び出しのあるループについても、オペランドスタックを用いてＳＩＭＤ化を行うことができる。
【００７７】
上述してきたように、実施例では、構文解析部１１が、ソースコード２を入力して構文解析を行い、ループを特定する。そして、構文解析部１１は、最適化オプションが指定されると、構文解析結果を最適化部１２に渡す。そして、最適化部１２に含まれるループＳＩＭＤ化部３０が、構文解析部１１により特定されたループのうち条件分岐を含むループとループの回転数が実行時まで不明なループとをマスク付きＳＩＭＤ命令を用いることなくＳＩＭＤ化する。ここで、ループの回転数が実行時まで不明なループには、例えばｗｈｉｌｅループ、ｂｒｅａｋ文を含むループがある。
【００７８】
したがって、コード生成装置１は、マスク付きＳＩＭＤ命令がないＣＰＵについても条件分岐を含むループをＳＩＭＤ化することができる。また、コード生成装置１は、ループの回転数が実行時まで不明なループをＳＩＭＤ化することができる。なお、ループの回転数が実行時まで不明なループには、例えばｗｈｉｌｅループ、ｂｒｅａｋ文を含むループがある。
【００７９】
また、実施例では、ループＳＩＭＤ化部３０は、条件分岐を含むループについて、条件分岐文内で実行される演算のオペランドをオペランドスタックに積む命令列を生成する。そして、ループＳＩＭＤ化部３０は、演算を行うＳＩＭＤ命令が１度に演算する個数のオペランドがオペランドスタックに積まれているか否かをチェックする命令列を生成する。そして、ループＳＩＭＤ化部３０は、ＳＩＭＤ命令が１度に演算する個数のオペランドをオペランドスタックから取り出す命令列を生成する。そして、ループＳＩＭＤ化部３０は、オペランドスタックから取り出されたオペランドに対して演算を行うＳＩＭＤ命令を生成する。したがって、ループＳＩＭＤ化部３０は、条件分岐を含むループをオペランドスタックを用いてＳＩＭＤ化することができる。また、ループＳＩＭＤ化部３０は、実行効率の良い命令列を生成することができる。
【００８０】
また、実施例では、ループＳＩＭＤ化部３０は、余りのオペランドの数と演算の種別からＳＩＭＤ化が有効か否かを判定する命令列、オペランドスタックにＮＵＬＬオペランドを追加する命令列及びＳＩＭＤ命令を生成する。また、ループＳＩＭＤ化部３０は、余りのオペランドの数の演算を行う命令列を生成する。したがって、ループＳＩＭＤ化部３０は、余りのオペランドを効率良く処理する命令列を生成することができる。
【００８１】
なお、実施例では、コード生成装置１について説明したが、コード生成装置１が有する構成をソフトウェアによって実現することで、同様の機能を有するコード生成プログラムを得ることができる。そこで、コード生成プログラムを実行するコンピュータについて説明する。
【００８２】
図２０は、実施例に係るコード生成プログラムを実行するコンピュータのハードウェア構成を示す図である。図２０に示すように、コンピュータ９０は、メインメモリ９１と、ＣＰＵ９２と、ＬＡＮ（Local  Area  Network）インタフェース９３と、ＨＤＤ（Hard  Disk  Drive）９４とを有する。また、コンピュータ９０は、スーパーＩＯ（Input  Output）９５と、ＤＶＩ（Digital  Visual  Interface）９６と、ＯＤＤ（Optical  Disk  Drive）９７とを有する。
【００８３】
メインメモリ９１は、プログラムやプログラムの実行途中結果などを記憶するメモリである。ＣＰＵ９２は、メインメモリ９１からプログラムを読み出して実行する中央処理装置である。ＣＰＵ９２は、メモリコントローラを有するチップセットを含む。
【００８４】
ＬＡＮインタフェース９３は、コンピュータ９０をＬＡＮ経由で他のコンピュータに接続するためのインタフェースである。ＨＤＤ９４は、プログラムやデータを格納するディスク装置であり、スーパーＩＯ９５は、マウスやキーボードなどの入力装置を接続するためのインタフェースである。ＤＶＩ９６は、液晶表示装置を接続するインタフェースであり、ＯＤＤ９７は、ＤＶＤの読み書きを行う装置である。
【００８５】
ＬＡＮインタフェース９３は、ＰＣＩエクスプレス（ＰＣＩｅ）によりＣＰＵ９２に接続され、ＨＤＤ９４及びＯＤＤ９７は、ＳＡＴＡ（Serial  Advanced  Technology  Attachment）によりＣＰＵ９２に接続される。スーパーＩＯ９５は、ＬＰＣ（Low  Pin  Count）によりＣＰＵ９２に接続される。
【００８６】
そして、コンピュータ９０において実行されるコード生成プログラムは、コンピュータ９０により読み出し可能な記憶媒体の一例であるＤＶＤに記憶され、ＯＤＤ９７によってＤＶＤから読み出されてコンピュータ９０にインストールされる。あるいは、コード生成プログラムは、ＬＡＮインタフェース９３を介して接続された他のコンピュータシステムのデータベースなどに記憶され、これらのデータベースから読み出されてコンピュータ９０にインストールされる。そして、インストールされたコード生成プログラムは、ＨＤＤ９４に記憶され、メインメモリ９１に読み出されてＣＰＵ９２によって実行される。
【符号の説明】
【００８７】
１    コード生成装置
２    ソースコード
３    オブジェクトコード
１１    構文解析部
１２    最適化部
１３    コード生成部
２０    汎用最適化部
３０    ループＳＩＭＤ化部
３１    ＳＩＭＤ化可否判定部
３２    ＳＩＭＤ化ループ変換部
３６    依存解析チェック部
３７    連続性チェック部
３８    命令有無チェック部
３９    飛び込みチェック部
４０    固有最適化部
５０    条件分岐ＳＩＭＤ化部
５１    ｐｕｓｈ命令生成部
５２    チェック命令生成部
５３    ｐｏｐ命令生成部
５４    ＳＩＭＤ命令生成部
６０    不明ループＳＩＭＤ化部
６１    ｐｕｓｈ命令生成部
６２    チェック命令生成部
６３    ｐｏｐ命令生成部
６４    ＳＩＭＤ命令生成部
７０    連続ＳＩＭＤ化部
８０    余りループ生成部
８１    方式選択部
８２    スカラループ生成部
８３    ＮＵＬＬオペランド生成部
８４    ＳＩＭＤ命令生成部
９０    コンピュータ
９１    メインメモリ
９２    ＣＰＵ
９３    ＬＡＮインタフェース
９４    ＨＤＤ
９５    スーパーＩＯ
９６    ＤＶＩ
９７    ＯＤＤ
【図１】
2019067117.tif 000003
【図２】
2019067117.tif 000004
【図３】
2019067117.tif 000005
【図４】
2019067117.tif 000006
【図５】
2019067117.tif 000007
【図６】
2019067117.tif 000008
【図７】
2019067117.tif 000009
【図８】
2019067117.tif 000010
【図９】
2019067117.tif 000011
【図１０】
2019067117.tif 000012
【図１１】
2019067117.tif 000013
【図１２】
2019067117.tif 000014
【図１３】
2019067117.tif 000015
【図１４】
2019067117.tif 000016
【図１５】
2019067117.tif 000017
【図１６】
2019067117.tif 000018
【図１７】
2019067117.tif 000019
【図１８】
2019067117.tif 000020
【図１９】
2019067117.tif 000021
【図２０】
2019067117.tif 000022