(57)【要約】【課題】オブジェクトコードの実行性能に優れ、コードサイズも削減可能なコンパイラ、演算処理システム及びオブジェクトコード生成方法を提供する。【解決手段】ソースプログラムに基づいてオブジェクトコードを生成するコンパイラにおいて、前記ソースプログラム中に記述された、第１及び第２の演算指示情報と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に開けるべきサイクル数または命令数とを記述した命令スケジューリング情報を検出する命令検出部と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、これらオブジェクトコードとは無関係のオブジェクトコードを前記サイクル数または命令数分だけ挿入するオブジェクトコード挿入部と、を備える。【選択図】　図１
2004038279.tif 000002
【特許請求の範囲】
【請求項１】
ソースプログラムに基づいてオブジェクトコードを生成するコンパイラにおいて、
前記ソースプログラム中に記述された、第１及び第２の演算指示情報と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に開けるべきサイクル数または命令数とを記述した命令スケジューリング情報を検出する命令検出部と、
前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、これらオブジェクトコードとは無関係のオブジェクトコードを前記サイクル数または命令数分だけ挿入するオブジェクトコード挿入部と、を備えることを特徴とするコンパイラ。
【請求項２】
前記オブジェクトコード挿入部は、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、これらオブジェクトコードが使用するハードウェアリソースを使用せずに別のハードウェアリソースを使用する他のオブジェクトコードを前記サイクル数または命令数分だけ挿入することを特徴とする請求項１に記載のコンパイラ。
【請求項３】
前記ハードウェアリソースは、演算レジスタ及びメモリの少なくとも一方であることを特徴とする請求項１または２に記載のコンパイラ。
【請求項４】
前記第１の演算指示情報に対応するオブジェクトコードの直前に実行される予定のオブジェクトコードを他のコード位置に移動可能か否かを判定する第１移動判定部と、
前記第１移動判定部により移動可能と判定されたオブジェクトコードが使用するハードウェアリソースが前記第１の演算指示情報に対応するオブジェクトコードが使用するハードウェアリソースと衝突するか否かを判定する第１リソース判定部と、を備え、
前記オブジェクトコード挿入部は、前記第１リソース判定部により衝突しないと判定されたオブジェクトコードを、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に移動させることを特徴とする請求項２または３に記載のコンパイラ。
【請求項５】
前記第２の演算指示情報に対応するオブジェクトコードの直後に実行される予定のオブジェクトコードを他のコード位置に移動可能な否かを判定する第２移動判定部と、
前記第２移動判定部により移動可能と判定されたオブジェクトコードが使用するハードウェアリソースが前記第２の演算指示情報に対応するオブジェクトコードが使用するハードウェアリソースと衝突するか否かを判定する第２リソース判定部と、を備え、
前記オブジェクトコード挿入部は、前記第２リソース判定部により衝突しないと判定されたオブジェクトコードを、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に移動させることを特徴とする請求項２及至４のいずれかに記載のコンパイラ。
【請求項６】
前記オブジェクトコード挿入部は、移動可能な他のオブジェクトコードが存在しない場合は、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間にｎｏｐコードを挿入することを特徴とすることを特徴とする請求項１及至５のいずれかに記載のコンパイラ。
【請求項７】
前記命令スケジューリング情報は、前記第１及び第２の演算指示情報と、これら第１及び第２の演算指示情報に対応するオブジェクトコード間に開けるべきサイクル数または命令数と、を引数とする特定の関数であることを特徴とする請求項１及至６のいずれかに記載のコンパイラ。
【請求項８】
前記特定の関数は、ソースプログラムの記述言語に新たに追加された予約語であることを特徴とする請求項７に記載のコンパイラ。
【請求項９】
前記特定の関数は、ＩＳＯ／ＪＩＳのＣ言語の規格で規定されている予約語以外の語句で構成されることを特徴とする請求項８に記載のコンパイラ。
【請求項１０】
前記命令スケジューリング情報は、前記第１及び第２の演算指示情報と、これら第１及び第２の演算指示情報に対応するオブジェクトコード間に開けるべきサイクル数または命令数と、を記述したＩＳＯ／ＪＩＳのＣ言語の規格で規定されている前処理指令であることを特徴とする請求項１及至５のいずれかに記載のコンパイラ。
【請求項１１】
前記命令スケジューリング情報は、Ｃ言語のＩＳＯ／ＩＥＣ　９８９９：１９９９　で規定されているｉｎｌｉｎｅ関数として宣言される関数中に含まれ、
前記オブジェクトコード挿入部は、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、ソースプログラム中に展開される前記命令スケジューリング情報の前後に位置する命令に対応するオブジェクトコードを挿入することを特徴とする請求項１及至６のいずれかに記載のコンパイラ。
【請求項１２】
前記第１及び第２の演算指示情報は、プロセッサとは別個に設けられる演算装置が実行する演算指示情報であることを特徴とする請求項１及至１１のいずれかに記載のコンパイラ。
【請求項１３】
前記演算装置は、プロセッサに付属するコプロセッサであることを特徴とする請求項１２に記載のコンパイラ。
【請求項１４】
ソースプログラムに基づいて生成されるオブジェクトコードに従って演算処理を行う演算処理システムにおいて、
前記ソースプログラム中に記述された、第１及び第２の演算指示情報と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に開けるべきサイクル数または命令数とに基づいて、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、これらオブジェクトコードが使用するハードウェアリソースを使用せずに別のハードウェアリソースを使用する他のオブジェクトコードを前記サイクル数または命令数分だけ挿入したオブジェクトコード群に基づいて演算処理を行う演算処理部を備えることを特徴とする演算処理システム。
【請求項１５】
プロセッサと、
このプロセッサとは別個に設けられる演算装置と、を備え、
前記演算処理部は、前記演算装置に内蔵されることを特徴とする請求項１４に記載の演算処理システム。
【請求項１６】
前記演算装置は、プロセッサに接続されるコプロセッサであることを特徴とする請求項１５に記載の演算処理システム。
【請求項１７】
ソースプログラムに基づいてオブジェクトコードを生成する演算処理方法において、
前記ソースプログラム中に記述された、第１及び第２の演算指示情報と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に開けるべきサイクル数または命令数とを記述した命令スケジューリング情報を検出するステップと、
前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、これらオブジェクトコードが使用するハードウェアリソースを使用せずに別のハードウェアリソースを使用する他のオブジェクトコードを前記サイクル数または命令数分だけ挿入するステップと、を備えることを特徴とする演算処理方法。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、高級言語で代表されるソースプログラムに基づいてオブジェクトコードを生成するコンパイラ及び演算処理方法と、この種のコンパイラで生成されたオブジェクトコードに基づいて演算処理を行う演算処理システムとに関する。
【０００２】
【従来の技術】
１サイクルで終わらない処理をプロセッサで行う場合、処理を開始する命令と結果を受け取る命令とが特定の専用命令の組合せであれば、コンパイラでも簡易にスケジューリングを行うことができる。
【０００３】
例えば、乗算を行うｍｕｌ命令と、乗算結果の下位３２ビットを受け取るｍｆｌｏ命令（ｍｕｌ命令とｍｆｌｏ命令はＲＩＳＣ型プロセッサの一例であるＭＩＰＳアーキテクチャの命令であり、本明細書のアセンブリ命令は、ＭＩＰＳアーキテクチャの命令を使用している）とを実行するのに、システムクロックの４サイクルを必要とする場合、図２７に示すように、ｍｕｌ命令とｍｆｌｏ命令の間に無関係な命令を３命令を入れることで、ストールを起こすことなく、処理を行うことができる。
【０００４】
図２７の場合、ｍｕｌ　命令と　ｍｆｌｏ　命令の間の３命令は、ＨＩレジスタとＬＯレジスタにアクセスしない命令で、かつｍｆｌｏ命令で定義するレジスタを使用しない命令であるという予め定めた規則をコンパイラに組み込むことにより、コンパイラがｍｕｌ命令とｍｆｌｏ命令を生成した場合だけでなく、プログラマが　ｍｕｌ　命令と　ｍｆｌｏ　命令を　組み込み関数（ｉｎｔｒｉｎｓｉｃｓ関数）にて記述した場合にも、コンパイラによる命令スケジューリングが可能になる。ちなみに、組み込み関数（ｉｎｔｒｉｎｓｉｃｓ関数）とは、コンパイラが直接生成できないような機械命令をＣ言語のソース中に関数形式で記述する方法である。
【０００５】
【発明が解決しようとする課題】
しかしながら、プロセッサに接続された演算装置で演算を行う場合、使用する命令は特別の命令ではなく、プロセッサに接続された演算装置や周辺装置にアクセスするための通常の命令（ｓｗ命令やｌｗ命令など）であるため、上述したｍｕｌ命令やｍｆｌｏ命令等の特別な命令の組合せによるスケジューリング手法では対応できない。
【０００６】
例えば、演算装置のレジスタにｓｗ命令で書き込んだ内容で演算を行い、その４サイクル後に、演算装置のレジスタからｌｗ命令で演算結果を読み出せるようにした場合、図２８のように記述する。なお、レジスタｒ２には、すでに演算装置のレジスタのアドレスが格納されているものとする。
【０００７】
ｓｗ命令とｌｗ命令の両方とも、通常のメモリアクセスに使用する命令であるため、ｍｕｌ　命令や　ｍｆｌｏ　命令等の特定命令の組み合わせのスケジューリングの規則と同様の規則をコンパイラに予め組み込むことはできない。このため、ｓｗ命令やｌｗ命令を実行する場合は、プログラマが　スケジューリングを考えてプログラムを記述する必要があった。
【０００８】
本発明は、このような点に鑑みてなされたものであり、その目的は、オブジェクトコードの実行性能に優れ、コードサイズも削減可能なコンパイラ、演算処理システム及び演算処理方法を提供することにある。
【０００９】
【課題を解決するための手段】
上述した課題を解決するために、本発明は、ソースプログラムに基づいてオブジェクトコードを生成するコンパイラにおいて、前記ソースプログラム中に記述された、第１及び第２の演算指示情報と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に開けるべきサイクル数または命令数とを記述した命令スケジューリング情報を検出する命令検出部と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、これらオブジェクトコードとは無関係のオブジェクトコードを前記サイクル数または命令数分だけ挿入するオブジェクトコード挿入部と、を備える。
【００１０】
また、本発明は、ソースプログラムに基づいて生成されるオブジェクトコードに従って演算処理を行う演算処理システムにおいて、前記ソースプログラム中に記述された、第１及び第２の演算指示情報と、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に開けるべきサイクル数または命令数とに基づいて、前記第１の演算指示情報に対応するオブジェクトコードと前記第２の演算指示情報に対応するオブジェクトコードとの間に、これらオブジェクトコードが使用するハードウェアリソースを使用せずに別のハードウェアリソースを使用する他のオブジェクトコードを前記サイクル数または命令数分だけ挿入したオブジェクトコード群に基づいて演算処理を行う演算処理部を備える。
【００１１】
【発明の実施の形態】
以下、本発明に係るコンパイラ、演算処理システム及び演算処理方法について、図面を参照しながら具体的に説明する。
【００１２】
図１は本発明に係るコンパイラの一実施形態の概略構成を示すブロック図である。図１のコンパイラは、パーソナルコンピュータ等のコンピュータ機器に読み込まれて実行されるプログラムであり、ユーザから与えられたＣ言語等で記述されたソースプログラムを、プロセッサが実行可能なオブジェクトコードに変換するものである。なお、コンパイラをハードウェアで実装することも可能である。この場合、プロセッサと同一チップに内蔵させてもよいし、プロセッサとは別チップに実装してもよい。
【００１３】
図１のコンパイラは、字句解析部１と、構文解析部２と、中間コード生成部３と、中間コード最適化部４と、コード生成部５と、コード最適化部６と、コード出力部７とを備えている。
【００１４】
字句解析部１は、ソースプログラムを意味のある最小単位である字句ごとに分割する。例えば図２のようなＣ言語のソースプログラムの場合、「ｖｏｉｄ」、「ｘ」、「（」、「）」、「｛」、「ｉｎｔ」、「ａ」、「；」、「｝」のそれぞれが字句である。
【００１５】
構文解析部２は、分割された字句それぞれが、ソースプログラムの言語で定められた文法に従って記述されているか否かをチェックする。この構文解析部２では、関数の各引数の記述に誤りがないか否かのチェックも行う。
【００１６】
中間コード生成部３は、アセンブリ言語よりも高水準で、高級言語よりも低水準の言語である中間コードを生成する。中間コード最適化部４は、１＋１のような定数同士の演算等の最適化を行う。
【００１７】
ソースプログラムから直接オブジェクトコードを生成せずに、いったん中間コードに変換するのは、高級言語が異なっていても中間コードは共通化でき、中間コードを生成してからオブジェクトコードを生成するまでの処理を複数の高級言語で共用できるためである。このため、中間コードの段階で命令の最適化処理を行うようにすれば、個々の高級言語ごとに別個に最適化処理を開発する必要がなくなる。
【００１８】
コード生成部５は、構文解析結果に基づいて、オブジェクトコードを生成する。コード最適化部６は、生成されたオブジェクトコードに対して最適化処理を行う。このコード最適化部６は、図１に示すように、命令検出部１１と、オブジェクトコード挿入部１２とを有する。
【００１９】
命令検出部１１は、ソースプログラムに後述する特定の関数が含まれているか否かを検出する。オブジェクトコード挿入部１２は、検出された特定の関数の引数に基づいて、一部のオブジェクトコードの移動やｎｏｐコードの挿入を行って、最終的なオブジェクトコードを生成する。生成されたオブジェクトコードは、コード出力部７から出力される。
【００２０】
なお、中間コードを生成せずに、ソースプログラムから直接オブジェクトコードを生成してもよい。この場合のブロック構成は図３のようになり、中間コード生成部３と中間コード最適化部４が不要になる。
【００２１】
図４は図１のコンパイラが生成したオブジェクトコードに基づいて演算処理を行うプロセッサシステムの概略構成を示すブロック図である。図示のように、メインの演算処理を行うコアプロセッサ１３と、コアプロセッサ１３とは別個に演算処理を行うプロセッサ外演算装置１４と、コアプロセッサ１３及びプロセッサ外演算装置により読み書きが可能なメモリ１５とを備えている。
【００２２】
以下に、本実施形態のコンパイラの使用方法について説明する。まず、単純な例として、コアプロセッサ１３に接続されるプロセッサ外演算装置１４のレジスタに、ｓｗ命令でデータを書き込んで演算を開始し、プロセッサ外演算装置１４のレジスタからｌｗ命令で演算結果を読み出す場合について説明する。ここでは、プロセッサ外演算装置１４のレジスタは、コアプロセッサ１３のメモリ空間上に固有のアドレスを持っているものとする。
【００２３】
例えば、プロセッサ外演算装置１４のレジスタ（アドレス０ｘ１０００番地）に値を書き込んで、その値を二乗する演算を開始し、演算結果をレジスタ（アドレス０ｘ１０００番地）に設定するものとする。これをＣ言語で記述すると、図５のようなソースプログラムになる。
【００２４】
図５のソースプログラムを所定のコアプロセッサ１３でコンパイルすると、図６のようなオブジェクトコードが得られる。なお、図６では、オブジェクトコードをアセンブリ言語で表している。
【００２５】
図６において、ａｄｄｉｕ　ｒ２，　ｒ０，　０ｘ１０００では、レジスタｒ２にレジスタｒ０＋０ｘ１０００を入れる。ここで、レジスタｒ０は常にゼロである。ｓｗ　ｒ４，　０　（ｒ２）では、レジスタｒ２のアドレスのメモリ１５に、レジスタｒ４の値（ソースプログラムのｐａｒａ）を書き込む。ｌｗ　ｒ２，　０　（ｒ２）では、レジスタｒ２のアドレスのメモリ１５から読み込んだ内容を、レジスタｒ２に入れる。ｊｒ　ｒａでは、関数を終了して、呼び出し元に戻る。
【００２６】
プロセッサ外演算装置１４の演算が　１サイクルで終了する場合は、図６のオブジェクトコードのままで特に問題ないが、例えば、上記の演算に必ず４サイクルかかり、ｓｗ命令とｌｗ命令の間を　３サイクル分（１命令の実行サイクル数が１の場合は３命令）空ける必要がある場合は、図７のようにソースプログラム中にｎｏｐ（）を記述する必要がある。
【００２７】
図７のｎｏｐ（）　は、組み込み関数（ｉｎｔｒｉｎｓｉｃｓ関数）によるｎｏｐ命令の記述である。図７のソースプログラムをコンパイルすると、図８に示すように、ｓｗ命令とｌｗ命令の間に３つのｎｏｐ命令が配置される。
【００２８】
図８のようなオブジェクトコードを得るには、予めプログラマがコアプロセッサ１３の処理スケジューリングを考慮に入れて、図７のようなソースプログラムを記述しなければならず、プログラマの負担が大きい。
【００２９】
そこで、本実施形態では、特定の関数形式（例えば、＿＿ｏｒｄｅｒ）によって命令スケジューリング情報をソースプログラム中に記述し、これにより、コンパイラにスケジューリングを行わせる点に特徴がある。このような特定の関数形式＿＿ｏｒｄｅｒを利用して図７のソースプログラムの書き直すと、図９のようになる。
【００３０】
図９のソースプログラムをコンパイルすると、図８と同様のコンパイル結果が得られる。
【００３１】
図９に示す＿＿ｏｒｄｅｒ　は、命令のスケジューリングを行うために独自に追加した予約語である。本実施形態では、特定の関数形式として＿＿ｏｒｄｅｒ　を使用しているが、ＩＳＯ／ＪＩＳ　Ｃ　言語規格　で規定されている予約語以外の任意の語句で表すことができる。
【００３２】
＿＿ｏｒｄｅｒ　は、関数コールの形式で記述される。より具体的には、＿＿ｏｒｄｅｒ　は３つの引数を持っており、第１引数と第２引数にはスケジューリングの対象となる式が記述され、第３引数には第１引数と第２引数から生成されたオブジェクトコードの間に開けるべき必要なサイクル数が記述される。すなわち、第１引数には第１の演算指示情報が記述され、第２引数には第２の演算指示情報が記述され、第３引数には、第１の演算指示情報に対応するオブジェクトコードと第２の演算指示情報に対応するオブジェクトコードとの間に開けるべきサイクル数が記述される。
【００３３】
図９のソースプログラムをコンパイルして得られる図８のオブジェクトコードは、ｓｗ命令とｌｗ命令の間に配置されたｎｏｐ命令を有するが、このｎｏｐ命令はコンパイラが自動的に挿入する。このため、プログラマが予めソースプログラムにｎｏｐ命令を記述する必要がなくなり、プログラムの開発負担を軽減できる。
【００３４】
また、ソースプログラム中の＿＿ｏｒｄｅｒ文の近くに、他の命令文が存在する場合は、ｓｗ命令とｌｗ命令とは無関係で、移動可能なｎｏｐ命令以外の命令を　ｓｗ命令とｌｗ命令の間に挿入する。これにより、生成されたオブジェクトコードの実行性能の向上とコードサイズの削減が図れる。
【００３５】
このように、ソースプログラム中に＿＿ｏｒｄｅｒ文があると、その第１引数に対応するオブジェクトコードと第２引数に対応するオブジェクトコードとの間に、これらオブジェクトコードとは無関係なオブジェクトコードが第３引数で指定されるサイクル数だけ挿入される。一例を具体的に説明すれば、第１引数に対応するオブジェクトコードと第２引数に対応するオブジェクトコードとの間に、これらオブジェクトコードが使用するハードウェアリソースを使用せずに別のハードウェアリソースを使用する他のオブジェクトコードが第３引数で指定されるサイクル数だけ挿入される。
【００３６】
図１０は＿＿ｏｒｄｅｒ文の近くに他の命令文ａｒｙ［ｘ］［ｙ］　＝　ｒｅｔが存在する場合のソースプログラムの一例を示している。図１０のソースプログラムは、配列ａｒｙ［ｘ］［ｙ］に演算結果を入れるものである。このソースプログラムをコンパイルし、ｓｗ命令と　ｌｗ命令の間にｎｏｐ命令を挿入すると、コンパイル結果を示すオブジェクトコードは図１１のようになる。
【００３７】
図１１において、ａｒｙ［ｘ］［ｙ］　＝　ｒｅｔのコンパイル結果は、ｌｗ　ｒ７，０（ｒ２）、ｓｌｌ　ｒ４，ｒ６，２、ｓｌｌ　ｒ８，ｒ５，４、ａｄｄｉｕ　ｒ３，ｇｐ，ｓｄａｏｆｆ（＿ａｒｙ）、ａｄｄｕ　ｒ２，ｒ３，ｒ８、ａｄｄｕ　ｒ２，ｒ２，ｒ４である。ｌｗ　ｒ７，０（ｒ２）では、レジスタｒ２のアドレスのメモリ１５から読み込んだ内容をレジスタｒ７に入れる。ｓｌｌ　ｒ４，ｒ６，２では、図１０のソースプログラム中のｙを記憶しているレジスタｒ６を左に２ビットシフトして、レジスタｒ４に入れる。すなわち、ｙを４倍する。ｓｌｌ　ｒ８，ｒ５，４では、ソースプログラム中のｘを記憶しているレジスタｒ５を左に４ビットシフトして、レジスタｒ８に入れる。すなわち、ｘを１６倍する。ａｄｄｉｕ　ｒ３，ｇｐ，ｓｄａｏｆｆ（＿ａｒｙ）では、レジスタｇｐとｓｄａｏｆｆ（＿ａｒｙ）を加算して、＿ａｒｙの先頭アドレスをレジスタｒ３に入れる。ａｄｄｕ　ｒ２，ｒ３，ｒ８では、レジスタｒ３とｒ８を加算して、レジスタｒ２に入れる。これにより、ａｒｙ［ｘ］［０］のアドレスが計算される。ａｄｄｕ　ｒ２，ｒ２，ｒ４では、レジスタｒ２とｒ４を加算して、レジスタｒ２に入れる。これにより、ａｒｙ［ｘ］［ｙ］のアドレスが計算される。
【００３８】
これら命令列のうち、ｓｌｌ　ｒ４，ｒ６，２やｓｌｌ　ｒ８，ｒ５，４は、ｌｗ　ｒ７，０（ｒ２）の演算処理とは無関係に実行可能である。そこで、本実施形態のコンパイラは、図１１のオブジェクトコードの一部の命令列の順序を入れ替えて、図１２のようなオブジェクトコードを生成する。図１２では、ｓｗ　ｒ４，０（ｒ２）とｌｗ　ｒ７，０（ｒ２）との間に、ｓｌｌ　ｒ４，ｒ６，２、ｓｌｌ　ｒ８，ｒ５，４及びａｄｄｉｕ　ｒ３，ｇｐ，ｓｄａｏｆｆ（＿ａｒｙ）を配置する。
【００３９】
図１１のオブジェクトコードは１４命令で構成されるのに対し、図１２のオブジェクトコードは１１命令で構成されている。
【００４０】
このように、本実施形態のコンパイラは、＿＿ｏｒｄｅｒの近くに、無関係な命令文が存在する場合には、この無関係な命令をｎｏｐ命令の代わりに挿入するため、生成されるオブジェクトコードの実行性能が向上し、かつ命令数も削減できるため、コードサイズを減少させることができる。
【００４１】
これに対して、プログラマがＣ言語等のソースプログラムの中で命令スケジューリングを行う場合、図１３のようにソースプログラムの記述を修正する必要がある。図１３では、＊ｐ＝ｐａｒａでメモリ１５にｐａｒａを入力した後に、ａｐ＝＆ａｒｙ［ｘ］［ｙ］を挿入して、ａｒｙ［ｘ］［ｙ］のアドレスを求めてａｐに入れる処理を行っている。
【００４２】
図１３のように、プログラマ自身でソースプログラムの記述を修正すると、プログラマの負担が大きくなる。また、ソースプログラム上でスケジューリングを行っても、コンパイラの最適化処理により、期待した通りのオブジェクトコードが生成されない場合もある。
【００４３】
本実施形態では、プログラマがソースプログラムを修正するのではなく、プログラマはコンパイラに命令のスケジューリング情報を与えるだけである。このスケジューリング情報に基づいて、コンパイラは無関係で移動可能な命令を見つけて、指定された２つの演算命令中に挿入する。また、コンパイラは、無関係で移動可能な命令が必要サイクル分見つからない場合のみ、ｎｏｐを挿入する。
【００４４】
図１のコンパイラは、ソースプログラム中に上述した特定の関数＿＿ｏｒｄｅｒを見つけると、以下のような処理を行う。字句解析部１は、＿＿ｏｒｄｅｒを予約語として認識する。構文解析部２はまず、＿＿ｏｒｄｅｒの各引数の記述内容をチェックし、第１及び第２引数が意味のある式であるか否かをチェックする。例えば、＿＿ｏｒｄｅｒ（１，　２，　３）のように第１及び第２引数に定数が記述されている場合、スケジューリングすべき命令が生成されないので、エラーとする。また、第３引数が正の整数型定数であるか否かをチェックする。第３引数に定数以外の変数などを記述した場合、コンパイル時にはその値がわからないので、エラーとする。
【００４５】
中間コードを生成する場合は、第１及び第２引数の式から生成される通常の中間コードと、この中間コードの前後に＿＿ｏｒｄｅｒで記述されたことを示す目印となる中間コードと、＿＿ｏｒｄｅｒの第３引数で指定された値を示す中間コードとが中間コード生成部３にて生成される。
【００４６】
コード生成部５は、＿＿ｏｒｄｅｒの第１及び第２引数に基づいてオブジェクトコードを生成する。＿＿ｏｒｄｅｒで付加されたことを示す目印となる中間コードと第３引数の値を示す中間コードはオブジェクトコードには変換されないが、第１及び第２引数に基づいて生成されたオブジェクトコードに関連するデータとして記憶される。
【００４７】
コード最適化部６は、＿＿ｏｒｄｅｒで付加されたことを示す目印と第３引数に基づいて、命令のスケジューリングを行う。
【００４８】
図１４はコード最適化部６の処理手順を示すフローチャートである。まず、＿＿ｏｒｄｅｒの第１引数から生成されたオブジェクトコードで定義されたリソース（例えば、レジスタやメモリ１５など）ｄ１と、演算に使用するリソースｕ１とを求める（ステップＳ１）。例えば、図１２では、第１引数から生成されたオブジェクトコードは　ｓｗ　ｒ４，０（ｒ２）　で、この命令の定義するリソース　ｄ１はメモリ１５で、使用するリソース　ｕ１は　ｒ４，ｒ２である。
【００４９】
＿＿ｏｒｄｅｒの第１引数から生成されたオブジェクトコードの直前に配置された命令を別の場所に移動可能か否かを調べる（ステップＳ２）。分岐命令等の移動不可能な命令の場合は、＿＿ｏｒｄｅｒの前方からの移動は不可能なので、第２引数から生成されたオブジェクトコードの後方からの命令移動の処理に移る。
【００５０】
直前の命令が移動可能である場合、この命令が定義するリソース　ｄ２と使用するリソース　ｕ２　を求める（ステップＳ３）。図１２の場合、直前の命令は　ａｄｄｉｕｒ２，ｒ０，０ｘ１００００　で、この命令の定義するリソース　ｄ２はｒ２で、使用するリソースはなしである。ｒ０は常に０のレジスタで、０ｘ１００００は定数のオペランドなので、リソースに含めない。
【００５１】
次に、直前の命令に関するリソースｄ２，ｕ２が、第１引数から生成されたオブジェクトコードのリソースｄ１，ｕ１と衝突するか否かを調べる（ステップＳ４）。リソースが衝突しない場合は移動可能と判断する。
【００５２】
ここで、リソースが衝突していないという条件は、ｄ１　と　ｕ１　の論理和と　ｄ２　の論理積が空であり（（ｄ１｜ｕ１）　＆　ｄ２）、かつ、ｄ１　と　ｕ２　の論理（ｄ１　＆　ｕ２）積が空である場合である。図１２の場合、リソースｕ１とｄ２がともにｒ２であり、リソースが衝突するため、移動ができない。
【００５３】
移動可能であると判断されると、直前の命令を、第１引数から生成されたオブジェクトコードと第２引数から生成されたオブジェクトコードの間に移動させる（ステップＳ５）。この命令の移動によって、指定したサイクル数分の命令を移動させた場合は、スケジューリングは終了である。まだ、第３引数で指定した指定したサイクル数分の命令を移動していない場合は、更に前方の命令が移動できるかを調べる（ステップＳ６）。
【００５４】
ステップＳ４でリソースが衝突すると判断されると、移動不可能と判断して（ステップＳ７）、リソースの集合を論理和でまとめる（ステップＳ８）。定義するリソースはｄ１　にまとめ　（ｄ１　＝　ｄ１　｜　ｄ２）、使用するリソース　はｕ１　にまとめる（ｕ１　＝　ｕ１　｜　ｕ２）。これにより、リソース　ｄ１，ｕ１が移動される間にある命令のリソースとなるので、次の直前の命令が移動可能かどうかを調べる場合にも、ｄ１，ｕ１　だけを調べるだけでよい。
【００５５】
図１２でのリソースをまとめた結果、定義するリソースｄ１はレジスタｒ２とメモリ１５、使用するリソースｕ１は　レジスタｒ４，ｒ２である。ステップＳ８の処理が終了すると、ステップＳ２以降の処理を行う。
【００５６】
一方、第１引数から生成されたオブジェクトコードの前方の命令だけでは、指定したサイクル数分の命令が挿入できなかった場合、あるいは、＿＿ｏｒｄｅｒの第１引数から生成されたオブジェクトコードの直前に配置された命令を別の場所に移動できないと判断された場合は、第２引数から生成されたオブジェクトコードの後方の命令についてもスケジューリングの対象とする。例えば、図１２の場合、ａｄｄｉｕ命令の直前の命令は存在しないので、第２引数から生成されたオブジェクトコード群の後方の命令についてスケジューリングの対象とする。
【００５７】
まず、第２引数から生成されたオブジェクトコードが定義するリソースｄ３と使用するリソースｕ３　を求める（ステップＳ９）。図１２では、第２引数から生成されたオブジェクトコードは　ｌｗ　ｒ７，０（ｒ２）であるので、定義するリソース　ｄ３は　レジスタｒ７，使用するリソース　ｕ３　はレジスタｒ２となる。第２引数から生成されたオブジェクトコードの直後の命令が移動可能か否かを調べる（ステップＳ１０）。
【００５８】
分岐命令など移動不可能な命令の場合は、もう移動できる命令がないので、第３引数で指定したサイクル数分に足らない分だけｎｏｐ命令を挿入し（ステップＳ１１，Ｓ１２）、このスケジューリングを終了する。
【００５９】
直後の命令が移動可能である場合、この命令の定義するリソース　ｄ４　と使用するリソース　ｕ４　を求める（ステップＳ１３）。図１２では、では、直後の命令はｓｌｌ　ｒ４，ｒ６，２　で、定義するリソース　ｄ４　は　ｒ４、使用するリソース　ｕ４は　ｒ６、メモリ１５である。
【００６０】
次に、直前の命令に関するリソースｄ４，ｕ４が、第１引数から生成されたオブジェクトコードのリソースｄ３，ｕ３と衝突するか否かを調べる（ステップＳ１４）。リソースが衝突しない場合は移動可能と判断する。
【００６１】
ここで、リソースが衝突していないという条件は、ｄ３　と　ｕ３　の論理和と　ｄ４　の論理積が空であり（（ｄ３｜ｕ３）　＆　ｄ４）、かつ、ｄ３　と　ｕ４　の論理積（ｄ３　＆　ｕ４）が空である場合である。図１２では、ｌｗ　ｒ７，０（ｒ２）とｓｌｌ　ｒ４，ｒ６，２に衝突するリソースはないので、ｓｌｌ　ｒ４，ｒ６，２は移動可能である。
【００６２】
移動可能であると判断されると、直前の命令を、第１引数から生成されたオブジェクトコードと第２引数から生成されたオブジェクトコードの間に移動させる（ステップＳ１５）。この命令の移動によって、指定したサイクル数分の命令を移動させた場合は、スケジューリングは終了である。まだ、第３引数で指定した指定したサイクル数分の命令を移動していない場合は、更に前方の命令が移動できるかを調べる（ステップＳ１６）。
【００６３】
ステップＳ１４でリソースが衝突すると判断されると、移動不可能と判断して（ステップＳ１７）、リソースの調停処理を行った後（ステップＳ１８）、ステップＳ１０以降の処理を行う。
【００６４】
図１４のフローチャートでは、第１引数の前から移動させる方を先に行ったが、第２引数の後ろから移動させる方を先に行った場合でも、同様の最適化処理が可能である。
【００６５】
なお、第３引数のサイクル数の定義は、第１引数から生成されたオブジェクトコード群の最後から　第２引数から生成されたオブジェクトコード群の先頭までに必要なサイクル数とするのが普通である。しかし、このスケジューリング機能の外部仕様として、第１引数から生成されたオブジェクトコード群の最後から　第２引数から生成されたオブジェクトコード群の最後までに必要なサイクル数と定義することもまた可能である。これは、双方の最後の命令がスケジューリング対象の命令となっていると仮定して、サイクル数をカウントしている。
【００６６】
また、コンパイル時に　命令のサイクル数の見積が困難な場合は、第３引数をサイクル数から命令数にしてもよい。
【００６７】
図１４のフローチャートの処理手順をコンパイラに実装することによって、＿＿ｏｒｄｅｒ　で指定した命令形式の命令スケジューリングを行うことが可能となる。
【００６８】
このように、第１の実施形態では、特定の関数に基づいて、リソースが衝突しないように命令の順序を入れ替えるため、ｎｏｐ命令を入れる必要がなくなり、オブジェクトコードの実行性能の向上が図れる。また、オブジェクトコードのサイズも削減できる。
【００６９】
（第２の実施形態）
第１の実施形態では、ソースプログラムに記述された特定の関数（例えば、＿＿ｏｒｄｅｒ）に基づいて命令スケジューリングを行う例を説明したが、別の記述方法で命令スケジューリングを行うことも可能である。
【００７０】
＃ｐｒａｇｍａ　は、ＩＳＯ／ＪＩＳＣ言語規格に規定されている前処理指令の一つであり、処理系によって独自の拡張が許されている。本実施形態では、＃ｐｒａｇｍａ　の後に　ｏｒｄｅｒ　を付加した　＃ｐｒａｇｍａ　ｏｒｄｅｒ　を用いて　命令スケジューリングの指定を行う。
【００７１】
図９のソースプログラムを　＃ｐｒａｇｍａ　ｏｒｄｅｒ　を用いて書き直すと、図１５のようになる。
【００７２】
「＃ｐｒａｇｍａ　ｏｒｄｅｒ　｛」と「＃ｐｒａｇｍａ　ｏｒｄｅｒ　３」によって挟まれた式が前半の式で、「＃ｐｒａｇｍａ　ｏｒｄｅｒ　３」と「＃ｐｒａｇｍａ　｝」によって挟まれた式が後半の式である。その間の「＃ｐｒａｇｍａ　ｏｒｄｅｒ　３」で示された３の定数値が、前半の式と後半の式の間に挿入すべきサイクル数の指定である。４サイクル必要な場合は、「＃ｐｒａｇｍａ　ｏｒｄｅｒ　４」と記載される。
【００７３】
第１及び第２の実施形態からわかるように、ソースプログラム中に記述する必要がある付加情報は、スケジューリングすべき第１及び第２の演算指示情報とその間に挿入すべき実行サイクル数である。これらの情報をどのような形態で実現するかは特に問わない。
【００７４】
図１のコンパイラは、ソースプログラム中の＃ｐｒａｇｍａ　ｏｒｄｅｒを以下の手順で処理する。
【００７５】
字句解析部１は、字句分割を行って、＃ｐｒａｇｍａ　ｏｒｄｅｒ文を見つける。構文解析部２は、＃ｐｒａｇｍａ　ｏｒｄｅｒ文の記述内容を調べる。まず、｛　，定数，｝　の順で並んでいるかをチェックする。＃ｐｒａｇｍａ　ｏｒｄｅｒ文の先頭部分が「＃ｐｒａｇｍａ　ｏｒｄｅｒ　｛」と記述されていない場合や、｛，定数，｝の途中で　関数の定義が終了した場合などは、エラーである。また、＃ｐｒａｇｍａ　ｏｒｄｅｒ　を関数定義中以外で使用した場合もエラーである。定数は、正の整数型定数であるか否かをチェックする。
【００７６】
＃ｐｒａｇｍａ　ｏｒｄｅｒ文で挟まれた　前半と後半の二つの式についても、構文解析部２でチェック可能であれば、＃ｐｒａｇｍａ　ｏｒｄｅｒに特有のチェックを行う。しかし、コンパイラの実装上、構文解析部２で式の内容がチェックできない場合などは、後段側のコード生成部５などでチェックを行ってもよい。チェックすべき項目は、スケジューリングすべき意味がある式が記述されているかどうかである。前半、後半の式が記述されていなかったり、意味がないため生成されるオブジェクトコードがないような式を記述した場合は、エラーとなる。
【００７７】
＃ｐｒａｇｍａ　ｏｒｄｅｒから生成される中間コードは、＃ｐｒａｇｍａ　ｏｒｄｅｒの前方の式から生成される中間コードと後方の式から生成される中間コードとの間に付加される。＃ｐｒａｇｍａ　ｏｒｄｅｒから生成される中間コードは、＃ｐｒａｇｍａ　ｏｒｄｅｒの前方と後方の式から生成されたことを示すための目印と挿入すべきサイクル数を示す値とを意味する。
【００７８】
中間コードを生成した段階では、第１の実施形態と同じコードになる。このため、以下のコード生成部５、コード最適化部６の構成は第１の実施形態と同じである。
【００７９】
このように、第２の実施形態では、Ｃ言語等の高級言語で規定されている前処理指令を用いて、オブジェクトコード間のサイクル数を指定するため、第１の実施形態のような関数形式で記述するのと同様に、オブジェクトコードの実行性能の向上とオブジェクトコードサイズの削減が図れる。
【００８０】
（第３の実施形態）
第３の実施形態は、図４で示したプロセッサ外演算装置として、コプロセッサを用いたものである。
【００８１】
図１６はコアプロセッサ１３にコプロセッサ１６とメモリ１５が接続されているプロセッサシステムの一例を示すブロック図である。
【００８２】
図１６のコプロセッサ１６のレジスタにアクセスするための命令は、メモリ１５にアクセスするためのロード命令やストア命令とは異なる。このため、コンパイラが自動的に命令スケジューリングができる可能性もあるが、コプロセッサ１６の演算の種類によって、演算サイクルが異なる場合には、コンパイラが自動的にスケジューリングするのは一般には困難である。
【００８３】
本実施形態は、このような場合でも、プログラマがコプロセッサ１６の演算の種類に応じたサイクル数を予めソースプログラム中に指定することにより、コンパイラが最適な命令スケジューリングを行うことができる。
【００８４】
図１７のソースプログラムは、コプロセッサ１６のレジスタの書き込みにＣＴＣ２命令を用い、コプロセッサ１６の演算の実行にＣＯＰ２命令を用い、コプロセッサ１６のレジスタの読込みにＣＦＣ２命令を用い、組み込み関数（ｉｎｔｒｉｎｓｉｃｓ関数）を用いてＣ言語で記述した従来の記述例である。
【００８５】
図１７のソースプログラムでは、コプロセッサ１６のレジスタ２に演算パラメータを設定し、ｃｏｐ２命令で設定されるパラメータ（ｆｕｎｃｔｉｏｎ　ｎｕｍｂｅｒ）が１で演算を開始し、より具体的には例えば、コプロセッサ１６のレジスタ２から値を読み込んで、その値を二乗する演算を行い、その演算結果を４サイクル後にコプロセッサ１６のレジスタ１へ書き込む。図１７の場合、コプロセッサ１６の演算に時間がかかるため、３つのｎｏｐ命令を挿入する必要がある。
【００８６】
この例を　＿＿ｏｒｄｅｒ　を用いて記述すると、図１８のようになる。
【００８７】
図１８のソースプログラムをコンパイルすると、図１９のようなオブジェクトコードが生成される。
【００８８】
図１９の例では、挿入すべき無関係な命令がないため、４つのｎｏｐ命令が挿入されている。
【００８９】
次に無関係な命令を入れた場合の例を挙げる。図２０は、配列ａｒｙ［ｘ］［ｙ］に演算結果を入れるプログラムを示している。
【００９０】
図２０のコンパイル結果は、図２１のようになる。図２０のａｒｙ［ｘ］［ｙ］＝ｒｅｔは、図２１の５つの命令ｓｌｌ　ｒ４，ｒ６，２、ｓｌｌ　ｒ８，ｒ５，４、ａｄｄｉｕ　ｒ３，ｇｐ，ｓｄａｏｆｆ（＿ａｒｙ）、ａｄｄｕ　ｒ２，ｒ３，ｒ８、ａｄｄｕ　ｒ２，ｒ２，ｒ４に相当し、そのうちの前者３つがｃｏｐ２（１）とｃｆｃ２　ｒ７，１の間に挿入される。
【００９１】
これにより、図１９のようにｎｏｐ命令を挿入する必要がなくなり、生成されるオブジェクトコードの実行性能が向上し、ｎｏｐ命令が減る分、コードサイズも削減できる。
【００９２】
このように、第３の実施形態では、コプロセッサ１６に対して演算を行わせるためのオブジェクトコードを生成する場合でも、オブジェクトコードの実行性能の向上とオブジェクトコードサイズの削減が図れる。
【００９３】
（第４の実施形態）
あるアプリケーション・プログラムで、非常によく利用される関数、すなわちプログラム全体の実行時間に占める割合が大きい関数を、コアプロセッサ１３の通常命令による演算からハードウェアでの演算に置き換えることにより、アプリケーション・プログラムの全体の性能向上を図ることができる。
【００９４】
図２２はソースプログラムの一例であり、このプログラム中で、ｍｕｌ２５５が非常によく利用される関数であると仮定する。この場合、関数ｍｕｌ２５５をハードウェア化したプロセッサ外演算装置をコアプロセッサ１３に接続する。この演算装置で関数ｍｕｌ２５５の演算処理を実行する場合の外部仕様を以下のように定める。
【００９５】
関数ｍｕｌ２５５の引数ａ　を設定するレジスタのアドレスが　０ｘ１０００　番地、引数　ｂ　を設定するレジスタのアドレスが　０ｘ１００４番地、演算結果を受け取るレジスタのアドレスが　０ｘ１０００番地とする。
【００９６】
プロセッサ外演算装置は、０ｘ１０００番地のレジスタに値が書き込まれた場合、既に０ｘ１００４番地のレジスタに設定してある内容と０ｘ１０００番地のレジスタに書き込まれた内容とを乗算し、この乗算結果が２５５以下の場合はその値のまま、２５６以上の場合は２５５　を０ｘ１０００番地のレジスタに設定する。演算にかかるサイクル数は、０ｘ１０００番地のレジスタに書き込んでから、０ｘ１０００番地のレジスタから演算結果を受け取るまで、４サイクル必要とする。
【００９７】
プログラマは、このような演算装置の仕様に従って関数ｍｕｌ２５５の記述を変更する必要がある。＿＿ｏｒｄｅｒを用いて関数ｍｕｌ２５５を記述すると、図２３のようになる。
【００９８】
ところが、図２３のように関数の内部をレジスタのアクセスに変更しただけでは、＿＿ｏｒｄｅｒの前後に無関係な命令が存在しないため、ｎｏｐ命令が挿入される可能性が高い。図２３のソースプログラム　をコンパイルすると図２４のようになり、ｎｏｐ命令が挿入され、実行性能が落ち、かつコードサイズも増大する。
【００９９】
ｎｏｐ命令の挿入を避けるためには、記述を変更した関数ｍｕｌ２５５をインライン関数として宣言する必要がある。インライン関数にすると、関数コールでなく、関数を呼び出した場所に関数の中身が展開される。このようにすると、展開の前後に無関係な命令が存在する可能性が高くなり、その結果、＿＿ｏｒｄｅｒでｎｏｐ命令が挿入される可能性が低くなる。なお、インライン関数は、Ｃ言語では　ＩＳＯ／ＩＥＣ　９８９９：１９９９　で追加された機能で、以前の仕様　ＩＳＯ／ＩＥＣ　９８９９：１９９０　には存在していない。
【０１００】
上述した関数ｍｕｌ２５５　をインライン関数として記述すると、図２５のようになり、関数ｍｕｌ２５５の先頭に　インライン関数の目印であるｉｎｌｉｎｅ　が追加されている。
【０１０１】
上記の例のインライン関数を図２２の関数ｔｅｓｔに適用した場合のコンパイル結果は、図２６のようになる。ｓｗ　ｒ２，０（ｒ５）とｌｗ　ｒ１，０（ｒ５）との間に無関係な３命令ｓｌｌ　ｒ３，ｒ２，３、ａｄｄｉｕ　ｒ６，ｇｐ，ｓｄａｏｆｆ（＿ａｒｙ）、ａｄｄｕ　ｒ３，ｒ６，ｒ３が挿入され、また、ｓｗｒ２，０（ｒ５）とｌｗ　ｒ１，０（ｒ５）の間にも無関係な３命令ｓｌｌ　ｒ３，ｒ２，３、ａｄｄｉｕ　ｒ６，ｇｐ，ｓｄａｏｆｆ（＿ａｒｙ＋４）、ａｄｄｕ　ｒ３，ｒ６，ｒ３が挿入されている。これにより、ｎｏｐ命令を挿入する必要がなくなる。
【０１０２】
このように、第４の実施形態では、コアプロセッサ１３とは別の演算装置（プロセッサ外演算装置１４）を制御する関数をｉｎｌｉｎｅ関数として指定することにより、展開される周囲に無関係な命令が存在する可能性が高くなり、第１〜第３の実施形態と同様に、オブジェクトコードの実行性能の向上とオブジェクトコードサイズの削減が図れる。
【０１０３】
【発明の効果】
以上詳細に説明したように、本発明によれば、特定の関数に基づいて、リソースが衝突しないように命令の順序を入れ替えるため、ｎｏｐ命令を入れる必要がなくなり、オブジェクトコードの実行性能の向上が図れる。また、オブジェクトコードのサイズも削減できる。
【図面の簡単な説明】
【図１】本発明に係るコンパイラの一実施形態の概略構成を示すブロック図。
【図２】Ｃ言語のソースプログラムの一例を示す図。
【図３】中間コードを生成しないコンパイラの一実施形態の概略構成を示すブロック図。
【図４】図１のコンパイラが生成したオブジェクトコードに基づいて演算処理を行うプロセッサシステムの概略構成を示すブロック図。
【図５】Ｃ言語のソースプログラムの一例を示す図。
【図６】図５に対応するオブジェクトコードを示す図。
【図７】図５のソースプログラム中にｎｏｐ（）を追加した例を示す図。
【図８】図７に対応するオブジェクトコードを示す図。
【図９】図７のソースプログラムを＿＿ｏｒｄｅｒを用いて書き直したソースプログラムを示す図。
【図１０】＿＿ｏｒｄｅｒ文の近くに他の命令文ａｒｙ［ｘ］［ｙ］　＝　ｒｅｔが存在する場合のソースプログラムの一例を示す図。
【図１１】図１０のソースプログラムのコンパイル結果を示すオブジェクトコードを示す図。
【図１２】図１１のオブジェクトコードの一部の命令列の順序を入れ替えた図。
【図１３】プログラマがソースプログラムの記述を修正した例を示す図。
【図１４】コード最適化部６の処理手順を示すフローチャート。
【図１５】図９のソースプログラムを　＃ｐｒａｇｍａ　ｏｒｄｅｒ　を用いて書き直した図。
【図１６】コアプロセッサ１３にコプロセッサ１６とメモリ１５が接続されているプロセッサシステムの一例を示すブロック図。
【図１７】コプロセッサに演算をさせる場合のソースプログラムの一例を示す図。
【図１８】図１７のソースプログラムを＿＿ｏｒｄｅｒを用いて書き直した例を示す図。
【図１９】図１８のソースプログラムをコンパイルしたオブジェクトコードを示す図。
【図２０】配列ａｒｙ［ｘ］［ｙ］に演算結果を入れるプログラムを示す図。
【図２１】図２０のコンパイル結果を示す図。
【図２２】関数ｍｕｌ２５５が記述されたソースプログラムの一例を示す図。
【図２３】＿＿ｏｒｄｅｒを用いて関数ｍｕｌ２５５を記述した例を示す図。
【図２４】図２３のソースプログラムのコンパイル結果を示す図。
【図２５】関数ｍｕｌ２５５　をインライン関数として記述した例を示す図。
【図２６】図２５のインライン関数のコンパイル結果を示す図。
【図２７】ｍｕｌ命令とｍｆｌｏ命令の間に無関係な命令を３命令を入れたオブジェクトコードの一例を示す図。
【図２８】ｓｗ命令とｌｗ命令の間に３つのｎｏｐ命令を入れたオブジェクトコードの一例を示す図。
【符号の説明】
１　字句解析部
２　構文解析部
３　中間コード生成部
４　中間コード最適化部
５　コード生成部
６　コード最適化部
７　コード出力部
１１　命令検出部
１２　オブジェクトコード挿入部
【図１】
2004038279.tif 000003
【図２】
2004038279.tif 000004
【図３】
2004038279.tif 000005
【図４】
2004038279.tif 000006
【図５】
2004038279.tif 000007
【図６】
2004038279.tif 000008
【図７】
2004038279.tif 000009
【図８】
2004038279.tif 000010
【図９】
2004038279.tif 000011
【図１０】
2004038279.tif 000012
【図１１】
2004038279.tif 000013
【図１２】
2004038279.tif 000014
【図１３】
2004038279.tif 000015
【図１４】
2004038279.tif 000016
【図１５】
2004038279.tif 000017
【図１６】
2004038279.tif 000018
【図１７】
2004038279.tif 000019
【図１８】
2004038279.tif 000020
【図１９】
2004038279.tif 000021
【図２０】
2004038279.tif 000022
【図２１】
2004038279.tif 000023
【図２２】
2004038279.tif 000024
【図２３】
2004038279.tif 000025
【図２４】
2004038279.tif 000026
【図２５】
2004038279.tif 000027
【図２６】
2004038279.tif 000028
【図２７】
2004038279.tif 000029
【図２８】
2004038279.tif 000030