(57)【要約】【課題】コンパイラによる最適化をユーザが緻密に制御することが可能な柔軟性の高いコンパイラを提供する。【解決手段】コンパイラ１００に対するユーザからの指示（オプション及びプラグマ）を検出する解析部１１０と、解析部１１０からの指示等に従って、ユーザによるオプション及びプラグマによって指定された個別的な最適化処理を行う処理部（グローバル領域割り付け部１２１、ソフトウェアパイプライニング部１２２、ループアンローリング部１２３、ｉｆ変換部１２４及びペア命令生成部１２５）からなる最適化部１２０等を備え、グローバル領域割り付け部１２１は、グローバル領域に配置する変数の最大データサイズの指定、グローバル領域に配置させる変数の指定、及び、グローバル領域に配置させない変数の指定に関するオプション及びプラグマに従った最適化処理を行う。【選択図】　　　　図１
2004038597.tif 000002
【特許請求の範囲】
【請求項１】
ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、
生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、
取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、
前記最適化手段は、前記指示取得手段がグローバルメモリ領域に配置する配列データについての指示を取得した場合には、取得した指示に従ってグローバルメモリ領域に配置する配列データを決定することにより、前記最適化を施す
ことを特徴とするコンパイラ装置。
【請求項２】
前記指示取得手段は、前記ソースプログラムを翻訳する旨の指示とともに、グローバルメモリ領域に配置する配列データの最大データサイズについての指定を取得し、
前記最適化手段は、前記ソースプログラムで宣言された配列データのうち、前記最大データサイズを超えないデータサイズの配列データについてはグローバルメモリ領域に配置し、前記最大データサイズを超えるデータサイズの配列データについてはグローバルメモリ領域外のメモリ領域に配置する
ことを特徴とする請求項１記載のコンパイラ装置。
【請求項３】
前記指示取得手段は、前記ソースプログラムの中において、特定の配列データについて、グローバルメモリ領域に配置しない旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となった配列データについては、グローバルメモリ領域外のメモリ領域に配置する
ことを特徴とする請求項１記載のコンパイラ装置。
【請求項４】
前記指示取得手段は、前記ソースプログラムの中において、特定の配列データについて、グローバルメモリ領域に配置する旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となった配列データについては、グローバルメモリ領域に配置する
ことを特徴とする請求項１記載のコンパイラ装置。
【請求項５】
高級言語で記述されたソースプログラムが記録されたコンピュータ読み取り可能な記録媒体であって、
前記ソースプログラムには、当該ソースプログラムを機械語プログラムに翻訳するコンパイラに対して、（１）特定の配列データについて、グローバルメモリ領域に配置しない旨を指示する記述、及び、（２）特定の配列データについて、グローバルメモリ領域に配置する旨を指示する記述の少なくとも１つが含まれる
ことを特徴とする記録媒体。
【請求項６】
ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、
生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、
取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、
前記最適化手段は、前記指示取得手段がソフトウェアパイプライニングによる最適化についての指示を取得した場合には、取得した指示に従ってソフトウェアパイプライニングに関する最適化を施す
ことを特徴とするコンパイラ装置。
【請求項７】
前記指示取得手段は、前記ソースプログラムを翻訳する旨の指示とともに、ソフトウェアパイプライニングによる最適化をしない旨の指示を取得し、
前記最適化手段は、前記指示取得手段がソフトウェアパイプライニングによる最適化をしない旨の指示を取得した場合に、前記ソースプログラム中の全てのループ処理について、ソフトウェアパイプライニングによる最適化が行われることを抑制する
ことを特徴とする請求項６記載のコンパイラ装置。
【請求項８】
前記指示取得手段は、前記ソースプログラムの中において、特定のループ処理について、ソフトウェアパイプライニングによる最適化をしない旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったループ処理については、ソフトウェアパイプライニングによる最適化が行われることを抑制する
ことを特徴とする請求項６記載のコンパイラ装置。
【請求項９】
前記指示取得手段は、前記ソースプログラムの中において、特定のループ処理について、プロログ部及びエピログ部を除去したソフトウェアパイプライニングによる最適化をする旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったループ処理については、プロログ部及びエピログ部を除去できる範囲でソフトウェアパイプライニングによる最適化をする
ことを特徴とする請求項６記載のコンパイラ装置。
【請求項１０】
前記指示取得手段は、前記ソースプログラムの中において、特定のループ処理について、プロログ部及びエピログ部を除去しないでソフトウェアパイプライニングによる最適化をする旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったループ処理については、プロログ部及びエピログ部を除去せずに、可能な範囲でソフトウェアパイプライニングによる最適化をする
ことを特徴とする請求項６記載のコンパイラ装置。
【請求項１１】
前記指示取得手段は、前記ソースプログラムの中において、特定のループ処理の繰り返し回数に関する指定を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったループ処理については、指定された繰り返し回数に基づく最適化を行う
ことを特徴とする請求項６記載のコンパイラ装置。
【請求項１２】
前記繰り返し回数に関する指定は、前記ループ処理が繰り返される最低回数であり、
前記最適化手段は、前記最低回数がソフトウェアパイプライニングによって重なり合うイタレーション数以上である場合に、ソフトウェアパイプライニングによる最適化を行う
ことを特徴とする請求項１１記載のコンパイラ装置。
【請求項１３】
高級言語で記述されたソースプログラムが記録されたコンピュータ読み取り可能な記録媒体であって、
前記ソースプログラムには、当該ソースプログラムを機械語プログラムに翻訳するコンパイラに対して、（１）特定のループ処理について、ソフトウェアパイプライニングによる最適化をしない旨を指示する記述、（２）特定のループ処理について、プロログ部及びエピログ部を除去したソフトウェアパイプライニングによる最適化をする旨を指示する記述、及び、（３）特定のループ処理について、プロログ部及びエピログ部を除去しないでソフトウェアパイプライニングによる最適化をする旨を指示する記述の少なくとも１つが含まれる
ことを特徴とする記録媒体。
【請求項１４】
ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、
生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、
取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、
前記最適化手段は、前記指示取得手段がループアンローリングによる最適化についての指示を取得した場合には、取得した指示に従ってループアンローリングに関する最適化を施す
ことを特徴とするコンパイラ装置。
【請求項１５】
前記指示取得手段は、前記ソースプログラムを翻訳する旨の指示とともに、ループアンローリングによる最適化をしない旨の指示を取得し、
前記最適化手段は、前記指示取得手段がループアンローリングによる最適化をしない旨の指示を取得した場合に、前記ソースプログラム中の全てのループ処理について、ループアンローリングによる最適化が行われることを抑制する
ことを特徴とする請求項１４記載のコンパイラ装置。
【請求項１６】
前記指示取得手段は、前記ソースプログラムの中において、特定のループ処理について、ループアンローリングによる最適化をする旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったループ処理については、ループアンローリングによる最適化を行う
ことを特徴とする請求項１４記載のコンパイラ装置。
【請求項１７】
前記指示取得手段は、前記ソースプログラムの中において、特定のループ処理について、ループアンローリングによる最適化をしない旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったループ処理については、ループアンローリングが行われることを抑制する
ことを特徴とする請求項１４記載のコンパイラ装置。
【請求項１８】
前記指示取得手段は、前記ソースプログラムの中において、特定のループ処理の繰り返し回数に関する指定を検出し、
前記最適化手段は、前記指示取得手段によって検出された指定の対象となったループ処理については、指定された繰り返し回数に基づく最適化を行う
ことを特徴とする請求項１４記載のコンパイラ装置。
【請求項１９】
前記繰り返し回数に関する指定は、前記ループ処理が繰り返される最低回数であり、
前記最適化手段は、前記最低回数が１以上である場合に、繰り返し回数が０である場合に必要とされるエスケープコードの生成を抑制する
ことを特徴とする請求項１８記載のコンパイラ装置。
【請求項２０】
前記繰り返し回数に関する指定は、前記ループ処理が繰り返される最低回数であり、
前記最適化手段は、前記最低回数がループアンローリングによる展開数以上である場合に、ループアンローリングによる最適化を行う
ことを特徴とする請求項１８記載のコンパイラ装置。
【請求項２１】
前記繰り返し回数に関する指定は、前記ループ処理が偶数回だけ繰り返される旨の保証であり、
前記最適化手段は、前記指示取得手段によって検出された指定の対象となったループ処理については、偶数回だけ繰り返されるものとして、ループアンローリングによる最適化を行う
ことを特徴とする請求項１８記載のコンパイラ装置。
【請求項２２】
前記繰り返し回数に関する指定は、前記ループ処理が奇数回だけ繰り返される旨の保証であり、
前記最適化手段は、前記指示取得手段によって検出された指定の対象となったループ処理については、奇数回だけ繰り返されるものとして、ループアンローリングによる最適化を行う
ことを特徴とする請求項１８記載のコンパイラ装置。
【請求項２３】
高級言語で記述されたソースプログラムが記録されたコンピュータ読み取り可能な記録媒体であって、
前記ソースプログラムには、当該ソースプログラムを機械語プログラムに翻訳するコンパイラに対して、（１）特定のループ処理について、ループアンローリングによる最適化をする旨を指示する記述、（２）特定のループ処理について、ループアンローリングによる最適化をしない旨を指示する記述、及び、（３）特定のループ処理の繰り返し回数に関する保証を示す記述の少なくとも１つが含まれる
ことを特徴とする記録媒体。
【請求項２４】
ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、
生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、
取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、
前記最適化手段は、前記指示取得手段がｉｆ変換についての指示を取得した場合には、取得した指示に従ってｉｆ変換に関する最適化を施す
ことを特徴とするコンパイラ装置。
【請求項２５】
前記指示取得手段は、前記ソースプログラムを翻訳する旨の指示とともに、ｉｆ変換をしない旨の指示を取得し、
前記最適化手段は、前記指示取得手段がｉｆ変換をしない旨の指示を取得した場合に、前記ソースプログラム中の全てのｉｆ構造文について、ｉｆ変換が行われることを抑制する
ことを特徴とする請求項２４記載のコンパイラ装置。
【請求項２６】
前記指示取得手段は、前記ソースプログラムの中において、特定のｉｆ構造文について、ｉｆ変換をする旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったｉｆ構造文について、ｉｆ変換をする
ことを特徴とする請求項２４記載のコンパイラ装置。
【請求項２７】
前記指示取得手段は、前記ソースプログラムの中において、特定のｉｆ構造文について、ｉｆ変換をしない旨の指示を検出し、
前記最適化手段は、前記指示取得手段によって検出された指示の対象となったｉｆ構造文については、ｉｆ変換が行われることを抑制する
ことを特徴とする請求項２４記載のコンパイラ装置。
【請求項２８】
高級言語で記述されたソースプログラムが記録されたコンピュータ読み取り可能な記録媒体であって、
前記ソースプログラムには、当該ソースプログラムを機械語プログラムに翻訳するコンパイラに対して、（１）特定のｉｆ構造文について、ｉｆ変換をする旨を指示する記述、及び、（２）特定のｉｆ構造文について、ｉｆ変換をしない旨を指示する記述の少なくとも１つが含まれる
ことを特徴とする記録媒体。
【請求項２９】
ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、
生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、
取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、
前記最適化手段は、メモリ領域に配置する配列データのアライメントについての指示を取得した場合には、取得した指示に従ってデータをメモリ領域に配置することにより、前記最適化を施す
ことを特徴とするコンパイラ装置。
【請求項３０】
前記指示取得手段は、前記ソースプログラムを翻訳する旨の指示とともに、特定の型の配列データのアライメントについての指定を取得し、
前記最適化手段は、前記ソースプログラムで宣言された前記特定の型の全ての配列データについて、その先頭アドレスが前記アライメントとなるようにメモリ領域に配置する
ことを特徴とする請求項２９記載のコンパイラ装置。
【請求項３１】
前記指示取得手段は、前記ソースプログラムを翻訳する旨の指示とともに、構造体のアライメントについての指定を取得し、
前記最適化手段は、前記ソースプログラムで宣言された前記構造体データについて、その先頭アドレスが前記アライメントとなるようにメモリ領域に配置する
ことを特徴とする請求項２９記載のコンパイラ装置。
【請求項３２】
前記指示取得手段は、前記ソースプログラムの中において、特定の変数名で示される引数のポインタ変数が指すデータのアライメントについての指定を検出し、
前記最適化手段は、前記指示取得手段によって検出された指定の対象となったデータについては、指定されたアライメントでメモリ領域に配置されているものとして、前記最適化を施す
ことを特徴とする請求項２９記載のコンパイラ装置。
【請求項３３】
前記指示取得手段は、前記ソースプログラムの中において、特定の変数名で示されるローカルポインタ変数が指すデータのアライメントについての指定を検出し、
前記最適化手段は、前記指示取得手段によって検出された指定の対象となったデータについては、指定されたアライメントでメモリ領域に配置されているものとして、前記最適化を施す
ことを特徴とする請求項２９記載のコンパイラ装置。
【請求項３４】
前記最適化手段は、メモリ領域に配置した前記データにアクセスするメモリアクセス命令については、２以上のデータを同時に転送するペア命令を生成する
ことを特徴とする請求項３０〜３３のいずれか１項に記載のコンパイラ装置。
【請求項３５】
高級言語で記述されたソースプログラムが記録されたコンピュータ読み取り可能な記録媒体であって、
前記ソースプログラムには、当該ソースプログラムを機械語プログラムに翻訳するコンパイラに対して、（１）特定の変数名で示される引数のポインタ変数が指すデータのアライメントを保証する旨の記述、及び、（２）特定の変数名で示されるローカルポインタ変数が指すデータのアライメントを保証する旨の記述の少なくとも１つが含まれる
ことを特徴とする記録媒体。
【請求項３６】
ソースプログラムを機械語プログラムに翻訳するコンパイラ装置のためのプログラムであって、
請求項１〜４、６〜１２、１４〜２２、２４〜２７、２９〜３４のいずれか１項に記載のコンパイラ装置が備える全ての手段としてコンピュータに機能させる
ことを特徴とするプログラム。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、Ｃ言語等の高級言語で記述されたソースプログラムを機械語プログラムに変換するコンパイラに関し、特に、コンパイラによる最適化についての指示に関する。
【０００２】
【従来の技術】
従来のコンパイラは、主に制御処理アプリケーション向けに作られている。制御処理アプリケーションでは、精密な実行性能及びコードサイズのチューニングはそれほど必要とされておらず、むしろ開発工数削減の観点から、ユーザは、「性能優先」、「コードサイズ優先」、あるいは、「性能とコードサイズのバランス」といった大雑把な指示（コンパイル時に指定するオプション等）のみ与えて、その最適化戦略のほとんどをコンパイラに任せている。
【０００３】
一方、クリティカルな実行性能及びコードサイズが要求されるメディア処理
アプリケーションの分野では、アセンブリ言語によるハンドコーディングを行
うことにより、要求性能及びコードサイズを実現することを第一目標に開発が
行われている。
【０００４】
【発明が解決しようとする課題】
しかしながら、近年、メディア処理アプリケーションの増大化、多様化により、開発工数が増大し、メディア処理分野においても高級言語によるアプリケーション開発が必要とされるようになってきている。そのために、高級言語によるメディア処理アプリケーション開発を実現する試みが行われている。その際、ユーザは、高級言語開発であっても、より精密なチューニングができることを期待しており、コンパイラが行う最適化戦略を詳細に制御することが必要となる。
【０００５】
したがって、従来のような大雑把な指示ではなく、コンパイラによる各種最適化の種類ごとにＯＮ／ＯＦＦやその程度を指定したり、プログラム中の変数やループ処理等の単位で最適化をＯＮ／ＯＦＦさせたりする等のきめ細かい制御が必要とされる。
【０００６】
そこで、本発明は、このような状況に鑑みてなされたものであり、コンパイラによる最適化をユーザが緻密に制御することが可能な柔軟性の高いコンパイラを提供することを目的とする。
【０００７】
【課題を解決するための手段】
上記目的を達成するために、本発明に係るコンパイラは、ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、前記最適化手段は、前記指示取得手段がグローバルメモリ領域に配置する配列データについての指示を取得した場合には、取得した指示に従ってグローバルメモリ領域に配置する配列データを決定することにより、前記最適化を施すことを特徴とする。
【０００８】
また、本発明に係るコンパイラは、ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、前記最適化手段は、前記指示取得手段がソフトウェアパイプライニングによる最適化についての指示を取得した場合には、取得した指示に従ってソフトウェアパイプライニングに関する最適化を施すことを特徴とする。
【０００９】
また、本発明に係るコンパイラは、ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、前記最適化手段は、前記指示取得手段がループアンローリングによる最適化についての指示を取得した場合には、取得した指示に従ってループアンローリングに関する最適化を施すことを特徴とする。
【００１０】
また、本発明に係るコンパイラは、ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、前記最適化手段は、前記指示取得手段がｉｆ変換についての指示を取得した場合には、取得した指示に従ってｉｆ変換に関する最適化を施すことを特徴とする。
【００１１】
また、本発明に係るコンパイラは、ソースプログラムを機械語プログラムに翻訳するコンパイラ装置であって、生成する機械語プログラムを最適化する旨の指示を取得する指示取得手段と、取得された指示に従って機械語命令列を生成することにより、最適化を施す最適化手段とを備え、前記最適化手段は、メモリ領域に配置する配列データのアライメントについての指示を取得した場合には、取得した指示に従ってデータをメモリ領域に配置することにより、前記最適化を施すことを特徴とする。
【００１２】
なお、本発明は、上記のようなコンパイラ装置として実現することができるだけでなく、このようなコンパイラ装置が備える手段をステップとするプログラムとして実現したり、コンパイラへの指示が含まれたソースプログラムとして実現することもできる。そして、そのようなプログラムは、ＣＤ−ＲＯＭ等の記録媒体やインターネット等の伝送媒体を介して広く流通させることができるのは言うまでもない。
【００１３】
【発明の実施の形態】
以下、本発明に係るコンパイラの実施の形態について図面を用いて詳細に説明する。
本実施の形態におけるコンパイラは、Ｃ言語等の高級言語で記述されたソースプログラムを特定のプロセッサが実行できる機械語プログラムに翻訳するクロスコンパイラであり、生成する機械語プログラムのコードサイズや実行時間に関する最適化の指示をきめ細かく指定することができるという特徴を有する。
【００１４】
まず、本実施の形態におけるコンパイラの対象となるプロセッサの一例について、図１〜図３６を用いて説明する。
【００１５】
本実施の形態におけるコンパイラの対象となるプロセッサは、例えば、通常のマイコンに比べて実行可能な命令の並列性が高く、ＡＶメディア系信号処理技術分野をターゲットとして開発された汎用プロセッサである。
【００１６】
図１は、そのようなプロセッサの概略ブロック図の一例である。このプロセッサ１は、命令制御部１０、デコード部２０、レジスタファイル３０、演算部４０、Ｉ／Ｆ部５０、命令メモリ部６０、データメモリ部７０、拡張レジスタ部８０及びＩ／Ｏインターフェース部９０から構成される。演算部４０は、ＳＩＭＤ型命令の演算を実行する算術論理・比較演算器４１〜４３、乗算・積和演算器４４、バレルシフタ４５、除算器４６及び変換器４７からなる。乗算・積和演算器４４は、ビット精度を落とさないように、最長で６５ビットで累算する。また、乗算・積和演算器４４は、算術論理・比較演算器４１〜４３と同様、ＳＩＭＤ型命令の実行が可能である。更に、このプロセッサ１は、算術論理・比較演算命令が最大３並列実行可能である。
【００１７】
図２は、算術論理・比較演算器４１〜４３の概略図を示す。算術論理・比較演算器４１〜４３それぞれは、ＡＬＵ部４１ａ、飽和処理部４１ｂ及びフラグ部４１ｃから構成される。ＡＬＵ部４１ａは、算術演算器、論理演算器、比較器、ＴＳＴ器からなる。対応する演算データのビット幅は、８ビット（演算器を４並列で使用）、１６ビット（演算器を２並列で使用）、３２ビットである（全演算器で３２ビットデータ処理）。更に算術演算結果に対しては、フラグ部４１ｃ等により、オーバーフローの検出とコンディションフラグの生成が行われる。各演算器、比較器、ＴＳＴ器の結果は、算術右シフト、飽和処理部４１ｂによる飽和、最大・最小値検出、絶対値生成処理が行われる。
【００１８】
図３は、バレルシフタ４５の構成を示すブロック図である。バレルシフタ４５は、セレクタ４５ａ、４５ｂ、上位バレルシフタ４５ｃ、下位バレルシフタ４５ｄ及び飽和処理部４５ｅから構成され、データの算術シフト（２の補数体系のシフト）または、論理シフト（符号なしシフト）を実行する。通常は、３２ビットもしくは、６４ビットのデータを入出力としている。レジスタ３０ａ、３０ｂに格納された被シフトデータに対して、別のレジスタまたは即値でシフト量が指定される。データは、左６３ビット〜右６３ビットの算術または論理シフトが行われ、入力ビット長で出力される。
【００１９】
また、バレルシフタ４５は、ＳＩＭＤ型命令に対して、８、１６、３２、６４ビットのデータをシフトすることができる。例えば、８ビットデータのシフトを４並列で処理することができる。
【００２０】
算術シフトは、２の補数体系のシフトであり、加算や減算時の小数点の位置合わせや、２のべき乗の乗算（２、２の２乗、２の（−１）乗、２の（−２）乗倍など）等のために行われる。
【００２１】
図４は、変換器４７の構成を示すブロック図である。変換器４７は、飽和ブロック（ＳＡＴ）４７ａ、ＢＳＥＱブロック４７ｂ、ＭＳＫＧＥＮブロック４７ｃ、ＶＳＵＭＢブロック４７、ＢＣＮＴブロック４７ｅ及びＩＬブロック４７ｆから構成される。
【００２２】
飽和ブロック（ＳＡＴ）４７ａは、入力データに対する飽和処理を行う。３２ビットデータを飽和処理するブロックを２つ持つことにより、２並列のＳＩＭＤ型命令をサポートする。
【００２３】
ＢＳＥＱブロック４７ｂは、ＭＳＢから連続する０か１をカウントする。
ＭＳＫＧＥＮブロック４７ｃは、指定されたビット区間を１、それ以外を０として出力する。
ＶＳＵＭＢブロック４７ｄは、入力データを指定されたビット幅に区切り、その総和を出力する。
ＢＣＮＴブロック４７ｅは、入力データで１となっているビットの数をカウントする。
ＩＬブロック４７ｆは、入力データを指定されたビット幅に区切り、各データブロックを入れ換えた値を出力する。
【００２４】
図５は、除算器４６の構成を示すブロック図である。除算器４６は、被除数を６４ビット、除数を３２ビットとし、商と剰余を３２ビットずつ出力する。商と剰余を求めるまでに３４サイクルを必要とする。符号付き、符号なし、両方のデータを扱うことが可能である。ただし、被除数と除数において符号の有無の設定は共通とする。その他、オーバーフローフラグ、０除算フラグを出力する機能を有する。
【００２５】
図６は、乗算・積和演算器４４の構成を示すブロック図である。乗算・積和演算器４４は、２つの３２ビット乗算器（ＭＵＬ）４４ａ、４４ｂ、３つの６４ビット加算器（Ａｄｄｅｒ）４４ｃ〜４４ｅ、セレクタ４４ｆ及び飽和処理部（Ｓａｔｕｒａｔｉｏｎ）４４ｇから構成され、以下の乗算、積和演算を行う。
・３２×３２ビットのｓｉｇｎｅｄの乗算、積和、積差演算
・３２×３２ビットのｕｎｓｉｇｎｅｄの乗算
・１６×１６ビットの２並列のｓｉｇｎｅｄの乗算、積和、積差演算
・３２×１６ビットの２並列のｓｉｇｎｅｄの乗算、積和、積差演算
【００２６】
これらの演算を整数、固定小数点フォーマット（ｈ１、ｈ２、ｗ１、ｗ２）のデータに対して行う。また、これらの演算に対し、丸め、飽和を行う。
【００２７】
図７は、命令制御部１０の構成を示すブロック図である。命令制御部１０は、命令キャッシュ１０ａ、アドレス管理部１０ｂ、命令バッファ１０ｃ〜１０ｅ、ジャンプバッファ１０ｆ及びローテーション部（ｒｏｔａｔｉｏｎ）１０ｇから構成され、通常時及び分岐時の命令供給を行う。１２８ビットの命令バッファを３つ（命令バッファ１０ｃ〜１０ｅ）持つことにより、最大並列実行数に対応している。分岐処理に関しては、分岐実行前に、ジャンプバッファ１０ｆ等を介して、後述するＴＡＲレジスタに予め分岐先アドレスを格納する（ｓｅｔｔａｒ命令）。ＴＡＲレジスタに格納された分岐先アドレスを使用して、分岐を行う。
【００２８】
なお、本実施の形態におけるコンパイラの対象となるプロセッサ１は、例えば、ＶＬＩＷアーキテクチャを持つプロセッサである。ここで、ＶＬＩＷアーキテクチャとは、１つの命令語中に複数の命令（ロード、ストア、演算、分岐など）を格納し、それらを全て同時に実行するアーキテクチャである。プログラマは、並列実行可能な命令を１つの発行グループとして記述することによって、その発行グループを並列処理させることができる。本明細書では、発行グループの区切りを”；；”で示す。以下に表記例を示す。
（例１）
ｍｏｖ　ｒ１，　０ｘ２３；；
この命令記述は、命令ｍｏｖのみを実行することを意味する。
（例２）
ｍｏｖ　ｒ１，　０ｘ３８
ａｄｄ　ｒ０，　ｒ１，　ｒ２
ｓｕｂ　ｒ３，　ｒ１，　ｒ２；；
これらの命令記述は、命令ｍｏｖ、ａｄｄ、ｓｕｂを３並列で実行することを意味する。
【００２９】
命令制御部１０は、発行グループを識別し、デコード部２０に送る。デコード部２０では、発行グループの命令を解析し、必要な資源を制御する。
【００３０】
次に、このようなプロセッサ１が備えるレジスタについて説明する。
プロセッサ１のレジスタセットは、以下の表１に示される通りである。
【表１】
2004038597.tif 000003
【００３１】
また、このようなプロセッサ１のフラグセット（後述する条件フラグレジスタ等で管理されるフラグ）は、以下の表２に示される通りである。
【表２】
2004038597.tif 000004
【００３２】
図８は、汎用レジスタ（Ｒ０〜Ｒ３１）３０ａの構造を示す図である。汎用レジスタ（Ｒ０〜Ｒ３１）３０ａは、実行対象となっているタスクのコンテキストの一部を構成し、データまたはアドレスを格納する３２ビットのレジスタ群である。なお、汎用レジスタＲ３０およびＲ３１は、それぞれグローバルポインタ、スタックポインタとして、ハードウェアが使用する。
【００３３】
図９は、リンクレジスタ（ＬＲ）３０ｃの構造を示す図である。なお、このリンクレジスタ（ＬＲ）３０ｃと関連して、このプロセッサ１は、図示されていない退避レジスタ（ＳＶＲ）も備える。リンクレジスタ（ＬＲ）３０ｃは、関数コール時のリターンアドレスを格納する３２ビットのレジスタである。なお、退避レジスタ（ＳＶＲ）は、関数コール時の条件フラグレジスタのコンディションフラグ（ＣＦＲ．ＣＦ）を退避する１６ビットのレジスタである。リンクレジスタ（ＬＲ）３０ｃは、後述する分岐レジスタ（ＴＡＲ）と同様に、ループ高速化にも使用される。下位１ビットは常に０が読み出されるが、書き込み時には０を書き込む必要がある。
【００３４】
例えば、ｃａｌｌ（ｂｒｌ，ｊｍｐｌ）命令を実行した場合には、このプロセッサ１は、リンクレジスタ（ＬＲ）３０ｃに戻りアドレスを退避し、退避レジスタ（ＳＶＲ）にコンディションフラグ（ＣＦＲ．ＣＦ）を退避する。また、ｊｍｐ命令を実行した場合には、リンクレジスタ（ＬＲ）３０ｃから戻りアドレス（分岐先アドレス）を取り出し、プログラムカウンタ（ＰＣ）を復帰させる。さらに、ｒｅｔ（ｊｍｐｒ）命令を実行した場合には、リンクレジスタ（ＬＲ）３０ｃから分岐先アドレス（戻りアドレス）を取り出し、プログラムカウンタ（ＰＣ）に格納（復帰）する。さらに、退避レジスタ（ＳＶＲ）からコンディションフラグを取り出し、条件フラグレジスタ（ＣＦＲ）３２のコンディションンフラグ領域ＣＦＲ．ＣＦに格納（復帰）する。
【００３５】
図１０は、分岐レジスタ（ＴＡＲ）３０ｄの構造を示す図である。分岐レジスタ（ＴＡＲ）３０ｄは、分岐ターゲットアドレスを格納する３２ビットのレジスタである。主に、ループの高速化に用いられる。下位１ビットは常に０が読み出されるが、書き込み時には０を書き込む必要がある。
【００３６】
例えば、ｊｍｐ，ｊｌｏｏｐ命令を実行した場合には、プロセッサ１は、分岐レジスタ（ＴＡＲ）３０ｄから分岐先アドレスを取り出し、プログラムカウンタ（ＰＣ）に格納する。分岐レジスタ（ＴＡＲ）３０ｄに格納されたアドレスの命令が分岐用命令バッファに格納されている場合は、分岐ペナルティが０になる。分岐レジスタ（ＴＡＲ）３０ｄにループの先頭アドレスを格納しておくことでループを高速化することができる。
【００３７】
図１１は、プログラム状態レジスタ（ＰＳＲ）３１の構造を示す図である。プログラム状態レジスタ（ＰＳＲ）３１は、実行対象となっているタスクのコンテキストの一部を構成し、以下に示されるプロセッサ状態情報を格納する３２ビットのレジスタである。
【００３８】
ビットＳＷＥ：ＶＭＰ（Ｖｉｒｔｕａｌ　Ｍｕｌｔｉ−Ｐｒｏｃｅｓｓｏｒ）のＬＰ（Ｌｏｇｉｃａｌ　Ｐｒｏｃｅｓｓｏｒ）切替えイネーブルを示す。「０」はＬＰ切替え不許可を示し、「１」はＬＰ切替え許可を示す。
【００３９】
ビットＦＸＰ：固定小数点モードを示す。「０」はモード０を示し、「１」はモード１を示す。
ビットＩＨ：割込み処理フラグであり、マスカブル割込み処理中であることを示す。「１」は割込み処理中であることを示し、「０」は割込み処理中でないことを示す。割込みが発生すると自動的にセットされる。ｒｔｉ命令で割込みから復帰したところが、他の割込み処理中かプログラム処理中であるのかを見分けるために使用される。
【００４０】
ビットＥＨ：エラーまたはＮＭＩを処理中であることを示すフラグである。「０」はエラー／ＮＭＩ割込み処理中でないことを示し、「１」はエラー／ＮＭＩ割込み処理中であることを示す。ＥＨ＝１のとき、非同期エラーまたはＮＭＩが発生した場合は、マスクされる。また、ＶＭＰイネーブル時はＶＭＰのプレート切り替えがマスクされる。
【００４１】
ビットＰＬ［１：０］：特権レベルを示す。「００」は特権レベル０、つまり、プロセッサアブストラクションレベルを示し、「０１」は特権レベル１（設定できない）を示し、「１０」は特権レベル２、つまり、システムプログラムレベルを示し、「１１」は特権レベル３、つまり、ユーザプログラムレベルを示す。
【００４２】
ビットＬＰＩＥ３：ＬＰ固有割込み３イネーブルを示す。「１」は割込み許可を示し、「０」は割込み不許可を示す。
ビットＬＰＩＥ２：ＬＰ固有割込み２イネーブルを示す。「１」は割込み許可を示し、「０」は割込み不許可を示す。
ビットＬＰＩＥ１：ＬＰ固有割込み１イネーブルを示す。「１」は割込み許可を示し、「０」は割込み不許可を示す。
ビットＬＰＩＥ０：ＬＰ固有割込み０イネーブルを示す。「１」は割込み許可を示し、「０」は割込み不許可を示す。
ビットＡＥＥ：ミスアライメント例外イネーブルを示す。「１」はミスアライメント例外許可を示し、「０」はミスアライメント例外不許可を示す。
ビットＩＥ：レベル割込みイネーブルを示す。「１」はレベル割込み許可を示し、「０」はレベル割込み不許可を示す。
ビットＩＭ［７：０］：割込みマスクを示す。レベル０〜７まで定義され、個々のレベルでマスクすることができる。レベル０が最も高いレベルとなる。ＩＭによりマスクされていない割込み要求のうち最も高いレベルを持った割込み要求のみがプロセッサ１に受理される。割込み要求を受理すると受理したレベル以下のレベルはハードウェアで自動的にマスクされる。ＩＭ［０］はレベル０のマスクであり、ＩＭ［１］はレベル１のマスクであり、ＩＭ［２］はレベル２のマスクであり、ＩＭ［３］はレベル３のマスクであり、ＩＭ［４］はレベル４のマスクであり、ＩＭ［５］はレベル５のマスクであり、ＩＭ［６］はレベル６のマスクであり、ＩＭ［７］はレベル７のマスクである。
ｒｅｓｅｒｖｅｄ：予約ビットを示す。常に０が読み出される。書き込む時は０を書き込む必要がある。
【００４３】
図１２は、条件フラグレジスタ（ＣＦＲ）３２の構造を示す図である。条件フラグレジスタ（ＣＦＲ）３２は、実行対象となっているタスクのコンテキストの一部を構成する３２ビットのレジスタであり、コンディションフラグ（条件フラグ）、オペレーションフラグ（演算フラグ）、ベクタコンディションフラグ（ベクタ条件フラグ）、演算命令用ビット位置指定フィールド、ＳＩＭＤデータアライン情報フィールドから構成される。
【００４４】
ビットＡＬＮ［１：０］：アラインモードを示す。ｖａｌｎｖｃ命令のアラインモードを設定する。
ビットＢＰＯ［４：０］：ビットポジションを示す。ビット位置指定の必要な命令で使用する。
ビットＶＣ０〜ＶＣ３：ベクタ条件フラグである。ＬＳＢ側のバイトあるいはハーフワードから順にＶＣ０に対応し、ＭＳＢ側がＶＣ３に対応する。
ビットＯＶＳ：オーバーフローフラグ（サマリー）である。飽和発生やオーバーフロー検出でセットされる。検出されなかった場合は、命令実行前の値を保持する。クリアはソフトで行う必要がある。
ビットＣＡＳ：キャリーフラグ（サマリー）である。ａｄｄｃ命令でキャリーまたはｓｕｂｃ命令でボローが発生した場合セットされる。ａｄｄｃ命令でキャリーもしくはｓｕｂｃ命令でボローが発生しなかった場合は、命令実行前の値を保持する。クリアはソフトで行う必要がある。
ビットＣ０〜Ｃ７：コンディションフラグである。条件付き実行命令における条件（ＴＲＵＥ／ＦＡＬＳＥ）を示す。条件付き命令の条件とビットＣ０〜Ｃ７との対応は、命令に含まれるプレディケート・ビットによって決定される。なお、フラグＣ７は常に値が１である。フラグＣ７へのＦＡＬＳＥ条件の反映（０書き込み）は無視される。
ｒｅｓｅｒｖｅｄ：予約ビットを示す。常に０が読み出される。書き込む時は０を書き込む必要がある。
【００４５】
図１３は、アキュムレータ（Ｍ０，Ｍ１）３０ｂの構造を示す図である。このアキュムレータ（Ｍ０，Ｍ１）３０ｂは、実行対象となっているタスクのコンテキストの一部を構成し、図１３（ａ）に示される３２ビットレジスタＭＨ０−ＭＨ１（乗除算・積和用レジスタ（上位３２ビット））と、図１３（ｂ）に示される３２ビットレジスタＭＬ０−ＭＬ１乗除算・積和用レジスタ（下位３２ビット）とからなる。
【００４６】
レジスタＭＨ０−ＭＨは、乗算命令では結果の上位３２ビットを格納するのに使用される。積和命令ではアキュムレータの上位３２ビットとして使用される。また、ビットストリームを取り扱う場合に汎用レジスタと組み合わせて使用することができる。レジスタＭＬ０−ＭＬ１は、乗算命令では結果の下位３２ビットを格納するのに使用される。積和命令ではアキュムレータの下位３２ビットとして使用される。
【００４７】
図１４は、プログラムカウンタ（ＰＣ）３３の構造を示す図である。このプログラムカウンタ（ＰＣ）３３は、実行対象となっているタスクのコンテキストの一部を構成し、実行中の命令のアドレスを保持する３２ビットのカウンタである。下位１ビットは常に０が格納される。
【００４８】
図１５は、ＰＣ退避用レジスタ（ＩＰＣ）３４の構造を示す図である。このＰＣ退避用レジスタ（ＩＰＣ）３４は、実行対象となっているタスクのコンテキストの一部を構成する３２ビットのレジスタであり、下位１ビットは常に０が読み出されるが、書き込み時には０を書き込む必要がある。
【００４９】
図１６は、ＰＳＲ退避用レジスタ（ＩＰＳＲ）３５の構造を示す図である。このＰＳＲ退避用レジスタ（ＩＰＳＲ）３５は、実行対象となっているタスクのコンテキストの一部を構成し、プログラム状態レジスタ（ＰＳＲ）３１を退避するための３２ビットのレジスタであり、プログラム状態レジスタ（ＰＳＲ）３１の予約ビットに対応する部分は常に０が読み出されるが、書き込み時には０を書き込む必要がある。
【００５０】
次に、本実施の形態におけるコンパイラの対象となるプロセッサ１のメモリ空間について説明する。例えば、プロセッサ１では、４ＧＢのリニアなメモリ空間を３２分割し、１２８ＭＢ単位の空間に命令ＳＲＡＭ（Ｓｔａｔｉｃ　ＲＡＭ）とデータＳＲＡＭが割り当てられる。この１２８ＭＢの空間を１ブロックとして、ＳＡＲ（ＳＲＡＭ　Ａｒｅａ　Ｒｅｇｉｓｔｅｒ）にアクセスしたいブロックを設定する。アクセスされたアドレスがＳＡＲで設定された空間である場合は、直接命令ＳＲＡＭ／データＳＲＡＭに対してアクセスを行うが、ＳＡＲで設定された空間でない場合は、バスコントローラ（ＢＣＵ）に対してアクセス要求を出する。ＢＣＵにはオン・チップ・メモリ（ＯＣＭ）、外部メモリ、外部デバイス、Ｉ／Ｏポート等が接続されており、それらのデバイスに対して読み書きを行うことができる。
【００５１】
図１７は、本実施の形態におけるコンパイラの対象となるプロセッサ１のパイプライン動作を示すタイミング図である。このプロセッサ１は、本図に示されるように、例えば、基本的に命令フェッチ、命令割り当て（ディスパッチ）、デコード、実行、書き込みの５段パイプラインで構成されている。
【００５２】
図１８は、このようなプロセッサ１による命令実行時の各パイプライン動作を示すタイミング図である。命令フェッチステージでは、プログラムカウンタ（ＰＣ）３３で指定されるアドレスの命令メモリをアクセスし、命令を命令バッファ１０ｃ〜１０ｅ等に転送する。命令割り当てステージでは、分岐系命令に対する分岐先アドレス情報の出力、入力レジスタ制御信号の出力、可変長命令の割り当てを行い、命令をインストラクションレジスタ（ＩＲ）に転送する。デコードステージでは、ＩＲをデコード部２０に入力し、演算器制御信号、メモリアクセス信号を出力する。実行ステージでは、演算を実行、演算結果をデータメモリか汎用レジスタ（Ｒ０〜Ｒ３１）３０ａに出力する。書き込みステージでは、データ転送、演算結果を汎用レジスタに格納する。
【００５３】
本実施の形態におけるコンパイラの対象となるプロセッサ１は、例えば、ＶＬＩＷアーキテクチャにより上記の処理を最高３並列で行うことができる。したがって、図１８に示された動作については、本プロセッサ１は、図１９に示されるタイミングで並列に実行する。
【００５４】
次に、以上のように構成されたプロセッサ１の命令セットの例について説明する。
【００５５】
以下の表３〜表５は、本実施の形態におけるコンパイラの対象となるプロセッサ１が実行する命令をカテゴリー別に分類した表である。
【表３】
2004038597.tif 000005
【表４】
2004038597.tif 000006
【表５】
2004038597.tif 000007
【００５６】
なお、表中の「演算器」は、その命令が使用する演算器を示す。演算器の略号の意味は次の通りである。つまり、「Ａ」はＡＬＵ命令、「Ｂ」は分岐命令、「Ｃ」は変換命令、「ＤＩＶ」は除算命令、「ＤＢＧＭ」はデバッグ命令、「Ｍ」はメモリアクセス命令、「Ｓ１」、「Ｓ２」はシフト命令、「Ｘ１」、「Ｘ２」は乗算命令を意味する。
【００５７】
図２０は、このようなプロセッサ１が実行する命令のフォーマットの例を示す図である。そのフォーマットには、図２０（ａ）に示される１６ビット命令フォーマットと、図２０（ｂ）に示される３２ビット命令フォーマットとがある。
【００５８】
なお、図中における略号の意味は次の通りである。つまり、「Ｅ」はエンドビット（並列実行の境界）、「Ｆ」はフォーマットビット（００、０１、１０：１６ビット命令フォーマット、１１：３２ビット命令フォーマット）、「Ｐ」はプレディケート（実行条件：８個の条件フラグＣ０〜Ｃ７のいずれかを指定）、「ＯＰ」はオペコードフィールド、「Ｒ」はレジスタフィールド、「Ｉ」は即値フィールド、「Ｄ」ディスプースメントフィールドを意味する。なお、「Ｅ」フィールドはＶＬＩＷに特有のもので、Ｅ＝０の命令は次の命令と並列に実行される。つまり、「Ｅ」フィールドによって並列度が可変のＶＬＩＷを実現している。
【００５９】
図２１〜図３６は、プロセッサ１が実行する命令の概略的な機能を説明する図である。つまり、図２１は、カテゴリー「ＡＬＵａｄｄ（加算）系」に属する命令を説明する図であり、図２２は、カテゴリー「ＡＬＵｓｕｂ（減算）系」に属する命令を説明する図であり、図２３は、カテゴリー「ＡＬＵｌｏｇｉｃ（論理演算）系ほか」に属する命令を説明する図であり、図２４は、カテゴリー「ＣＭＰ（比較演算）系」に属する命令を説明する図であり、図２５は、カテゴリー「ｍｕｌ（乗算）系」に属する命令を説明する図であり、図２６は、カテゴリー「ｍａｃ（積和演算）系」に属する命令を説明する図であり、図２７は、カテゴリー「ｍｓｕ（積差演算）系」に属する命令を説明する図であり、図２８は、カテゴリー「ＭＥＭｌｄ（メモリ読み出し）系」に属する命令を説明する図であり、図２９は、カテゴリー「ＭＥＭｓｔｏｒｅ（メモリ書き出し）系」に属する命令を説明する図であり、図３０は、カテゴリー「ＢＲＡ（分岐）系」に属する命令を説明する図であり、図３１は、カテゴリー「ＢＳａｓｌ（算術バレルシフト）系ほか」に属する命令を説明する図であり、図３２は、カテゴリー「ＢＳｌｓｒ（論理バレルシフト）系ほか」に属する命令を説明する図であり、図３３は、カテゴリー「ＣＮＶｖａｌｎ（算術変換）系」に属する命令を説明する図であり、図３４は、カテゴリー「ＣＮＶ（一般変換）系」に属する命令を説明する図であり、図３５は、カテゴリー「ＳＡＴｖｌｐｋ（飽和処理）系」に属する命令を説明する図であり、図３６は、カテゴリー「ＥＴＣ（その他）系」に属する命令を説明する図である。
【００６０】
これらの図において、項目「ＳＩＭＤ」は、その命令の型（ＳＩＳＤ（ＳＩＮＧＬＥ）かＳＩＭＤかの区別）を示し、項目「サイズ」は、演算の対象となる個々のオペランドのサイズを示し、項目「命令」は、その命令のオペコードを示し、項目「オペランド」は、その命令のオペランドを示し、項目「ＣＦＲ」は、条件フラグレジスタの変化を示し、項目「ＰＳＲ」は、プロセッサ状態レジスタの変化を示し、項目「代表的な動作」は、動作の概要を示し、項目「演算器」は、使用される演算器を示し、項目「３１１６」は、命令のサイズを示す。
【００６１】
以下に、後述する具体例で使用される主な命令についてのプロセッサ１の動作を説明する。
ｌｄ　Ｒｂ，（Ｒａ，Ｄ１０）
レジスタＲａにディスプレースメント値（Ｄ１０）を加算したアドレスからワードデータをレジスタＲｂにロードする。
ｌｄｈ　Ｒｂ，（Ｒａ＋）Ｉ９
レジスタＲａが示すアドレスからハーフワードデータを符号拡張してロードする。さらに、レジスタＲａに即値（Ｉ９）を加算し、レジスタＲａに格納する。
ｌｄｐ　Ｒｂ：Ｒｂ＋１，（Ｒａ＋）
レジスタＲａが示すアドレスから　レジスタＲｂとＲｂ＋１に２　つのワードデータを符号拡張してロードする。さらに、レジスタＲａに　８　を加算し、レジスタＲａに格納する。
【００６２】
ｌｄｈｐ　Ｒｂ：Ｒｂ＋１，　（Ｒａ＋）
レジスタＲａが示すアドレスから　２　つのハーフワードデータを符号拡張してロードする。さらに、レジスタＲａに　４　を加算し、レジスタＲａに格納する。
ｓｅｔｌｏ　Ｒａ，Ｉ１６
レジスタＲａに即値（Ｉ１６）を符号拡張して格納する。
ｓｅｔｈｉ　Ｒａ，Ｉ１６
レジスタＲａの上位　１６　ｂｉｔに即値（Ｉ１６）を格納する。レジスタＲａの下位　１６　ｂｉｔには影響しない。
【００６３】
ｌｄ　Ｒｂ，（Ｒａ）
レジスタＲａが示すアドレスからワードデータをレジスタＲｂにロードする。
ａｄｄ　Ｒｃ，Ｒａ，Ｒｂ
レジスタＲａとＲｂを加算し、レジスタＲｂに格納する。
ａｄｄｕ　Ｒｂ，ＧＰ，Ｉ１３
レジスタＧＰに即値（Ｉ１３）を加算し、レジスタＲｂに格納する。
ｓｔ　（ＧＰ，Ｄ１３），Ｒｂ
レジスタＧＰにディスプレースメント値（Ｄ１３）を加算したアドレスに、レジスタＲｂに格納されたハーフワードデータをストアする。
【００６４】
ｓｔｈ　（Ｒａ＋）Ｉ９，Ｒｂ
レジスタＲａが示すアドレスに、レジスタＲｂに格納されたハーフワードデータをストアする。さらに、レジスタＲａに即値（Ｉ９）を加算し、レジスタＲａに格納する。
ｓｔｐ　（Ｒａ＋），Ｒｂ：Ｒｂ＋１
レジスタＲａが示すアドレスに、レジスタＲｂとＲｂ＋１に格納された　２　つのワードデータをストアする。さらに、レジスタＲａに　８　を加算し、レジスタＲａに格納する。
ｒｅｔ
サブルーチンコールからのリターンに使用する。ＬＲに格納されているアドレスに分岐する。ＳＶＲ．ＣＦをＣＦＲ．ＣＦに転送する。
【００６５】
ｍｏｖ　Ｒａ，Ｉ１６
レジスタＲａに値（Ｉ１６）を符号拡張して格納する。
ｓｅｔｔａｒ　Ｃ６，Ｄ９
以下の処理を行う。　（１）　ＰＣとディスプレースメント値（Ｄ９）を加算したアドレスを　分岐レジスタＴＡＲに格納する。　（２）　そのアドレスの命令をフェッチして分岐用命令バッファに格納する。　（３）　Ｃ６を　１　にセットする。
ｓｅｔｔａｒ　Ｃ６，Ｃｍ，Ｄ９
以下の処理を行う。　（１）　ＰＣとディスプレースメント値（Ｄ９）を加算したアドレスを　分岐レジスタＴＡＲに格納する。　（２）　そのアドレスの命令をフェッチして分岐用命令バッファに格納する。　（３）　Ｃ６を　１　に、Ｃｍを　０　にセットする。
【００６６】
ｓｅｔｔａｒ　Ｃ６，Ｃ２：Ｃ４，Ｄ９
以下の処理を行う。　（１）　ＰＣとディスプレースメント値（Ｄ９）を加算したアドレスを　分岐レジスタＴＡＲに格納する。　（２）　そのアドレスの命令をフェッチして分岐用命令バッファに格納する。　（３）　Ｃ４とＣ６を　１　に、Ｃ２とＣ３を　０　にセットする。
ｊｌｏｏｐ　Ｃ６，ＴＡＲ，Ｒａ２，−１
ループで使用する。以下の処理を行う。　（１）　レジスタＲａ２に　−１　を加算し、レジスタＲａ２に格納する。レジスタＲａ２が　０　より小さくなるとＣ６に　０　をセットする。　（２）　分岐レジスタＴＡＲが示すアドレスにジャンプする。
ｊｌｏｏｐ　Ｃ６，Ｃｍ，ＴＡＲ，Ｒａ２，−１
ループで使用する。以下の処理を行う。　（１）　Ｃｍ　に　１　をセットする。　（２）　レジスタＲａ２に　−１　を加算し、レジスタＲａ２に格納する。レジスタＲａ２が　０　より小さくなるとＣ６に　０　をセットする。　（３）　分岐レジスタＴＡＲが示すアドレスにジャンプする。
【００６７】
ｊｌｏｏｐ　Ｃ６，Ｃ２：Ｃ４，ＴＡＲ，Ｒａ２，−１
ループで使用する。以下の処理を行う。（１）　Ｃ３をＣ２に転送し、Ｃ４をＣ３とＣ６に転送する。（２）　レジスタＲａ２に　−１　を加算し、レジスタＲａ２に格納する。レジスタＲａ２が　０　より小さくなるとＣ４に　０　をセットする。（３）　分岐レジスタＴＡＲが示すアドレスにジャンプする。
ｍｕｌ　Ｍｍ，Ｒｂ，Ｒａ，Ｉ８
レジスタＲａと即値（Ｉ８）を符号付乗算し、結果をレジスタＭｍとレジスタＲｂに格納する。
ｍａｃ　Ｍｍ，Ｒｃ，Ｒａ，Ｒｂ，Ｍｎ
レジスタＲａとＲｂを整数乗算し、レジスタＭｎと加算する。結果をレジスタＭｍとレジスタＲｃに格納する。
【００６８】
ｌｍａｃ　Ｍｍ，Ｒｃ，Ｒａ，Ｒｂ，Ｍｎ
レジスタＲｂをハーフワードベクタ形式で扱う。レジスタＲａとＲｂの下位　１６　ｂｉｔを整数乗算し、レジスタＭｎと加算する。結果をレジスタＭｍとレジスタＲｃに格納する。
ｊｌｏｏｐ　Ｃ６，Ｃ２：Ｃ４，ＴＡＲ，Ｒａ２，−１
ループで使用する。以下の処理を行う。（１）　Ｃ３をＣ２に転送し、Ｃ４をＣ３とＣ６に転送する。（２）　レジスタＲａ２に　−１　を加算し、レジスタＲａ２に格納する。レジスタＲａ２が　０　より小さくなるとＣ４に　０　をセットする。（３）　分岐レジスタＴＡＲが示すアドレスにジャンプする。
ａｓｒ　Ｒｃ，Ｒａ，Ｒｂ
レジスタＲａをＲｂが示すビット数だけ算術右シフトする。レジスタＲｂは±３１　以内に飽和され、負の場合は算術左シフトになる。
ｂｒ　Ｄ９
現在のＰＣに、ディスプレースメント値（Ｄ９）を加算し、そのアドレスに分岐する。
【００６９】
ｊｍｐｆ　ＴＡＲ
分岐レジスタＴＡＲに格納されているアドレスに分岐する。
ｃｍｐＣＣ　Ｃｍ，Ｒａ，Ｉ５
ＣＣ　には次のＣＣ比較条件を記述可能である。
ｅｑ／ｎｅ／ｇｔ／ｇｅ／ｇｔｕ／ｇｅｕ／ｌｅ／ｌｔ／ｌｅｕ／ｌｔｕ
ＣＣがｅｑ／ｎｅ／ｇｔ／ｇｅ／ｌｅ／ｌｔの場合、Ｉ５は符号付きの値で、符号拡張して比較する。ＣＣがｇｔｕ／ｇｅｕ／ｌｅｕ／ｌｔｕの場合、Ｉ５は符号なしの値である。
【００７０】
［コンパイラ］
次に、以上のプロセッサ１をターゲットとする本実施の形態におけるコンパイラについて説明する。
【００７１】
図３７は、本実施の形態におけるコンパイラ１００の構成を示す機能ブロック図である。このコンパイラ１００は、Ｃ言語等の高級言語で記述指定されたソースプログラム１０１を、上述のプロセッサ１をターゲットプロセッサとする機械語プログラム１０２に変換するクロスコンパイラであり、パーソナルコンピュータ等のコンピュータ上で実行されるプログラムによって実現され、大きく分けて、解析部１１０と、最適化部１２０と、出力部１３０とから構成される。
【００７２】
解析部１１０は、コンパイルの対象となるソースプログラム１０１及びこのコンパイラ１００に対するユーザからの指示等を字句解析することによって、コンパイラ１００に対する指示（オプション及びプラグマ）については最適化部１２０や出力部１３０に伝達し、コンパイルの対象となるプログラムについては内部形式データに変換したりする。
【００７３】
なお、「オプション」とは、コンパイラ１００を起動する際に、コンパイルの対象となるソースプログラム１０１の指定とともに、ユーザが任意に指定することができるコンパイラ１００への指示であり、生成する機械語プログラム１０２のコードサイズ及び実行時間を最適化するための指示等が含まれる。例えば、ユーザは、ソースプログラム１０１「ｓａｍｐｌｅ．ｃ」をコンパイルするときに、コマンド「ａｍｍｍｐ−ｃｃ」を用いて、コンピュータ上で、
ｃ：￥＞ａｍｍｍｐ−ｃｃ　−ｏ　−ｍａｘ−ｇｐ−ｄａｔａｓｉｚｅ＝４０　ｓａｍｐｌｅ．ｃ
と入力することができる。このコマンドにおける付加的な指示「−ｏ」及び「−ｍａｘ−ｇｐ−ｄａｔａｓｉｚｅ＝４０」がオプションである。このようなオプションによる指示は、ソースプログラム１０１全体に対する指示として扱われる。
【００７４】
また、「プラグマ（又は、プラグマ指令）」とは、ソースプログラム１０１中にユーザが任意に指定（配置）することができるコンパイラ１００への指示であり、オプションと同様に、生成する機械語プログラム１０２のコードサイズ及び実行時間を最適化するための指示等が含まれる。本実施の形態におけるコンパイラ１００では、「＃ｐｒａｇｍａ」で始まる文字列である。例えば、ユーザは、ソースプログラム１０１中に、
【００７５】
＃ｐｒａｇｍａ＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ　変数名
というステートメントを記述しておくことができる。このステートメントがプラグマ（プラグマ指令）である。このようなプラグマは、オプションと異なり、当該プラグマの直後に配置された変数やループ処理等だけに対する個別的な指示として扱われる。
【００７６】
最適化部１２０は、解析部１１０から出力されたソースプログラム１０１（内部形式データ）に対して、解析部１１０からの指示等に従って、（１）実行速度の向上を優先した最適化、（２）コードサイズの削減を優先した最適化、（３）実行速度とコードサイズの両方の最適化、の中から選択された最適化を実現するための全体的な最適化処理を行うことに加えて、ユーザによるオプション及びプラグマによって指定された個別的な最適化処理を行う処理部（グローバル領域割り付け部１２１、ソフトウェアパイプライニング部１２２、ループアンローリング部１２３、ｉｆ変換部１２４及びペア命令生成部１２５）を有する。
【００７７】
グローバル領域割り付け部１２１は、グローバル領域（共通のデータ領域として関数を超えて参照可能なメモリ領域）に配置する変数（配列）の最大データサイズの指定、グローバル領域に配置させる変数の指定、及び、グローバル領域に配置させない変数の指定に関するオプション及びプラグマに従った最適化処理を行う。
【００７８】
ソフトウェアパイプライニング部１２２は、ソフトウェアパイプライニングを行わない旨の指示、プロログ部・エピログ部が除去できる範囲でソフトウェアパイプライニングを行う旨の指示、及び、プロログ部・エピログ部を除去せずに可能な範囲でソフトウェアパイプライニングを行う旨の指示に関するオプション及びプラグマに従った最適化処理を行う。
【００７９】
ループアンローリング部１２３は、ループアンローリングを行う旨の指示、ループアンローリングを行わない旨の指示、ループが繰り返される最低回数の保証、ループが偶数回繰り返される旨の保証、及び、ループが奇数回繰り返される旨の保証に関するオプション及びプラグマに従った最適化処理を行う。
【００８０】
ｉｆ変換部１２４は、ｉｆ変換を行う旨の指示、及び、ｉｆ変換を行わない旨の指示に関するオプション及びプラグマに従った最適化処理を行う。
【００８１】
ペア命令生成部１２５は、配列と構造体の先頭アドレスのアラインの指定、及び、関数引数のポインタ変数やローカルポインタ変数の指すデータのアライメントの保証に関するプラグマに従った最適化処理を行う。
【００８２】
出力部１３０は、最適化部１２０による最適化処理が施されたソースプログラム１０１に対して、内部形式データを対応する機械語命令に置き換えたり、ラベルやモジュール等のアドレスを解決したりすることで、機械語プログラム１０２を生成し、ファイル等として出力する。
【００８３】
次に、以上のように構成された本実施の形態におけるコンパイラ１００の特徴的な動作について具体例を示しながら説明する。
［グローバル領域割り付け部１２１］
まず、グローバル領域割り付け部１２１の動作とその意義について説明する。グローバル領域割り付け部１２１は、大きく分けて、（１）グローバル領域配置の最大データサイズの指定に関する最適化と、（２）グローバル領域配置の指定に関する最適化とを行う。
【００８４】
まず、（１）グローバル領域配置の最大データサイズの指定に関する最適化について説明する。
上記プロセッサ１には、グローバルポインタレジスタ（ｇｐ；汎用レジスタＲ３０）が用意されており、グローバル領域（以下ｇｐ領域とする）の先頭のアドレスを保持している。ｇｐ領域先頭からのディスプレースメントが最大１４ビットの範囲については、１命令でアクセスすることが可能である。
【００８５】
このｇｐ領域には、外部変数・静的変数等の配列を配置することが可能である。ただし、１命令でアクセスできる範囲を超えた場合、逆に性能が低下するため注意が必要である。
【００８６】
図３８（ａ）は、グローバル領域におけるデータ等の配置例を示す図である。ここでは、配列Ａのデータサイズは、最大データサイズを超えない値であり、配列Ｃのデータサイズは、最大データサイズを超える値である。
【００８７】
ｇｐ領域に実体が収まっている配列Ａへのアクセスは、以下の例のように、１命令で可能である。
例：ｌｄ　　ｒ１，（ｇｐ，＿Ａ　−　．ＭＮ．ｇｐｔｏｐ）；；
なお、この例において、「．ＭＮ．ｇｐｔｏｐ」は、グローバルポインタレジスタと同じアドレスを指すセクション名（ラベル）である。
【００８８】
一方、ｇｐ領域配置の最大データサイズを超える配列Ｃの場合は、ｇｐ領域以外に実体が配置され、配列Ｃのアドレスのみがｇｐ領域に配置される（なお、後述の、＃ｐｒａｇｍａ　＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ指令を使用した場合は、ｇｐ領域に実体もアドレスも格納されない）。
【００８９】
この場合、配列Ｃへのアクセスは、以下の例のように、複数命令必要になる。
例：　ｇｐアドレス間接アクセスの場合
ｌｄ　　ｒ１，（ｇｐ，＿Ｃ＄　−　．ＭＮ．ｇｐｔｏｐ）；；
ｌｄ　　ｒ１，（ｒ１，８）；；
例：　絶対アドレスアクセスの場合
ｓｅｔｌｏ　ｒ０，ＬＯ（＿Ｃ＋８）；；
ｓｅｔｈｉ　ｒ０，ＨＩ（＿Ｃ＋８）；；
ｌｄ　　ｒ０，（ｒ０）；；
【００９０】
なお、図３８（ｂ）に示されるグローバル領域以外の領域における配置例のように、ｇｐ領域の１命令でアクセスできる範囲外に実体が配置された配列Ｚの場合でも、以下のようなコードが生成される。
ｌｄ　　ｒ０，（ｇｐ，＿Ｚ　−　．ＭＮ．ｇｐｔｏｐ）；；
このコードは、１命令でアクセスできる範囲を超えているため、リンカにより複数命令に展開される。よって、１命令アクセスにはならない。
【００９１】
なお、ｇｐ領域の１命令アクセス範囲は、最大１４ビット範囲であるが、オブジェクトの型サイズにより、その範囲は異なる。つまり、８バイト型であれば１４ビット範囲であり、４バイト型であれば１３ビット範囲であり、２バイト型であれば１２ビット範囲であり、１バイト型であれば１１ビット範囲である。
【００９２】
コンパイラ１００は、最大データサイズ（デフォルト３２バイト）以下の配列・構造体の実体をｇｐ領域に配置する。一方、グローバル領域配置の最大データサイズを超えるオブジェクトに関しては、ｇｐ領域以外に実体を配置し、ｇｐ領域にはオブジェクトの先頭アドレスのみを配置する。
【００９３】
ここで、ｇｐ領域に余裕があれば、データサイズ３２バイト以上のオブジェクトも配置させた方が、より良いコードを生成することが可能である。
【００９４】
そこで、以下のオプションを用いることで、ユーザは、この最大データサイズを任意の値に指定することが可能となっている。
・コンパイルオプション
−ｍｍａｘ−ｇｐ−ｄａｔａｓｉｚｅ＝ＮＵＭ
ここで、ＮＵＭは、グローバル領域に配置できる、一つの配列および構造体の最大データサイズの指定バイト（デフォルト３２バイト）である。
【００９５】
図３９は、グローバル領域割り付け部１２１の動作を示すフローチャートである。解析部１１０によって上記オプションが検出された場合には（ステップＳ１００、Ｓ１０１）、グローバル領域割り付け部１２１は、ソースプログラム１０１で宣言されている指定されたサイズ（ＮＵＭバイト）以下の全ての変数（配列）については、グローバル領域に配置し、ＮＵＭバイトを超える変数については、その先頭アドレスだけをグローバル領域に配置し、その実体をグローバル領域以外のメモリ領域に配置する（ステップＳ１０２）。このオプションによって、速度向上とサイズ削減という最適化が可能となる。
【００９６】
なお、この−ｍｍａｘ−ｇｐ−ｄａｔａｓｉｚｅオプションでは、変数個々の配置指定はできない。個々の変数に対してｇｐ領域に配置する／しないを指定するには、後述する　＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令を使用すればよい。また、外部変数・静的変数は、可能な限り１命令アクセス可能なｇｐ領域に配置することが好ましい。さらに、ｅｘｔｅｒｎ　宣言を使用して、他のファイルで定義される外部変数にアクセスする場合は、その外部変数のサイズを省略せずに、明記することが好ましい。例えば、外部変数の定義が、
ｉｎｔ　ａ［８］；
とされている場合、使用するファイルでは、
ｅｘｔｅｒｎ　ｉｎｔ　ａ［８］；
と宣言することが好ましい。
【００９７】
なお、ｅｘｔｅｒｎ　宣言外部変数に　＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令を使用する場合、定義の指定（配置する領域）と使用側の指定（アクセスする方法）を必ず合わせる必要がある。
【００９８】
次に、このようなオプション用いることによる最適化の具体例を示す。
図４０は、最大データサイズを変更した場合の最適化の具体例を示す図である。つまり、デフォルトの状態でコンパイルし、その結果、まだｇｐ領域に空きがあるので、以下のコマンド例のように、最大データサイズを変更してコンパイルした場合における両ケースで得られる生成コードの例が示されている。
ｃ：￥＞ａｍｍｍｐ−ｃｃ　−Ｏ　−ｍｍａｘ−ｇｐ−ｄａｔａｓｉｚｅ＝４０　ｓａｍｐｌｅ．ｃ
【００９９】
ここでは、配列ｃのオブジェクトサイズが、４０バイトであるとする。本図の左欄は、デフォルトの状態でコンパイルされた場合に生成されるコードの例であり、本図の右欄は、最大データサイズを４０に変更してコンパイルされた場合に生成されるコードの例である。なお、本図の最上段、中上段、中下段、最下段は、それぞれ、各欄のタイトル、サンプルプログラム（ソースプログラム１０１）、そこから生成されるコード（機械語プログラム１０２）、その生成コードのサイクル数及びコードサイズを示している（以下、最適化の具体例を示す他の図についても同様）。
【０１００】
本図の左欄の生成コードから分かるように、配列ｃの実体がｇｐ領域以外に配置されているため、複数命令での絶対アドレスアクセスになっている。一方、本図の右欄の生成コードから分かるように、配列ｃの実体がｇｐ領域に置かれるように最大データサイズ（４０）が指定されたので、配列ｃの実体がｇｐ領域に配置され、１命令アクセスでのｇｐ相対アクセスになり、実行速度が向上される。つまり、デフォルトでは、１０サイクルで実行される８バイトのコードが生成されるのに対し、最大データサイズの変更によって、７サイクルで実行される５バイトのコードが生成される。
【０１０１】
もう一つの具体例として、ファイル外定義の外部変数の場合の具体例を図４１に示す。ここでは、ｇｐ領域配置の最大データサイズは４０であるとする。本図の左欄は、ファイル外定義の外部変数に関してサイズ指定がない場合に生成されるコードの例を示し、本図の右欄は、サイズ指定がある場合に生成されるコードの例を示している。
【０１０２】
本図の左欄に示されるように、外部定義配列ａと外部定義配列ｃのサイズが共に不明なので、ｇｐ領域に配置されているのか否かコンパイラ１００では判断できず、複数命令での絶対アドレスアクセスのコードが生成されている。
【０１０３】
一方、本図の右欄に示されるように、配列ａの定義サイズが４０バイト以下なので、ｇｐ領域に実体を配置し、グローバルポインタレジスタ（ｇｐ）を用いて１命令でのｇｐ相対アクセスのコードが生成されている。また、外部定義配列ｃのサイズも明示的に指定されており、ｇｐ領域配置の最大データサイズ以下であるため、配列ｃの実体がｇｐ領域に配置されているものとし、ｇｐ相対アクセスのコードが生成されている。このように、ファイル外定義の外部変数のサイズを指定しない場合には、１０サイクルで実行される１２バイトのコードが生成されるのに対し、最大データサイズの変更と外部変数のサイズ指定とを行った場合には、７サイクルで実行される５バイトのコードが生成される。
【０１０４】
次に、グローバル領域割り付け部１２１による、（２）グローバル領域配置の指定に関する最適化について説明する。
前述の、グローバル領域配置の最大データサイズ指定（　−ｍｍａｘ−ｇｐ−ｄａｔａｓｉｚｅオプション）では、最大データサイズでのみ、ｇｐ領域の配置を指定するため、期待しない変数までｇｐ領域に配置されることがある。
【０１０５】
そこで、変数ごとにｇｐ領域の配置を指定する＃ｐｒａｇｍａ指令が用意されている。
・＃ｐｒａｇｍａ指令
＃ｐｒａｇｍａ　＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ　変数名　［，変数名，．．．］
＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ　変数名　［，変数名，．．．］
ここで、［］内は省略可能を意味する。複数指定する場合、”，”（カンマ）で変数名を区切ればよい。なお、オプションとプラグマ指令とが重複又は矛盾した場合は、プラグマ指令が優先する。
【０１０６】
このようなプラグマ指令に対して、コンパイラ１００は次のように動作する。つまり、図３９において、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ　変数名　［，変数名，．．．］」が検出された場合には（Ｓ１００、Ｓ１０１）、グローバル領域割り付け部１２１は、ここで指定された変数については、オプション指定にかかわらず、グローバル領域に配置させないコードを生成し（ステップＳ１０３）、一方、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ　変数名　［，変数名，．．．］」が検出された場合には（Ｓ１００、Ｓ１０１）、グローバル領域割り付け部１２１は、ここで指定された変数については、オプション指定にかかわらず、グローバル領域に配置させるコードを生成する（ステップＳ１０４）。これらの＃ｐｒａｇｍａ指令によって、速度向上とサイズ削減という最適化が可能となる。
【０１０７】
なお、＃ｐｒａｇｍａ　＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ指令が指定された場合は、グローバル領域割り付け部１２１は、その変数については、ｇｐ領域に実体もアドレスも配置しない。また、最大データサイズ指定よりも、＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令の方を優先する。もし、同一の変数に関して異なる指定が現れた場合には、コンパイラ１００の動作は不定となる。外部変数・静的変数については、可能な限り１命令アクセス可能なｇｐ領域に配置することが好ましい。
【０１０８】
次に、このようなプラグマ指令用いることによる最適化の具体例を示す。＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令を使用すると、ｇｐ領域配置の最大データサイズ以上の外部変数・静的変数をｇｐ領域に配置させることができので、その好適例を示す。
【０１０９】
図４２は、＃ｐｒａｇｍａ　＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ指令を用いた場合に生成されるコードの例（左欄）と、＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令を用いた場合に生成されるコードの例（右欄）とを示す図である。
【０１１０】
本図の左欄に示されるように、配列ｃのサイズは４０バイトなのでデフォルトの場合、先頭アドレスのみｇｐ領域に配置され、実体はｇｐ領域に配置されない。また、外部定義されている配列ａのサイズが３２バイトなのでデフォルトの場合は、ｇｐ領域に実体が配置されているとコンパイラ１００は判断する。
【０１１１】
しかし、＃ｐｒａｇｍａ　＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ指令により、配列ｃについては、ｇｐ領域には先頭アドレスも実体も配置されずに、ｇｐ領域以外に実体が配置され、絶対アドレスアクセスのコードが生成される。外部定義の配列ａについても、ｇｐ領域以外に実体が配置されているとして、絶対アドレスアクセスのコードが生成される。
【０１１２】
一方、本図の右欄に示されるように、配列ｃはサイズが４０バイトなので、デフォルトの場合ではｇｐ領域に配置されないが、＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令により配列ｃの実体がｇｐ領域に配置される。ファイル外定義の配列ａは、サイズが不明であるが＃ｐｒａｇｍａ指令により、ｇｐ領域に配置されているものとし、ｇｐ相対アクセスコードが生成される。
【０１１３】
このように、＃ｐｒａｇｍａ　＿ｎｏ＿ｇｐ＿ａｃｃｅｓｓ指令を用いた場合には、１０サイクルで実行される１２バイトのコードが生成されるのに対し、＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令を用いた場合には、７サイクルで実行される５バイトのコードが生成される。
【０１１４】
なお、ｅｘｔｅｒｎ　宣言外部変数に　＃ｐｒａｇｍａ　＿ｇｐ＿ａｃｃｅｓｓ指令を使用する場合、定義の指定（配置する領域）と使用側の指定（アクセスする方法）を必ず合わせておくことが好ましい。
【０１１５】
［ソフトウェアパイプライニング部１２２］
次に、ソフトウェアパイプライニング部１２２の動作とその意義について説明する。
ソフトウェアパイプライニング最適化は、ループ高速化手法の１つである。この最適化が行われると、ループ構造がプロログ部、カーネル部、　エピログ部に変換される。なお、ソフトウェアパイプライニング最適化は、それによって実行速度が向上されると判断された場合に行われる。カーネル部は、各イタレーション（繰り返し）をその前後のイタレーションとオーバーラップさせる。これにより、１イタレーション毎の平均処理時間が削減される。
【０１１６】
図４３（ａ）は、ループ処理におけるプロログ部・カーネル部・エピログ部の概念図である。ここでは、イタレーション間で依存関係のない命令Ｘ、Ｙ、Ｚ　が５回繰り返される場合の命令コード、実行イメージ、生成コードイメージの例が示されている。なお、ループ処理とは、ｆｏｒ文、ｗｈｉｌｅ文、ｄｏ文等による繰り返し処理である。
【０１１７】
ここで、プロログ部、　エピログ部は、可能であれば、図４３（ｂ）及び（ｃ）のプロセスに示されるように、除去される。しかし、不可能であれば除去されず、コードサイズが増加することがある。そのため、ソフトウェアパイプライニング最適化の動作を指定するオプション及び＃ｐｒａｇｍａ指令が用意されている。
【０１１８】
図４３（ｂ）は、ループ処理におけるプロログ部・エピログ部を除去するための処理を示す概念図である。つまり、図４３（ａ）で示されたイタレーション間で依存関係のない命令Ｘ、Ｙ、Ｚの５回の繰り返しについて、前記のプロログ部・カーネル部・エピログ部の概念図で示したループの生成コードイメージを並び替えたものが示されている。ただし、図中の　［］　のついた命令は、読み込まれるが実行されないとする。
【０１１９】
このようにすると、プロログ部・エピログ部は、カーネル部と同じ命令並びになることがわかる。よって、ループ回数は、プロログ部・エピログ部の実行分（４回）だけ増えるが、［］のついた命令をプレディケート（実行条件）によって制御することにより、図４３（ｃ）に示されるように、カーネル部だけでコードを生成することができる。
【０１２０】
図４３（ｃ）に示された生成コードの実行順序は、以下のようになる。
１回目においては、プレディケート［Ｃ２］、［Ｃ３］の付加された命令は実行されない。よって、［Ｃ４］Ｘ　のみ実行される。
２回目においては、プレディケート［Ｃ２］の付加された命令は実行されない。よって、［Ｃ３］Ｙ　、［Ｃ４］Ｘ　のみ実行される。
３〜５回目においては、［Ｃ２］Ｚ、　［Ｃ３］Ｙ、　［Ｃ４］Ｘ　すべてが実行される。
６回目においては、プレディケート［Ｃ４］の付加された命令は実行されない。よって、［Ｃ２］Ｚ　と　［Ｃ３］Ｙ　のみ実行される。
７回目においては、プレディケート［Ｃ３］、［Ｃ４］の付加された命令は実行されない。よって、［Ｃ２］Ｚ　のみ実行される。
【０１２１】
このように、カーネル部のループ　１回目、２回目でプロログ部を、６回目、７回目でエピログ部を実行していることになる。
【０１２２】
よって、プロログ部・エピログ部のあるループでは、コードサイズが増加するが、ループ回数が減少するため、実行速度向上を期待できる。逆に、プロログ部・エピログ部を除去したループでは、コードサイズを削減できるが、ループ回数が増加するため、実行サイクル数が増加する。
【０１２３】
そこで、このような最適化の選択を指定可能にするために、以下のコンパイルオプションとプラグマ指令が用意されている。
・コンパイルオプション
−ｆｎｏ−ｓｏｆｔｗａｒｅ−ｐｉｐｅｌｉｎｉｎｇ
・＃ｐｒａｇｍａ指令
＃ｐｒａｇｍａ　＿ｎｏ＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ
＃ｐｒａｇｍａ　＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ＿ｎｏ＿ｐｒｏｅｐｉ
＃ｐｒａｇｍａ　＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ＿ｗｉｔｈ＿ｐｒｏｅｐｉ
なお、オプションとプラグマ指令が重複又は矛盾した場合には、プラグマ指令が優先する。
【０１２４】
図４４は、ソフトウェアパイプライニング部１２２の動作を示すフローチャートである。解析部１１０によってオプション「−ｆｎｏ−ｓｏｆｔｗａｒｅ−ｐｉｐｅｌｉｎｉｎｇ」が検出された場合には（ステップＳ１１０、Ｓ１１１）、ソフトウェアパイプライニング部１２２は、対象となるソースプログラム１０１中の全てのループ処理に対してソフトウェアパイプライニング最適化を行わない（ステップＳ１１２）。このオプションによって、コードサイズが増加してしまうことが回避される。
【０１２５】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｎｏ＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ」が検出された場合には（ステップＳ１１０、Ｓ１１１）、ソフトウェアパイプライニング部１２２は、オプション指定にかかわらず、この指定の直後に置かれている１つのループ処理について、ソフトウェアパイプライニング最適化を行わない（ステップＳ１１３）。これによって、コードサイズが削減される。
【０１２６】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ＿ｎｏ＿ｐｒｏｅｐｉ」が検出された場合には（ステップＳ１１０、Ｓ１１１）、ソフトウェアパイプライニング部１２２は、オプション指定にかかわらず、この指定の直後に置かれている１つのループ処理について、プロログ部・エピログ部が除去できる範囲でソフトウェアパイプライニング最適化を行う（ステップＳ１１４）。これによって、速度の向上とサイズの削減化が図られる。
【０１２７】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ＿ｗｉｔｈ＿ｐｒｏｅｐｉ」が検出された場合には（ステップＳ１１０、Ｓ１１１）、ソフトウェアパイプライニング部１２２は、オプション指定にかかわらず、この指定の直後に置かれている１つのループ処理について、プロログ部・エピログ部を除去せずに、可能な範囲で、ソフトウェアパイプライニング最適化を行う（ステップＳ１１５）。これによって、速度が向上される。
【０１２８】
なお、ソフトウェアパイプライニング部１２２は、＃ｐｒａｇｍａ　＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ＿ｎｏ＿ｐｒｏｅｐｉ指令に対しては、プロログ部・エピログ部を除去できる範囲でソフトウェアパイプライニング最適化を行うが、＃ｐｒａｇｍａ　＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ＿ｗｉｔｈ＿ｐｒｏｅｐｉ指令に対しては、プロログ部・エピログ部の除去が可能であっても、除去しない。プロログ部・エピログ部の除去可能なループであっても、図４５に示される例のように、プロログ部・エピログ部の除去を抑制することにより、コードサイズは増加するが、実行速度の向上を期待できるからである。また、後述するように、ループ処理の最低繰り返し回数がソフトウェアパイプライニングによって重なり合うイタレーション数以上である場合には、ソフトウェアパイプライニング部１２２は、ソフトウェアパイプライニングによる最適化を行う。
【０１２９】
図４５は、ソフトウェアパイプライニング最適化の例を示す図である。なお、この例では、ソフトウェアパイプライニング最適化を行うために、コンパイルオプション　−Ｏ（実行速度とコードサイズ削減の最適化）をつけてコンパイルされている。
【０１３０】
本図の左欄の中下段に示された機械語プログラム１０２の例から分かるように、デフォルトのソフトウェアパイプライニング最適化が行われた場合には、プロログ部・エピログ部のコードも除去され、ループ回数が１０１回でカーネル部のサイクル数が２サイクルとなり、合計２０７サイクルで実行され、ループの性能が向上している。
【０１３１】
一方、本図の右欄の中上段に示されたソースプログラム１０１から分かるように、左欄のソースプログラム１０１に対して　＃ｐｒａｇｍａ　＿ｓｏｆｔｗａｒｅ＿ｐｉｐｅｌｉｎｉｎｇ＿ｗｉｔｈ＿ｐｒｏｅｐｉ指令が追加指定され、ループのプロログ部・エピログ部の除去を抑制した例となっている。これにより、右欄の中下段に示された機械語プログラム１０２の例から分かるように、プロログ部・エピログ部のコードが生成されるため、左側と比べコードサイズが増加しているが、ループ回数が９９回に減少しており、カーネル部サイクル数が２サイクルであるため、合計２０４サイクルで実行され、左欄の場合よりも更に実行速度が向上している。なお、プロログ部・エピログ部が周辺コードと並列実行可能な場合には、プロログ部・エピログ部による速度低下の影響は隠蔽できる。
［ループアンローリング部１２３］
【０１３２】
次に、ループアンローリング部１２３の動作とその意義について説明する。ループアンローリング部１２３は、大きく分けて、（１）ループアンローリングの指定に関する最適化と、（２）ループの繰り返し回数についての保証に関する最適化とを行う。
【０１３３】
まず、（１）ループアンローリングの指定に関する最適化について説明する。
ループアンローリング最適化とは、ループ高速化手法の１つである。複数のイタレーションを同時に実行することでループ内の実行を高速化する。ループアンローリング最適化を行うことにより、ｌｄｐ／ｓｔｐ命令の生成や並列度の向上により、実行速度の向上を図ることができる。しかし、コードサイズが増加することと、場合によっては、レジスタ不足によるスピルが発生し、逆に性能が低下してしまう場合がある。
【０１３４】
なお、ロードペア（ストアペア）命令（ｌｄｐ／ｓｔｐ命令）とは、二つのロード命令（ストア命令）を１命令で実現した命令である。また、「スピル」とは、空きレジスタを確保する為に、使用されているレジスタを一時的にスタックに退避させることである。この場合には、レジスタの退避・復帰のためにロード・ストア命令が生成される。
【０１３５】
このようなループアンローリング最適化の動作を指定するオプション及び＃ｐｒａｇｍａ指令が用意されている。
・コンパイルオプション
−ｆｎｏ−ｌｏｏｐ−ｕｎｒｏｌｌ
・＃ｐｒａｇｍａ指令
＃ｐｒａｇｍａ　＿ｌｏｏｐ＿ｕｎｒｏｌｌ
＃ｐｒａｇｍａ　＿ｎｏ＿ｌｏｏｐ＿ｕｎｒｏｌｌ
【０１３６】
図４６は、ループアンローリング部１２３の動作を示すフローチャートである。解析部１１０によってオプション「−ｆｎｏ−ｌｏｏｐ−ｕｎｒｏｌｌ」が検出された場合には（ステップＳ１２０、Ｓ１２１）、ループアンローリング部１２３は、対象となるソースプログラム１０１中の全てのループ処理に対してループアンローリング最適化を行わない（ステップＳ１２２）。このオプションによって、コードサイズが増加してしまうことが回避される。
【０１３７】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｌｏｏｐ＿ｕｎｒｏｌｌ」が検出された場合には（ステップＳ１２０、Ｓ１２１）、ループアンローリング部１２３は、直後に置かれている１つのループ処理に対してループアンローリング最適化を行う（ステップＳ１２３）。これによって、速度が向上される。
【０１３８】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｎｏ＿ｌｏｏｐ＿ｕｎｒｏｌｌ」が検出された場合には（ステップＳ１２０、Ｓ１２１）、ループアンローリング部１２３は、直後に置かれている１つのループ処理に対してループアンローリング最適化を行わない（ステップＳ１２４）。これによってコードサイズの増加が回避される。
【０１３９】
なお、最適化レベル指定に　−Ｏ／−Ｏｔ（実行速度を優先した最適化）が指定されている場合は、ループアンローリング部１２３は、ループアンローリング最適化が可能であるなら、デフォルトでループアンローリング最適化を行う。最適化レベル指定に−Ｏｓ（コードサイズ削減を優先した最適化）が指定されている場合は、ループアンローリング部１２３は、ループアンローリング最適化を行わない。よって、ユーザは、これらの最適化レベル指定コンパイルオプションと組み合わせて、個々のループのループアンローリング最適化の適用を、＃ｐｒａｇｍａ　＿ｎｏ＿ｌｏｏｐ＿ｕｎｒｏｌｌ指令及び＃ｐｒａｇｍａ＿ｌｏｏｐ＿ｕｎｒｏｌｌ　指令で制御することが可能である。
【０１４０】
図４７は、＃ｐｒａｇｍａ　＿ｌｏｏｐ＿ｕｎｒｏｌｌ指令による最適化の例を示す図である。本図の左欄は、最適化レベル指定コンパイルオプション　−Ｏのみをつけてコンパイルした場合の例であり、本図の右欄は、＃ｐｒａｇｍａ　＿ｌｏｏｐ＿ｕｎｒｏｌｌ指令を組み合わせてコンパイルした場合の例である。
【０１４１】
本図の左欄の中下段に示された機械語プログラム１０２の例から分かるように、プロログ部・エピログ部が除去されたソフトウェアパイプライニング最適化が適用されている。そのため、カーネル部の３命令（２サイクル）が１０１回実行され、全体として合計２０７サイクルかかっている。
【０１４２】
一方、右欄の中下段に示された機械語プログラム１０２の例から分かるように、左側と同様にソフトウェアパイプライニング最適化が行われ、プロログ部・エピログ部が削除されている。それに、この右欄の機械語プログラム１０２では、ループアンローリング最適化により、ループ回数が半減しているため、カーネル部の６命令（２サイクル）が５２回実行され、全体として合計１１０サイクルで実行され、速度が向上していいる。
【０１４３】
次に、ペアメモリアクセス命令（ｌｄｐ／ｓｔｐ）の生成によりループアンローリング最適化をより効果的に使用する方法を示す。
【０１４４】
ループアンローリング最適化では、現在のイタレーションと次のイタレーションを同時に実行するため、以下のような連続する領域のデータのロード・ストアが生成される場合がある。
ｌｄ　ｒ１，（ｒ４）；；
ｌｄ　ｒ２，（ｒ４，４）；；
【０１４５】
アクセスするデータが、必ず８バイトアラインされて配置されているならば、以下のようなペアメモリアクセス命令（ｌｄｐ命令）を生成することができる。
ｌｄｐ　ｒ１：ｒ２，（ｒ４＋）；；
図４８は、ペアメモリアクセス命令（ｌｄｐ／ｓｔｐ）の生成によりループアンローリング最適化をより効果的に使用する例を示す図である。ここでは、ソフトウェアパイプライニング最適化が適用されている。
【０１４６】
本図の右欄の例では、中下段に示された機械語プログラム１０２の例から分かるように、ループアンローリング最適化によりループ回数が半減されている。また、＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｌｏｃａｌ＿ｐｏｉｎｔｅｒ指令を使用して、ポインタ変数　ｐａ、ｐｂが８バイトアラインされているアドレスと明示することにより、ロードペア（ストアペア）命令が生成される。
【０１４７】
これらの最適化により、左欄の例では、カーネル部の５命令３サイクルが１０１回実行され、全体として合計３０８サイクルであるが、右欄の例では、カーネル部の７命令３サイクルが半分の５１回実行され、全体として合計１５８サイクルで実行され、速度が向上している。
【０１４８】
次に、ループアンローリング部１２３による、（２）ループの繰り返し回数の保証に関する最適化について説明する。
プログラムの記述上、コンパイラ１００ではループ回数を特定することができない場合、ループ高速化の各最適化を効果的に行うことができない。
【０１４９】
そこで、ユーザは、下記に示す＃ｐｒａｇｍａ指令にて、ループ回数の情報を提供することにより、より効果的にソフトウェアパイプライニング等のループ高速化の最適化を行わせることができる。
・＃ｐｒａｇｍａ指令
＃ｐｒａｇｍａ　＿ｍｉｎ＿ｉｔｅｒａｔｉｏｎ＝ＮＵＭ
＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｅｖｅｎ
＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｏｄｄ
【０１５０】
図４６において、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｍｉｎ＿ｉｔｅｒａｔｉｏｎ＝ＮＵＭ」が検出された場合には（ステップＳ１２０、Ｓ１２１）、ループアンローリング部１２３は、直後に置かれている１つのループ処理が最低ＮＵＭ回繰り返されることを前提に、ループアンローリング最適化を行う（ステップＳ１２５）。例えば、例えば、保証された繰り返し最低回数がループアンローリングによる展開数以上である場合に、ループアンローリング部１２３は、そのループ処理のループアンロールを行う。これによって、速度の向上とサイズの削減が図られる。
【０１５１】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｅｖｅｎ」が検出された場合には（ステップＳ１２０、Ｓ１２１）、ループアンローリング部１２３は、直後に置かれている１つのループ処理が偶数回繰り返されることを前提に、ループアンローリング最適化を行う（ステップＳ１２６）。これによって、実行速度が向上される。
【０１５２】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｏｄｄ」が検出された場合には（ステップＳ１２０、Ｓ１２１）、ループアンローリング部１２３は、直後に置かれている１つのループ処理が奇数回繰り返されることを前提に、ループアンローリング最適化を行う（ステップＳ１２６）。これによって、実行速度が向上される。
【０１５３】
なお、＃ｐｒａｇｍａ　＿ｍｉｎ＿ｉｔｅｒａｔｉｏｎ指令で１以上の値を指定した場合、１回もループを通らない場合のために生成されるエスケープコードを除去できるという効果もある。また、繰り返し回数が不明なループに対して、ループアンローリング最適化を期待する場合、遇数回ループか奇数回ループかが決まっているならば、＿ｉｔｅｒａｔｉｏｎ＿ｅｖｅｎ　／＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｏｄｄ指令を使用することにより、ループアンローリング最適化の適用が可能になるため、実行速度向上を期待することができる。
【０１５４】
図４９は、＃ｐｒａｇｍａ　＿ｍｉｎ＿ｉｔｅｒａｔｉｏｎ指令による最適化の例を示す図である。ここでは、繰り返し回数が不明なループでの、＃ｐｒａｇｍａ　＿ｍｉｎ＿ｉｔｅｒａｔｉｏｎ指令の使用効果が示されている。ただし、サイクル比較のため、引数ｅｎｄの値を１００とする。
【０１５５】
本図の左欄では、中下段に示された機械語プログラム１０２の例から分かるように、ループ回数が不明なため、一度もループを実行しない場合にループ本体を飛び越すための　ｃｍｐｌｅ／ｂｒ　命令（エスケープコード）が生成されている。また、ループ命令の生成を行うことができないため、加算命令・比較命令・ジャンプ命令でループが生成されている。サイクル数は、ループ部が７命令４サイクルの１００回繰り返しとなり、全体として合計４０５サイクルとなっている。
【０１５６】
一方、本図の右欄では、中上段に示されたソースプログラム１０１の例から分かるように、繰り返し回数が不明であるが、最低４回繰り返されることが＃ｐｒａｇｍａ　＿ｍｉｎ＿ｉｔｅｒａｔｉｏｎ指令で指定されている。これにより、ループ回数が０回の場合を考慮する必要が無いため、ループアンローリング部１２３は、エスケープコードを生成する必要がなくなる。
【０１５７】
また、ループ最低回数を考慮して、ループアンローリング部１２３は、ループ命令を生成することができる。例えば、保証された繰り返し最低回数（４）がループアンローリングによる展開数（この例では、３サイクル）以上であるので、ループアンローリング部１２３は、ループアンロールを行う。
【０１５８】
さらに、この例では、さらにソフトウェアパイプライニング最適化が可能になっている。これは、保証されたループの繰り返し最低回数（４）がソフトウェアパイプライニングによって重なり合うイタレーション数以上であったために、ソフトウェアパイプライニング部１２２がソフトウェアパイプライニングによる最適化を行ったためである。
【０１５９】
右欄の中下段に示された機械語プログラム１０２の例から分かるように、サイクル数は、ループ部が５命令３サイクルの１０１回繰り返しとなり、全体として合計３０８サイクルとなり、実行速度とサイズ削減が実現されている。
【０１６０】
図５０及び図５１は、＃ｐｒａｇｍａ　ｉｔｅｒａｔｉｏｎ＿ｅｖｅｎ／＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｏｄｄ　指令による最適化の例を示す図である。図５０は、ループ回数が不明の場合におけるソースプログラム１０１の例（左欄）と、そこから生成される機械語プログラム１０２の例（右欄）を示す図である。本図から分かるように、実際のループ回数が不明な場合、ループアンローリング最適化は適用できない。これは、ループ回数が偶数回の場合と奇数回の場合では、ループアンローリング最適化によって生成されるコードが異なるためである。
【０１６１】
ところが、図５１に示されるように、繰り返し回数が不明なループの場合でも、遇数回ループか奇数回ループかを指定することにより、ループアンローリング最適化を適用することができる。
【０１６２】
本図の左欄では、ループ回数が偶数回であることを、＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｅｖｅｎ指令で指定されているため、ループアンローリング部１２３によるループアンローリング最適化が行われ、左欄の中下段に示された機械語プログラム１０２の例から分かるように、偶数回用のコードが生成されている。
【０１６３】
また、本図の右欄では、ループ回数が奇数回であることを、＃ｐｒａｇｍａ　＿ｉｔｅｒａｔｉｏｎ＿ｏｄｄ指令により指定されているため、ループアンローリング部１２３によるループアンローリング最適化が行われ、右欄の中下段に示された機械語プログラム１０２の例から分かるように、奇数回用のコードが生成されている。この右欄の例から分かるように、左欄に示された偶数回の場合の生成コードと初期化部・ループ部はほぼ同じで、後処理部に、ループの最後の一回分を実行するコードが生成されている。
【０１６４】
このように、ループ回数が不明であっても、偶数回であるか奇数回であるかを保証することで、ループアンローリング部１２３は、ループアンローリング最適化を行うことができ、これによって実行速度が向上される。
【０１６５】
［ｉｆ変換部１２４］
次に、ｉｆ変換部１２４の動作とその意義について説明する。
通常、Ｃ言語プログラムのｉｆ構造をコンパイルすると、分岐命令（ｂｒ命令）が生成される。これに対して、ｉｆ変換とは、Ｃ言語プログラムのｉｆ構造を分岐命令を用いることなく、条件付き実行命令だけに書き換えることである。これによって、実行順序が固定化される（順次実行となる）るので、パイプラインの乱れが回避され、実行速度が向上され得る。なお、条件付き実行命令とは、その命令に含まれる条件（プレディケート）がプロセッサ１の状態（コンディションフラグ）と一致している場合にだけ実行される命令である。
【０１６６】
ｉｆ変換により、ｉｆ構造のワーストケースにおける実行時間は短縮されるが、ベストケースにおける実行時間は（短縮後の）ワースト実行時間と等しくなる。そのために、ｉｆ構造の特性（条件成立・不成立それぞれの発生頻度や各パスの実行サイクル数）に応じて、ｉｆ変換を適用すべき場合とすべきでない場合がある。
【０１６７】
このため、ユーザは、適用の可否をコンパイルオプションや＃ｐｒａｇｍａ指令で指示することができる。
・コンパイルオプション
−ｆｎｏ−ｉｆ−ｃｏｎｖｅｒｓｉｏｎ
・＃ｐｒａｇｍａ指令
＃ｐｒａｇｍａ　＿ｉｆ＿ｃｏｎｖｅｒｓｉｏｎ
＃ｐｒａｇｍａ　＿ｎｏ＿ｉｆ＿ｃｏｎｖｅｒｓｉｏｎ
なお、オプションとプラグマ指令が重複又は矛盾した場合には、プラグマ指令が優先する。
【０１６８】
図５２は、ｉｆ変換部１２４の動作を示すフローチャートである。解析部１１０によってオプション「−ｆｎｏ−ｉｆ−ｃｏｎｖｅｒｓｉｏｎ」が検出された場合には（ステップＳ１３０、Ｓ１３１）、ｉｆ変換部１２４は、対象となるソースプログラム１０１中の全てのｉｆ構造文に対してｉｆ変換を行わない（ステップＳ１３２）。なお、本オプションが検出されない場合は、ｉｆ変換部１２４は、ｉｆ変換が可能であり、かつ、そのワーストケースの時間がｉｆ変換前に対して短いｉｆ構造文である場合に、そのｉｆ構造文をｉｆ変換する。
【０１６９】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｉｆ＿ｃｏｎｖｅｒｓｉｏｎ」が検出された場合には（ステップＳ１３０、Ｓ１３１）、ｉｆ変換部１２４は、オプション指定にかかわらず、直後に置かれている１つのｉｆ構造文に対して、可能であればｉｆ変換を行う（ステップＳ１３３）。これによって、速度が向上される。
【０１７０】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ｎｏ＿ｉｆ＿ｃｏｎｖｅｒｓｉｏｎ」が検出された場合には（ステップＳ１３０、Ｓ１３１）、ｉｆ変換部１２４は、オプション指定にかかわらず、直後に置かれている１つのｉｆ構造文に対して、ｉｆ変換を行わない（ステップＳ１３４）。これによって、速度が向上される。
【０１７１】
図５３は、＃ｐｒａｇｍａ　＿ｎｏ＿ｉｆ＿ｃｏｎｖｅｒｓｉｏｎ指令でコンパイルした場合と、＃ｐｒａｇｍａ＿ｉｆ＿ｃｏｎｖｅｒｓｉｏｎ指令でコンパイルした場合の機械語プログラム１０２の例を示す図である。
【０１７２】
本図の左欄では、中下段の機械語プログラム１０２の例から分かるように、ｉｆ変換を抑制したことにより、分岐命令が生成されている（実行サイクル数：５あるいは７、　コードサイズ：１２バイト）。
【０１７３】
一方、本図の右欄では、中下段の機械語プログラム１０２の例から分かるように、＃ｐｒａｇｍａ指令によってｉｆ変換を行うこととしたことにより、分岐命令が、条件付き命令（プレディケート付き命令）に置き換わっている（実行サイクル数：４、　コードサイズ：８バイト）。このように、ｉｆ変換を実施することで、実行速度比１．２５倍、　コードサイズ比６７％が達成されている。
【０１７４】
［ペア命令生成部１２５］
次に、ペア命令生成部１２５の動作とその意義について説明する。ペア命令生成部１２５は、大きく分けて、（１）配列・構造体のアラインメントの設定に関する最適化と、（２）仮引数ポインタ・ローカルポインタのアラインの保証に関する最適化とを行う。
【０１７５】
まず、（１）配列・構造体のアラインメントの設定に関する最適化について説明する。
ユーザは、以下のオプションを用いて、配列と構造体の先頭アドレスのアラインを指定することができる。アラインメントを調整することで、メモリアクセス命令のペアリング（２つのレジスタとメモリ間の転送をひとつの命令で行うこと）が可能となり、実行速度の向上が期待できる。その反面、アラインメント値を大きくすると、データの未使用領域が増加し、データサイズが増大する可能性がある。
・コンパイルオプション
−ｆａｌｉｇｎ＿ｃｈａｒ＿ａｒｒａｙ＝ＮＵＭ　　（ＮＵＭ＝２，４または８）
−ｆａｌｉｇｎ＿ｓｈｏｒｔ＿ａｒｒａｙ＝ＮＵＭ　　（ＮＵＭ＝４または８）
−ｆａｌｉｇｎ＿ｉｎｔ＿ａｒｒａｙ＝ＮＵＭ　　（ＮＵＭ＝８）
−ｆａｌｉｇｎ＿ａｌｌ＿ａｒｒａｙ＝ＮＵＭ　　（ＮＵＭ＝２，４または８）
−ｆａｌｉｇｎ＿ｓｔｒｕｃｔ＝ＮＵＭ　　（ＮＵＭ＝２，４または８）
【０１７６】
上記オプションは、上から順に、ｃｈａｒ型の配列、ｓｈｏｒｔ型整数、ｉｎｔ型整数、それら３つののデータ型全ての配列、構造体のアラインメントを指定している。また、”ＮＵＭ”は、アラインするサイズ（バイト）を示す。
【０１７７】
図５４は、ペア命令生成部１２５の動作を示すフローチャートである。解析部１１０によって上記オプションのいずれかが検出された場合には（ステップＳ１４０、Ｓ１４１）、ペア命令生成部１２５は、対象となるソースプログラム１０１で宣言されている指定された型の全ての配列又は構造体について、その先頭アドレスが指定されたＮＵＭバイトのアラインとなるように配列又は構造体をメモリに配置し、その配列又は構造体にアクセスする命令については、可能な場合に、ペアリング（２つのレジスタとメモリ間の転送を並行して行う命令の生成）を行う（ステップＳ１４２）。これによって、実行速度が向上される。
【０１７８】
図５５は、サンプルプログラムをオプションなしでコンパイルした場合と、オプション’−ｆａｌｉｇｎ−ｓｈｏｒｔ−ａｒｒａｙ＝４’でコンパイルした場合のアセンブリコードを示す図である。
【０１７９】
本図の左欄に示されたオプションなしの場合、中下段に示された機械語プログラム１０２の例から分かるように、アラインメントが不明のため、ロード命令のペアリング（２つのレジスタとメモリ間の転送をひとつの命令で行う）ができない（実行サイクル数：２５、　コードサイズ：２２）。
【０１８０】
一方、本図の右欄に示されたオプションありの場合、配列が４バイトでアラインされるため、中下段に示された機械語プログラム１０２の例から分かるように、最適化部１２０によるペアリングが実現されている（実行サイクル数：１５、コードサイズ：１８）。このように、アラインメントの指定によって、実行速度比１．６７倍、　コードサイズ比８２％が達成されている。
【０１８１】
次に、ペア命令生成部１２５による、（２）仮引数ポインタ・ローカルポインタのアラインの保証に関する最適化を説明する。
【０１８２】
ユーザは、以下のプラグマ指令を用いて、関数引数のポインタ変数の指すデータのアラインメントや、ローカルポインタ変数の指すデータのアラインメントを保証することで、最適化部１２０によるメモリアクセス命令のペアリングが可能となり、実行速度の向上が期待できる。
・＃ｐｒａｇｍａ指令
＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｐａｒｍ＿ｐｏｉｎｔｅｒ＝ＮＵＭ　変数名　［，　変数名，　…］
＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｌｏｃａｌ＿ｐｏｉｎｔｅｒ＝ＮＵＭ　変数名　［，　変数名，　…］
【０１８３】
なお、”ＮＵＭ”はアラインするサイズ（２，４又は８バイト）を表す。また、上記＃ｐｒａｇｍａ指令で保証されたポインタ変数の指すデータが指定されたバイト境界にアラインされていなかった場合には、プログラムの正常動作は保証されない。
【０１８４】
図５４において、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｐａｒｍ＿ｐｏｉｎｔｅｒ＝ＮＵＭ　変数名　［，　変数名，　…］」が検出された場合には（ステップＳ１４０、Ｓ１４１）、ペア命令生成部１２５は、”変数名”で示される引数のポインタ変数の指すデータが引数渡しの時点でＮＵＭバイトにアラインされているものとし、その配列にアクセスする命令については、可能な場合に、ペアリングを行う（ステップＳ１４３）。これによって、実行速度が向上される。
【０１８５】
また、解析部１１０によってプラグマ指令「＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｌｏｃａｌ＿ｐｏｉｎｔｅｒ＝ＮＵＭ　変数名　［，　変数名，　…］」が検出された場合には（ステップＳ１４０、Ｓ１４１）、ペア命令生成部１２５は、”変数名”で示されるローカルポインタ変数の指すデータが関数内部で常にＮＵＭバイトでアラインされているものとし、その配列にアクセスする命令については、可能な場合に、ペアリングを行う（ステップＳ１４４）。これによって、実行速度が向上される。
【０１８６】
図５６は、プラグマ指令「＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｐａｒｍ＿ｐｏｉｎｔｅｒ＝ＮＵＭ　変数名　［，　変数名，　…］」による最適化の例を示す図である。
【０１８７】
本図の左欄に示されるように、＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｐａｒｍ＿ｐｏｉｎｔｅｒを与えない場合、ポインタ変数ｓｒｃの指すデータのアラインメントが不明なため、中下段に示された機械語プログラム１０２の例から分かるように、各データはそれぞれ独立にロードされる（実行サイクル数１６０、コードサイズ：２４バイト）。
【０１８８】
一方、本図の右欄に示されるように、＃ｐｒａｇｍａ指令を与えると、データは４バイト境界にアラインされるため、中下段の機械語プログラム１０２の例から分かるように、メモリ読み出しのペアリングが行われる（実行サイクル数：１０７、コードサイズ：１８バイト）。このように、アライメントを指定することで、実行速度比１．５０倍、　コードサイズ比４３％が達成される。
【０１８９】
図５７は、プラグマ指令「＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｌｏｃａｌ＿ｐｏｉｎｔｅｒ＝ＮＵＭ　変数名　［，　変数名，　…］」による最適化の例を示す図である。
本図の左欄に示されるように、＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｌｏｃａｌ＿ｐｏｉｎｔｅｒを与えない場合、ポインタ変数ｆｒｏｍ、ｔｏの指すデータのアラインメントが不明なため、中下段に示された機械語プログラム１０２の例から分かるように、配列要素はそれぞれ独立にロードされる（実行サイクル数：７２、　コードサイズ：３０）。
【０１９０】
一方、本図の右欄に示されるように、＃ｐｒａｇｍａ　＿ａｌｉｇｎ＿ｐａｒｍ＿ｐｏｉｎｔｅｒを与えることで、中下段に示された機械語プログラム１０２の例から分かるように、ポインタ変数ｆｒｏｍ、ｔｏの指すデータが４バイト境界にアラインされていることを利用したメモリ読み出しのペアリングが可能となる。（実行サイクル数：５６、　コードサイズ：２２）。このように、アライメントを指定することで、実行速度比１．３２倍、　コードサイズ比７３％が達成される。
【０１９１】
【発明の効果】
以上の説明から明らかように、本発明に係るコンパイラは、変数のグローバル領域への割り付けに関する指示を受け付け、その指示に基づいて、各種変数のグローバル領域へのマッピングを行う。
【０１９２】
その１つとして、ユーザは、コンパイル時のオプションによって、グローバル領域に割り付ける変数の最大データサイズを指定することができる。これによって、ユーザは、グローバル領域に配置させる変数のデータサイズを制御することが可能となり、グローバル領域を有効活用するように最適化を図ることができる。
【０１９３】
また、ユーザは、ソースプログラム中に置くプラグマ指令によって、変数ごとに、グローバル領域への割り付けをする／しない旨の指定をすることができる。これによって、グローバル領域に優先的に割り付けるべき変数、割り付けてはいけない変数を個々に区別して、最適なグローバル領域の割付けをユーザが管理することができる。
【０１９４】
また、本発明に係るコンパイラは、ソフトウェアパイプライニングの指示を受け付け、その指示に従ったソフトウェアパイプライニングによる最適化を行う。
【０１９５】
その１つとして、ユーザは、コンパイル時のオプションによって、ソフトウェアパイプライニングをしない旨の指定をすることができる。これによって、ソフトウェアパイプライニングによるコードサイズの増加が抑制される。またソフトウェアパイプライニングが行われたアセンブラコードは複雑なので、プログラムの機能検証のために、ソフトウェアパイプライニングを抑制するこで、デバッグが容易となる。
【０１９６】
また、ユーザは、ソースプログラム中のプラグマ指令によって、ループ処理ごとに、ソフトウェアパイプライニングをする／しない旨の指定をしたり、プロログ部及びエピログ部を除去して／除去しないでソフトウェアパイプライニングをする旨の指定をしたりすることができる。これによって、ループ処理ごとにソフトウェアパイプライニングをするか否かを選択したり、コードサイズ重視（プロローグエピローグ除去する）又はスピード重視（プロローグエピローグ除去しない）のソフトウェアパイプライニングを選択したりすることが可能となる。
【０１９７】
また、本発明に係るコンパイラは、ループアンローリングの指示を受け付け、その指示に従ったループアンローリングによる最適化を行う。
【０１９８】
その１つとして、ユーザは、コンパイル時のオプションによって、ループアンローリングをしない旨の指示をすることができる。これによって、ループアンローリングによるコードサイズの増加が回避される。
【０１９９】
また、ユーザは、ソースプログラム中のプラグマ指令によって、ループ処理ごとに、ループアンローリングをする／しない旨の指示をすることができる。これによって、ユーザは、ループ処理ごとに、その繰り返し回数等を勘案し、実行速度を重視するか、コードサイズを重視するかの最適化を選択することができる。
【０２００】
また、本発明に係るコンパイラは、ループ処理の繰り返し回数に関する指示を受け付け、その指示に従った最適化を行う。
【０２０１】
その１つとして、ユーザは、ソースプログラム中のプラグマ指令によって、ループ処理ごとに、最低の繰り返し回数を保証することができる。これによって、繰り返し回数が０である場合に必要とされるコード（エスケープコード）を生成する必要がなくなるとともに、ソフトウェアパイプライニングやループアンロールによる最適化が可能となる。
【０２０２】
また、ユーザは、ソースプログラム中のプラグマ指令によって、ループ処理ごとに、繰り返し回数が偶数回／奇数回であることを保証することができる。これによって、たとえ繰り返し回数が不明であっても、ループ処理ごとに、ループアンロールによる最適化が可能となり、実行速度が向上され得る。
【０２０３】
また、本発明に係るコンパイラは、ｉｆ変換に関する指示を受け付け、その指示に従ったｉｆ変換による最適化を行う。
【０２０４】
その１つとして、ユーザは、コンパイル時のオプションによって、ｉｆ変換をしない旨の指示をすることができる。これによって、ｉｆ構造のｔｈｅｎ側とｅｌｓｅ側で命令数のバランスが悪い場合に、ｉｆ変換によって命令数の少ない側の実行が命令数の多い側に制約されてしまうという不具合の発生を防ぐことができる。
【０２０５】
また、ユーザは、ソースプログラム中のプラグマ指令によって、ループ処理ごとに、ｉｆ変換をする／しない旨の指示をすることができる。これによって、個々のループ処理の特性（ｔｈｅｎ側とｅｌｓｅ側それぞれの命令数のバランス、予想される発生頻度のバランス等）を考慮して、より実行速度が向上されると予測される選択（ｉｆ変換をする／しない）を行うことができる。
【０２０６】
また、本発明に係るコンパイラは、配列データのメモリ領域への配置におけるアライメントに関する指示を受け付け、その指示に従った最適化を行う。
【０２０７】
その１つとして、ユーザは、コンパイル時のオプションによって、特定の型の配列データについて、バイト数によるアラインを指定することができる。これによって、２つのデータに対するメモリ・レジスタ間の転送を同時に行うペア命令が生成され、実行速度が向上される。
【０２０８】
また、ユーザは、ソースプログラム中のプラグマ指令によって、ポインタ変数が指すデータのアラインを指定することができる。これによって、データごとに、ペア命令が生成されることを可能にすることができ、実行速度が向上される。
【０２０９】
以上のように、本発明に係るコンパイラにより、ユーザは、従来のような大雑把な指示ではなく、コンパイラによる各種最適化の種類ごとにＯＮ／ＯＦＦやその程度を指定したり、プログラム中の変数やループ処理等の単位で最適化をＯＮ／ＯＦＦさせたりする等のきめ細かい制御が可能となり、特に、精密な最適化のチューニングが必要とされるメディア処理のアプリケーション開発に有効であり、その実用的価値は極めて高い。
【図面の簡単な説明】
【図１】本発明に係るコンパイラの対象となるプロセッサの概略ブロック図である。
【図２】同プロセッサの算術論理・比較演算器の概略図を示す。
【図３】同プロセッサのバレルシタの構成を示すブロック図である。
【図４】同プロセッサの変換器の構成を示すブロック図である。
【図５】同プロセッサの除算器の構成を示すブロック図である。
【図６】同プロセッサの乗算・積和演算器の構成を示すブロック図である。
【図７】同プロセッサの命令制御部の構成を示すブロック図である。
【図８】同プロセッサの汎用レジスタ（Ｒ０〜Ｒ３１）の構造を示す図である。
【図９】同プロセッサのリンクレジスタ（ＬＲ）の構造を示す図である。
【図１０】同プロセッサの分岐レジスタ（ＴＡＲ）の構造を示す図である。
【図１１】同プロセッサのプログラム状態レジスタ（ＰＳＲ）の構造を示す図である。
【図１２】同プロセッサの条件フラグレジスタ（ＣＦＲ）の構造を示す図である。
【図１３】同プロセッサのアキュムレータ（Ｍ０，Ｍ１）の構造を示す図である。
【図１４】同プロセッサのプログラムカウンタ（ＰＣ）の構造を示す図である。
【図１５】同プロセッサのＰＣ退避用レジスタ（ＩＰＣ）の構造を示す図である。
【図１６】同プロセッサのＰＳＲ退避用レジスタ（ＩＰＳＲ）の構造を示す図である。
【図１７】同プロセッサのパイプライン動作を示すタイミング図である。
【図１８】同プロセッサによる命令実行時の各パイプライン動作を示すタイミング図である。
【図１９】同プロセッサの並列動作を示す図である。
【図２０】同プロセッサが実行する命令のフォーマットを示す図である。
【図２１】カテゴリー「ＡＬＵａｄｄ（加算）系」に属する命令を説明する図である。
【図２２】カテゴリー「ＡＬＵｓｕｂ（減算）系」に属する命令を説明する図である。
【図２３】カテゴリー「ＡＬＵｌｏｇｉｃ（論理演算）系ほか」に属する命令を説明する図である。
【図２４】カテゴリー「ＣＭＰ（比較演算）系」に属する命令を説明する図である。
【図２５】カテゴリー「ｍｕｌ（乗算）系」に属する命令を説明する図である。
【図２６】カテゴリー「ｍａｃ（積和演算）系」に属する命令を説明する図である。
【図２７】カテゴリー「ｍｓｕ（積差演算）系」に属する命令を説明する図である。
【図２８】カテゴリー「ＭＥＭｌｄ（メモリ読み出し）系」に属する命令を説明する図である。
【図２９】カテゴリー「ＭＥＭｓｔｏｒｅ（メモリ書き出し）系」に属する命令を説明する図である。
【図３０】カテゴリー「ＢＲＡ（分岐）系」に属する命令を説明する図である。
【図３１】カテゴリー「ＢＳａｓｌ（算術バレルシフト）系ほか」に属する命令を説明する図である。
【図３２】カテゴリー「ＢＳｌｓｒ（論理バレルシフト）系ほか」に属する命令を説明する図である。
【図３３】カテゴリー「ＣＮＶｖａｌｎ（算術変換）系」に属する命令を説明する図である。
【図３４】カテゴリー「ＣＮＶ（一般変換）系」に属する命令を説明する図である。
【図３５】カテゴリー「ＳＡＴｖｌｐｋ（飽和処理）系」に属する命令を説明する図である。
【図３６】カテゴリー「ＥＴＣ（その他）系」に属する命令を説明する図である。
【図３７】本発明に係るコンパイラの構成を示す機能ブロック図である。
【図３８】（ａ）は、グローバル領域におけるデータ等の配置例、（ｂ）は、グローバル領域以外の領域におけるデータの配置例を示す図である。
【図３９】グローバル領域割り付け部の動作を示すフローチャートである。
【図４０】グローバル領域割り付け部による最適化の具体例を示す図である。
【図４１】グローバル領域割り付け部による最適化の具体例を示す図である。
【図４２】グローバル領域割り付け部による最適化の具体例を示す図である。
【図４３】ソフトウェアパイプライニング最適化を説明する図である。
【図４４】ソフトウェアパイプライニング部の動作を示すフローチャートである。
【図４５】ソフトウェアパイプライニング部による最適化の具体例を示す図である。
【図４６】ループアンローリング部の動作を示すフローチャートである。
【図４７】ループアンローリング部による最適化の具体例を示す図である。
【図４８】ループアンローリング部による最適化の具体例を示す図である。
【図４９】ループアンローリング部による最適化の具体例を示す図である。
【図５０】ループアンローリング最適化が適用できない例を示す図である。
【図５１】ループアンローリング部による最適化の具体例を示す図である。
【図５２】ｉｆ変換部の動作を示すフローチャートである。
【図５３】ｉｆ変換部による最適化の具体例を示す図である。
【図５４】ペア命令生成部の動作を示すフローチャートである。
【図５５】ペア命令生成部による最適化の具体例を示す図である。
【図５６】ペア命令生成部による最適化の具体例を示す図である。
【図５７】ペア命令生成部による最適化の具体例を示す図である。
【符号の説明】
１　　プロセッサ
１０　　命令制御部
２０　　デコード部
３０　　レジスタファイル
３１　　プログラム状態レジスタ（ＰＳＲ）
３２　　条件フラグレジスタ（ＣＦＲ）
３３　　プログラムカウンタ（ＰＣ）
３４　　ＰＣ退避用レジスタ（ＩＰＣ）
３５　　ＰＳＲ退避用レジスタ（ＩＰＳＲ）
４０　　演算部
４１〜４３　算術論理・比較演算器
４４　　積和演算器
４５　　バレルシフタ
４６　　除算器
４７　　変換器
５０　　Ｉ／Ｆ部
６０　　命令メモリ部
７０　　データメモリ部
８０　　拡張レジスタ部
９０　　Ｉ／Ｏインターフェース部
１００　　コンパイラ
１０１　　ソースプログラム
１０２　　機械語プログラム
１１０　　解析部
１１２　　ステップＳ
１２０　　最適化部
１２１　　グローバル領域割り付け部
１２２　　ソフトウェアパイプライニング部
１２３　　ループアンローリング部
１２４　　ｉｆ変換部
１２５　　ペア命令生成部
１３０　　出力部
【図１】
2004038597.tif 000008
【図２】
2004038597.tif 000009
【図３】
2004038597.tif 000010
【図４】
2004038597.tif 000011
【図５】
2004038597.tif 000012
【図６】
2004038597.tif 000013
【図７】
2004038597.tif 000014
【図８】
2004038597.tif 000015
【図９】
2004038597.tif 000016
【図１０】
2004038597.tif 000017
【図１１】
2004038597.tif 000018
【図１２】
2004038597.tif 000019
【図１３】
2004038597.tif 000020
【図１４】
2004038597.tif 000021
【図１５】
2004038597.tif 000022
【図１６】
2004038597.tif 000023
【図１７】
2004038597.tif 000024
【図１８】
2004038597.tif 000025
【図１９】
2004038597.tif 000026
【図２０】
2004038597.tif 000027
【図２１】
2004038597.tif 000028
【図２２】
2004038597.tif 000029
【図２３】
2004038597.tif 000030
【図２４】
2004038597.tif 000031
【図２５】
2004038597.tif 000032
【図２６】
2004038597.tif 000033
【図２７】
2004038597.tif 000034
【図２８】
2004038597.tif 000035
【図２９】
2004038597.tif 000036
【図３０】
2004038597.tif 000037
【図３１】
2004038597.tif 000038
【図３２】
2004038597.tif 000039
【図３３】
2004038597.tif 000040
【図３４】
2004038597.tif 000041
【図３５】
2004038597.tif 000042
【図３６】
2004038597.tif 000043
【図３７】
2004038597.tif 000044
【図３８】
2004038597.tif 000045
【図３９】
2004038597.tif 000046
【図４０】
2004038597.tif 000047
【図４１】
2004038597.tif 000048
【図４２】
2004038597.tif 000049
【図４３】
2004038597.tif 000050
【図４４】
2004038597.tif 000051
【図４５】
2004038597.tif 000052
【図４６】
2004038597.tif 000053
【図４７】
2004038597.tif 000054
【図４８】
2004038597.tif 000055
【図４９】
2004038597.tif 000056
【図５０】
2004038597.tif 000057
【図５１】
2004038597.tif 000058
【図５２】
2004038597.tif 000059
【図５３】
2004038597.tif 000060
【図５４】
2004038597.tif 000061
【図５５】
2004038597.tif 000062
【図５６】
2004038597.tif 000063
【図５７】
2004038597.tif 000064