(57)【要約】【課題】変更があったソースプログラムのみを再コンパイルするだけで所望のオブジェクトファイルを生成可能なコンパイル装置を提供する。【解決手段】関数実行で破壊されるレジスタの情報が記憶されていている関数破壊レジスタテーブル１１５と、関数実行で破壊されてはならないレジスタの情報が記憶されている関数非破壊レジスタテーブル１１６と、前記ソースプログラムに含まれる各関数を中間コードに変換する入力部１０７と、前記レジスタの情報に基づいて、前記中間コードに含まれる各関数の変数にレジスタを割り付けるレジスタ割り付け部１１０と、レジスタ割り付け後の関数について、破壊されるレジスタおよび破壊されてはならないレジスタの情報を関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６にそれぞれ登録する関数破壊レジスタ登録部１１３および関数呼び出し非破壊レジスタ登録部１１１とを備える。【選択図】        図１
2004362056.tif 000002
【特許請求の範囲】
【請求項１】
ソースプログラムを機械語命令列からなるオブジェクトプログラムに翻訳するコンパイル装置であって、
関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報が記憶されている破壊レジスタテーブルと、
関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報が記憶されている非破壊レジスタテーブルと、
前記ソースプログラムに含まれる各関数を中間コードに変換する中間コード変換手段と、
前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報に基づいて、前記中間コードに含まれる各関数の変数にレジスタを割り付けるレジスタ割り付け手段と、
レジスタが割り付けられた各関数について、当該関数に含まれる各レジスタの値が当該関数内で破壊される場合には、当該関数名と値が破壊されるレジスタのレジスタ名とを対応付けた関数破壊レジスタ情報を前記破壊レジスタテーブルに追加する破壊レジスタ追加手段と、
レジスタが割り付けられた各関数について、当該関数に含まれる各レジスタの生存区間内に関数呼び出しがある場合には、呼び出される関数名と当該レジスタのレジスタ名とを対応付けた関数非破壊レジスタ情報を前記非破壊レジスタテーブルに追加する非破壊レジスタ追加手段と、
前記中間コードを機械語命令列に変換し、前記機械語命令列からなるオブジェクトプログラムを出力する出力手段とを備える
ことを特徴とするコンパイル装置。
【請求項２】
前記レジスタ割り付け手段は、着目している関数の関数名が前記非破壊レジスタテーブルに登録されている場合には、前記着目している関数を実行することにより破壊されてはならないレジスタを破壊しないようにレジスタ割り付けを行なう
ことを特徴とする請求項１に記載のコンパイル装置。
【請求項３】
前記レジスタ割り付け手段は、着目している関数内で呼び出される関数が前記破壊レジスタテーブルに登録されている場合には、当該関数を呼び出すことにより、前記着目している関数に含まれる変数の値が破壊されないようにレジスタ割り付けを行なう
ことを特徴とする請求項１または２に記載のコンパイル装置。
【請求項４】
さらに、着目している関数内で値が破壊されるレジスタを求め、当該関数名と当該レジスタ名とが前記非破壊レジスタテーブルに登録されている場合には、当該レジスタの値が破壊されるよりも前に当該レジスタの値を退避させる命令を前記中間コードに挿入し、当該レジスタの値を破壊し終わった後に退避した前記値を当該レジスタに復帰させる命令を当該中間コードに挿入する退避・復帰命令挿入手段を備える
ことを特徴とする請求項１〜３のいずれかに記載のコンパイル装置。
【請求項５】
前記破壊レジスタ追加手段は、着目している関数内に関数呼び出しが含まれる場合には、前記着目している関数の関数名と呼び出される関数において値が破壊されるレジスタのレジスタ名とを対応付けた関数破壊レジスタ情報を前記破壊レジスタテーブルに追加する
ことを特徴とする請求項１〜４のいずれかに記載のコンパイル装置。
【請求項６】
前記出力手段は、
前記中間コードを前記オブジェクトプログラムに変換し、前記オブジェクトプログラムをファイルに格納して出力するオブジェクトプログラム出力手段と、
前記破壊レジスタテーブルおよび前記非破壊レジスタテーブルにそれぞれ登録されている関数破壊レジスタ情報および関数非破壊レジスタ情報を前記ファイルとは異なるファイルに格納して出力するレジスタ情報出力手段とを有する
ことを特徴とする請求項１〜５のいずれかに記載のコンパイル装置。
【請求項７】
前記出力手段は、前記オブジェクトプログラムと、前記破壊レジスタテーブルおよび前記非破壊レジスタテーブルにそれぞれ登録されている前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報とを同一のファイルに格納して出力する
ことを特徴とする請求項１〜５のいずれかに記載のコンパイル装置。
【請求項８】
さらに、他のオブジェクトプログラムとともにファイルに格納されている関数破壊レジスタ情報および関数非破壊レジスタ情報を読み込み、前記破壊レジスタテーブルおよび前記非破壊レジスタテーブルにそれぞれ追加する関数情報入力手段を備える
ことを特徴とする請求項６または７に記載のコンパイル装置。
【請求項９】
前記関数情報入力手段は、前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されている場合には、エラーメッセージを出力する
ことを特徴とする請求項８に記載のコンパイル装置。
【請求項１０】
前記非破壊レジスタ追加手段は、レジスタ名を追加する際に、関数呼び出し規約で常に値が保証されるレジスタ以外のレジスタ名を追加する
ことを特徴とする請求項１〜９のいずれかに記載のコンパイル装置。
【請求項１１】
前記破壊レジスタ追加手段は、レジスタ名を追加する際に、標準的に値が破壊されるレジスタ以外のレジスタ名を追加する
ことを特徴とする請求項１〜１０のいずれかに記載のコンパイル装置。
【請求項１２】
さらに、前記ソースプログラムに含まれる関数間の呼び出し関係を解析する呼び出し関係解析手段と、
前記呼び出し関係解析手段の出力に基づいて、関数の処理順序を決定する処理順序決定手段とを備え、
前記レジスタ割り付け手段は、前記処理順序決定手段で定められた前記処理順序に従い、各関数の変数にレジスタを割り付ける
ことを特徴とする請求項１〜１１のいずれかに記載のコンパイラ装置。
【請求項１３】
ソースプログラムを機械語命令列からなるオブジェクトプログラムに翻訳するコンパイル装置で用いられるコンパイル方法であって、
前記コンパイル装置は、
関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報が記憶されている破壊レジスタテーブルと、
関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報が記憶されている非破壊レジスタテーブルとを備え、
前記ソースプログラムに含まれる各関数を中間コードに変換するステップと、
前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報に基づいて、前記中間コードに含まれる各関数の変数にレジスタを割り付けるステップと、
レジスタが割り付けられた各関数について、当該関数に含まれる各レジスタの値が当該関数内で破壊される場合には、当該関数名と値が破壊されるレジスタのレジスタ名とを対応付けた関数破壊レジスタ情報を前記破壊レジスタテーブルに追加するステップと、
レジスタが割り付けられた各関数について、当該関数に含まれる各レジスタの生存区間内に関数呼び出しがある場合には、呼び出される関数名と当該レジスタのレジスタ名とを対応付けた関数非破壊レジスタ情報を前記非破壊レジスタテーブルに追加するステップと、
前記中間コードを機械語命令列に変換し、前記機械語命令列からなるオブジェクトプログラムを出力するステップとを含む
ことを特徴とするコンパイル方法。
【請求項１４】
ソースプログラムを機械語命令列からなるオブジェクトプログラムに翻訳するコンピュータで実行可能なコンパイル用プログラムであって、
前記コンピュータには、
関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報が記憶されている破壊レジスタテーブルと、
関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報が記憶されている非破壊レジスタテーブルとが記憶され、
コンピュータを請求項１〜１２のいずれかに記載のコンパイラ装置が備える手段として機能させるためのプログラム。
【請求項１５】
複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するリンク装置であって、
各オブジェクトプログラムに対応付けられている、関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報および関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報を読み込む関数情報取得手段と、
前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されているか否かを検査する関数情報検査手段と、
前記関数情報検査手段で登録されていると判断された場合には、エラーメッセージを出力するメッセージ出力手段と、
前記複数のオブジェクトプログラムを連結して実行形式のプログラムを生成する連結手段とを備える
ことを特徴とするリンク装置。
【請求項１６】
複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するリンク装置であって、
各オブジェクトプログラムに対応付けられている、関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報および関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報を読み込む関数情報取得手段と、
前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されているか否かを検査する関数情報検査手段と、
前記関数情報検査手段で登録されていると判断された関数名およびレジスタ名については、当該関数名を有する関数内で当該レジスタ名を有するレジスタの値が破壊されるよりも前に当該レジスタの値を退避させる命令をオブジェクトプログラムに挿入し、当該レジスタの値を破壊し終わった後に退避した前記値を復帰させる命令を当該オブジェクトプログラムに挿入する退避・復帰命令挿入手段と、
前記複数のオブジェクトプログラムを連結して実行形式のプログラムを生成する連結手段とを備える
ことを特徴とするリンク装置。
【請求項１７】
複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するリンク方法であって、
各オブジェクトプログラムに対応付けられている、関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報および関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報を読み込むステップと、
前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されているか否かを検査する検査ステップと、
前記検査ステップで登録されていると判断された場合には、エラーメッセージを出力するステップと、
前記複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するステップとを含む
ことを特徴とするリンク方法。
【請求項１８】
複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するリンク方法であって、
各オブジェクトプログラムに対応付けられている、関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報および関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報を読み込むステップと、
前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されているか否かを検査する検査ステップと、
前記検査ステップで登録されていると判断された関数名およびレジスタ名については、当該関数名を有する関数内で当該レジスタ名を有するレジスタの値が破壊されるよりも前に当該レジスタの値を退避させる命令をオブジェクトプログラムに挿入し、当該レジスタの値を破壊し終わった後に退避した前記値を復帰させる命令を当該オブジェクトプログラムに挿入するステップと、
前記複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するステップとを含む
ことを特徴とするリンク方法。
【請求項１９】
複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するコンピュータで実行可能なリンク用プログラムであって、
コンピュータを請求項１５または１６に記載のリンク装置が備える手段として機能させるためのプログラム。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、Ｃ言語等の高級言語で記述されたソースプログラムを分割コンパイル可能なコンパイル装置およびリンク装置に関し、特に、短時間で最適な実行形式のプログラムを生成可能なコンパイル装置およびリンク装置に関する。
【０００２】
【従来の技術】
従来、高級言語で記述されたソースプログラムを、コンピュータ上で実行可能な機械語のプログラムに変換するために、コンパイラおよびリンカ等のプログラムが用いられている。
【０００３】
コンパイラは、高級言語で記述されたソースプログラムを、相対形式のオブジェクトプログラムに翻訳するプログラムである。リンカは複数の相対形式のオブジェクトプログラムを連結し、各オブジェクトプログラムの主メモリ中での格納アドレスを決定し、また各オブジェクトプログラム間でのアドレス参照の問題を解決して、実行形式のプログラムを生成するプログラムである。
【０００４】
一般的なコンパイラでは、変数をレジスタに対応付けるレジスタ割り付けは関数定義毎に行われる。関数定義内に、生存期間中に他の関数呼び出しを含む変数が存在する場合には、その変数は、他の関数呼び出しにより破壊される可能性がある。このため、コンパイラは、通常、その変数に割り付けられるレジスタの値を、関数呼び出しの前にスタックに退避させ、関数呼び出しの後にスタックに退避させられた値を当該レジスタに復帰させる。
【０００５】
図２３は、ソースプログラムと、上述の方法に従い作成されるオブジェクトプログラムとの一例を示す図である。ソースプログラムソースプログラム３２ａに含まれる関数Ｆｕｎｃ（）は、関数ＵｐｄａｔｅＸ（）を呼び出しており、かつ、関数Ｆｕｎｃ（）の前後で変数ｒｅｓｕｌｔが参照されている。すなわち、変数ｒｅｓｕｌｔの生存期間中に関数Ｆｕｎｃ（）が呼び出されている。このため、関数ＵｐｄａｔｅＸ（）を呼び出すことにより、変数ｒｅｓｕｌｔの値が変化する可能性がある。
【０００６】
よって、コンパイラ３４は、変数ｒｅｓｕｌｔに割り当てられたレジスタｒ０の値を、関数ＵｐｄａｔｅＸ（）を呼び出す前にスタックに退避し（命令「ｐｕｓｈ  ｒ０」）、関数ＵｐｄａｔｅＸ（）を呼び出した後にスタックから復帰させる（命令「ｐｏｐ  ｒ０」）コードを生成し、オブジェクトプログラム３２ｂを生成する。
【０００７】
しかし、関数呼び出しでレジスタの値が破壊されないことが予め分かっていれば、スタックへの退避、復帰をする必要がなくなり、コンパイラにより生成されるオブジェクトプログラムを短く改善することができる。
既存のコンパイラの中には、同一のソースプログラム内において、関数の依存関係を調べ、関数呼び出しで破壊されないレジスタの集合を求め、レジスタ割り付けを効率的に行なうものがある。
【０００８】
図２４は、ソースプログラムと、上述の方法に従い作成されるオブジェクトプログラムとの一例を示す図である。
ソースプログラム２０ａは、関数ＵｐｄａｔｅＸ（）と、関数Ｆｕｎｃ（）とを含んでいる。このソースプログラム２０ａをコンパイラ２２によりコンパイルすることによりオブジェクトファイル２０ｂが生成される。
【０００９】
ソースプログラム２０ａに含まれる関数Ｆｕｎｃ（）は、図２３に示したソースプログラム３２ａに含まれる関数Ｆｕｎｃ（）と同一のものである。従って、関数ＵｐｄａｔｅＸ（）を呼び出すことにより、変数ｒｅｓｕｌｔの値が変化する可能性がある。
【００１０】
ところが、オブジェクトプログラム２０ｂに示されるように関数ＵｐｄａｔｅＸ（）では、変数ａに割り当てられたレジスタｒ０の値が破壊されることはない。このため、関数Ｆｕｎｃ（）の前後で変数ｒｅｓｕｌｔの値が変化することはなく、変数ｒｅｓｕｌｔに割り当てられたレジスタｒ０の値をスタックに退避させたり、復帰させたりする必要がない。このため、関数Ｆｕｎｃ（）について生成されるコードを図２３に示したオブジェクトプログラム３２ｂのコードに比べて短くすることができる。
【００１１】
しかし、この方法は、呼び出される側の関数（ソースプログラム２０ａにおける関数ＵｐｄａｔｅＸ（））が、呼び出す側の関数（ソースプログラム２０ａにおける関数Ｆｕｎｃ（））と同一のソースプログラム内に存在することを前提としている。したがって、呼び出される側の関数と呼び出す側の関数とが異なるソースプログラム内に存在し、それぞれのソースプログラムを分割コンパイルする場合には、この方法を適用することができない。
【００１２】
この問題の第１の解決方法として、すべての関数の情報が参照できるリンク時にレジスタ割り付けを行うようにする方法がある。
また、第２の解決方法として、関数呼び出しにより破壊されないレジスタをユーザが明示的にソースプログラム内に記述する方法がある。図２５は、そのようにして破壊されないレジスタが明示的に示されたソースプログラムと、そのコンパイル結果であるオブジェクトプログラムとの一例を示す図である。
【００１３】
図２５のソースプログラム４２ａおよび４４ａに示されるように、関数呼び出しにより破壊されないレジスタをユーザが明示的にソースプログラム内に記述する方法がある。たとえば、ソースプログラム４２ａでは、関数ＵｐｄａｔｅＸ（）の引数である変数ａに割り当てられるレジスタｒ０の値は、関数ＵｐｄａｔｅＸ（）内では破壊されないことが「＃ｐｒａｇｍａ＿ｎｏｂｒｅａｋ＿ｒｅｇ＿ＵｐｄａｔｅＸ  ｒ０」として明示的に示されている。また、ソースプログラム４４ａでは、変数ｒｅｓｕｌｔに割り当てられるレジスタｒ０の値は、関数ＵｐｄａｔｅＸ（）の呼び出しによっては破壊されないことが「＃ｐｒａｇｍａ＿ｎｏｂｒｅａｋ＿ｒｅｇ＿ＵｐｄａｔｅＸ  ｒ０」として明示的に示されている。なお、ユーザは、コンパイラ４６の規約により変数ｒｅｓｕｌｔにはレジスタｒ０が割り付けられることが予め分かっているものとする。
【００１４】
さらに、第３の解決方法として、複数のソースプログラムに含まれる関数間の呼び出し関係と必要レジスタ数とをあらかじめ解析し、コンパイル時にその解析結果を利用してオブジェクトプログラムを生成する方法がある（例えば、特許文献１参照。）。
【００１５】
【特許文献１】
特開平３−１７２９３６号公報
【００１６】
【発明が解決しようとする課題】
しかしながら、上述の第１の解決方法では、複数のオブジェクトプログラムをリンクするたびにレジスタ割り付けを行なわなければならず、リンク時間が非常にかかるという問題がある。また、分割されたソースファイルごとにレジスタ割り付けができるという分割コンパイルのメリットが生かせないため、現実的な方法ではない。
【００１７】
また、上述の第２の解決方法では、ユーザが関数呼び出しにより破壊されないレジスタを予め把握していなければならない。このため、例えば、入れ子になって関数呼び出しされている場合などには、その把握が非常に困難であるという問題がある。特に、ソースプログラムの変更を行なった場合などには、順次、関数の呼び出しに関する対応関係を把握しなければならず、ユーザにとって負担であるという問題がある。
【００１８】
さらに、上述の第３の解決方法では、あるソースプログラムの内容を変更した場合には、すべてのソースプログラムを再度コンパイルし直さなければならず、コンパイルに時間がかかりすぎると言う問題がある。また、実行形式のプログラムを作成するために必要なすべてのオブジェクトプログラムが揃わないとコンパイルができないという問題もある。
【００１９】
そこで、本発明は、上述の問題点を解決するためになされたものであり、ソースプログラムの変更を行なった場合であっても、そのソースプログラムのみを再コンパイルすれば所望のオブジェクトファイルを生成できるコンパイル装置を提供することを目的とする。
【００２０】
また、上述のコンパイラ装置でコンパイルされた複数のオブジェクトプログラムを実行形式のプログラムに変換する際に、不適切な実行形式のプログラムの生成を抑制することができるリンク装置を提供することも目的とする。
【００２１】
【課題を解決するための手段】
本発明のある局面に係るコンパイル装置は、ソースプログラムを機械語命令列からなるオブジェクトプログラムに翻訳するコンパイル装置であって、関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報が記憶されている破壊レジスタテーブルと、関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報が記憶されている非破壊レジスタテーブルと、前記ソースプログラムに含まれる各関数を中間コードに変換する中間コード変換手段と、前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報に基づいて、前記中間コードに含まれる各関数の変数にレジスタを割り付けるレジスタ割り付け手段と、レジスタが割り付けられた各関数について、当該関数に含まれる各レジスタの値が当該関数内で破壊される場合には、当該関数名と値が破壊されるレジスタのレジスタ名とを対応付けた関数破壊レジスタ情報を前記破壊レジスタテーブルに追加する破壊レジスタ追加手段と、レジスタが割り付けられた各関数について、当該関数に含まれる各レジスタの生存区間内に関数呼び出しがある場合には、呼び出される関数名と当該レジスタのレジスタ名とを対応付けた関数非破壊レジスタ情報を前記非破壊レジスタテーブルに追加する非破壊レジスタ追加手段と、前記中間コードを機械語命令列に変換し、前記機械語命令列からなるオブジェクトプログラムを出力する出力手段とを備えることを特徴とする。
【００２２】
この構成によると、既にコンパイル済みの関数における破壊レジスタ情報および非破壊レジスタ情報を用いてレジスタ割り付けを行なうことができる。このため、あるソースファイルを変更した場合には、そのファイルのみを再コンパイルすればよく、プログラムの開発効率を向上させることができる。
【００２３】
また、関数破壊レジスタ情報および関数非破壊レジスタ情報を参照してレジスタ割り付けを行なっているため、効率のよいオブジェクトプログラムを生成することができる。たとえば、前記レジスタ割り付け手段は、着目している関数内で呼び出される関数が前記破壊レジスタテーブルに登録されている場合には、当該関数を呼び出すことにより、前記着目している関数に含まれる変数の値が破壊されないようにレジスタ割り付けを行なうようにしてもよい。これにより、関数呼び出しで破壊されるレジスタが分かっているため、そのレジスタを関数呼び出しにまたがって使用しないようにすれば、レジスタの値の退避命令および復帰命令を挿入する必要がなく、処理ステップの短いオブジェクトプログラムを生成することができる。
【００２４】
好ましくは、前記破壊レジスタ追加手段は、着目している関数内に関数呼び出しが含まれる場合には、前記着目している関数の関数名と呼び出される関数において値が破壊されるレジスタのレジスタ名とを対応付けた関数破壊レジスタ情報を前記破壊レジスタテーブルに追加することを特徴とする。
【００２５】
これは、呼び出される関数における値が破壊されるレジスタは、呼び出し側の関数における値が破壊されるレジスタと言えるからである。
さらに好ましくは、前記関数情報入力手段は、前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されている場合には、エラーメッセージを出力することを特徴とする。
【００２６】
これによると、コンパイルの途中で関数破壊レジスタ情報および関数非破壊レジスタ情報の矛盾を検出することができるため、早い段階でコンパイルをやり直すことができ、プログラムの開発効率が向上する。
さらに好ましくは、前記非破壊レジスタ追加手段は、レジスタ名を追加する際に、関数呼び出し規約で常に値が保証されるレジスタ以外のレジスタ名を追加するようにしてもよい。また、前記破壊レジスタ追加手段は、レジスタ名を追加する際に、標準的に値が破壊されるレジスタ以外のレジスタ名を追加するようにしてもよい。
【００２７】
このようにすることにより、コンパイル時に必要な破壊レジスタテーブルおよび非破壊レジスタテーブルのメモリ量およびそれらのテーブル探索に必要な時間を短縮することができる。また、コンパイル装置より出力される関数破壊レジスタ情報および関数非破壊レジスタ情報を含むファイルの容量を削減することもできる。
【００２８】
さらに好ましくは、上述のコンパイラ装置は、さらに、前記ソースプログラムに含まれる関数間の呼び出し関係を解析する呼び出し関係解析手段と、前記呼び出し関係解析手段の出力に基づいて、関数の処理順序を決定する処理順序決定手段とを備え、前記レジスタ割り付け手段は、前記処理順序決定手段で定められた前記処理順序に従い、各関数の変数にレジスタを割り付けることを特徴とする。
【００２９】
このように、翻訳順序を適宜変更することにより最適なコードを得ることが可能となる。
本発明の他の局面に係るリンク装置は、複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するリンク装置であって、各オブジェクトプログラムに対応付けられている、関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報および関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報を読み込む関数情報取得手段と、前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されているか否かを検査する関数情報検査手段と、前記関数情報検査手段で登録されていると判断された場合には、エラーメッセージを出力するメッセージ出力手段と、前記複数のオブジェクトプログラムを連結して実行形式のプログラムを生成する連結手段とを備えることを特徴とする。
【００３０】
これによると、複数のオブジェクトプログラムを実行形式のプログラムに変換する際に、関数破壊レジスタ情報および関数非破壊レジスタ情報に矛盾があれば、メッセージを出力することができる。このため、不適切な実行形式のプログラムの作成を防ぐことができる。
【００３１】
本発明のさらに他の局面に係るリンク装置は、複数のオブジェクトプログラムを連結して実行形式のプログラムを生成するリンク装置であって、各オブジェクトプログラムに対応付けられている、関数名と当該関数を実行することにより値が破壊されるレジスタのレジスタ名とが対応付けられた関数破壊レジスタ情報および関数名と当該関数を実行することにより値が破壊されてはならないレジスタのレジスタ名とが対応付けられた関数非破壊レジスタ情報を読み込む関数情報取得手段と、前記関数破壊レジスタ情報および前記関数非破壊レジスタ情報の双方に、同一の関数名と同一のレジスタ名とが対応付けられて登録されているか否かを検査する関数情報検査手段と、前記関数情報検査手段で登録されていると判断された関数名およびレジスタ名については、当該関数名を有する関数内で当該レジスタ名を有するレジスタの値が破壊されるよりも前に当該レジスタの値を退避させる命令をオブジェクトプログラムに挿入し、当該レジスタの値を破壊し終わった後に退避した前記値を復帰させる命令を当該オブジェクトプログラムに挿入する退避・復帰命令挿入手段と、前記複数のオブジェクトプログラムを連結して実行形式のプログラムを生成する連結手段とを備えることを特徴とする。
【００３２】
これによると、複数のオブジェクトプログラムを実行形式のプログラムに変換する際に、関数破壊レジスタ情報および関数非破壊レジスタ情報に矛盾があれば、退避・復帰命令挿入手段により適切な実行形式のプログラムが作成される。このように、不適切な実行形式のプログラムの作成を防ぐことができる。
【００３３】
なお、本発明は、上述のようなコンパイル装置およびリンク装置として実現できるのみではなく、このコンパイル装置およびリンク装置が備える手段をそれぞれステップとするコンパイル方法およびリンク方法、また、コンピュータをコンパイル装置およびリンク装置としてそれぞれ機能させるためのコンパイラおよびリンカとして実現したり、当該コンパイラおよびリンカをＤＶＤ（Ｄｉｇｉｔａｌ  Ｖｅｒｓａｔｉｌｅ  Ｄｉｓｃ）、ＣＤ−ＲＯＭ（Ｃｏｍｐａｃｔ  Ｄｉｓｃ−Ｒｅａｄ  Ｏｎｌｙ  Ｍｅｍｏｒｙ）などの記録媒体や通信ネットワーク等の伝送媒体を介して流通させることができるのは言うまでもない。
【００３４】
【発明の実施の形態】
以下、本発明の実施の形態に係るコンパイル装置およびリンク装置について図面を参照しながら説明する。
【００３５】
＜コンパイル装置の構成＞
図１は、本発明の実施の形態に係るコンパイル装置１００の構成を示す機能ブロック図である。
【００３６】
コンパイル装置１００は、ソースファイル（たとえば、ソースファイル１０１ａ，１０２ａ）に含まれるソースプログラムを入力として受け、当該ソースプログラムを翻訳し、相対形式の機械語命令列であるオブジェクトプログラムを生成し、当該オブジェクトプログラムを格納したファイルであるオブジェクトファイル（たとえば、オブジェクトファイル１０１ｂ，１０２ｂ）を生成する装置である。ここで、ソースファイル１０１ａ，１０２ａには、Ｃ言語で記述されたソースプログラムが格納されている。
【００３７】
コンパイル装置１００は、関数情報入力部１０６と、入力部１０７と、関数呼び出し破壊レジスタ決定部１０８と、関数非破壊レジスタ登録部１０９と、レジスタ割り付け部１１０と、関数呼び出し非破壊レジスタ登録部１１１と、退避・復帰命令挿入部１１２と、関数破壊レジスタ登録部１１３と、出力部１１４と、関数破壊レジスタテーブル１１５と、関数非破壊レジスタテーブル１１６とを備える。
【００３８】
なお、コンパイル装置１００は、実際には、コンピュータ（図示せず）上で実行されるコンパイラおよびそのコンパイラが利用するデータとして実現される。関数情報入力部１０６から出力部１１４までの各構成要素は、ＣＰＵ（Ｃｅｎｔｒａｌ  Ｐｒｏｃｅｓｓｉｎｇ  Ｕｎｉｔ）上で動作するコンパイラの実行形式のプログラムであり、関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６は、メモリ上またはハードディスク上に存在するデータである。
【００３９】
関数情報入力部１０６から出力部１１４までの動作については、コンパイル装置１００の動作説明の中で合わせて説明する。
【００４０】
＜コンパイル装置の動作＞
次に、上述した構成を備えるコンパイル装置の動作について説明する。
図２は、コンパイル装置１００の全体的な動作を示すフローチャートである。
関数情報入力部１０６は、複数のオブジェクトファイル（たとえば、オブジェクトファイル１０１ｂ，１０２ｂ）およびライブラリファイル１０５にそれぞれ格納されている後述する関数情報セクションを読み込み、関数破壊レジスタ情報および関数非破壊レジスタ情報を関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６にそれぞれ格納する（Ｓ２）。ライブラリファイル１０５とは、ライブラリ関数の機械語命令列、すなわち、種々の再配置可能な汎用のサブルーチンであるライブラリプログラムと、上述の関数情報セクションとを格納したファイルのことである。
【００４１】
ここで、関数情報セクションには、関数破壊レジスタ情報と、関数非破壊レジスタ情報とが含まれる。関数破壊レジスタ情報とは、関数のラベル名と、その関数内で値が変更される（破壊される）レジスタの集合とからなる情報である。本明細書中では、関数呼び出しや演算等により値が破壊されるレジスタのことを「破壊レジスタ」と呼ぶ。
【００４２】
関数非破壊レジスタ情報とは、関数呼び出しの前後をまたいで生存しているレジスタがある場合に、当該関数のラベル名と、その関数をまたいで生存しているレジスタの集合とからなる情報である。すなわち、関数呼び出しの前後をまたいで生存しているレジスタの値は、関数呼び出しによって破壊されてはならない。このように、関数呼び出し等により値が破壊されてはならないレジスタのことを本明細書中では「非破壊レジスタ」と呼ぶ。
【００４３】
入力部１０７は、翻訳対象のソースファイルを読み込み、ソースファイルに含まれるソースプログラム内の関数定義をコンパイル装置１００の処理に適した形式である中間コード形式のプログラムに変換する（Ｓ４）。
関数呼び出し破壊レジスタ決定部１０８は、入力部１０７で中間コードに変換されたすべての関数のうち、現在選択されている翻訳対象の関数に含まれる関数呼び出しに対して、関数破壊レジスタテーブル１１５の情報をもとに、その関数呼び出しによって値が破壊されるレジスタ（破壊レジスタ）の集合を決定する（Ｓ１０）。
【００４４】
関数非破壊レジスタ決定部１０９は、翻訳対象の関数に対して、関数非破壊レジスタテーブル１１６の情報をもとに、その関数で値が破壊されてはならないレジスタ（非破壊レジスタ）の集合を決定する（Ｓ１２）。ここで、決定されたレジスタ集合は、後述する退避・復帰命令挿入部１１２での処理に用いられる。
【００４５】
レジスタ割り付け部１１０は、関数呼び出し破壊レジスタ決定部１０８で決定された関数呼び出しで破壊されるレジスタ集合および関数非破壊レジスタ決定部１０９で決定された関数で破壊してはならないレジスタ情報を利用して、中間コードに変換された関数に含まれる変数に対してレジスタ割り付けを行い、機械語命令列を生成する（Ｓ１４）。すなわち、レジスタ割り付け部１１０は、翻訳対象の関数内の呼び出し関数で値が破壊されるレジスタが存在する場合には、関数呼び出しにより、翻訳対象の関数内の変数の値が破壊されないようにレジスタ割り付けを行なう。また、レジスタ割り付け部１１０は、翻訳対象の関数で値が破壊されてはならないレジスタの値を破壊しないようにレジスタ割り付けを行なう。
【００４６】
退避・復帰命令挿入部１１２は、翻訳対象の関数のレジスタ割り付けされた中間コードを解析し、その関数内で値が破壊されるレジスタの集合を求める。その後、その集合に含まれるレジスタが関数非破壊レジスタ決定部１０９で決定された非破壊レジスタの集合に含まれているか否かを調べ、含まれている場合には、そのレジスタの値が破壊されないようにするために、その関数の中間コードの先頭にそのレジスタの値をスタックに退避する命令を挿入し、その関数を呼び出した関数への復帰命令の直前にその値をスタックから当該レジスタに復帰する命令を挿入する（Ｓ１６）。
【００４７】
関数呼び出し非破壊レジスタ登録部１１１は、レジスタ割り付け部１１０でのレジスタ割り付けの結果、翻訳対象となっている関数に含まれる関数呼び出しをまたいで生存しているレジスタ（非破壊レジスタ）を検出し、呼び出される関数のラベル名と非破壊レジスタとの組を関数非破壊レジスタテーブル１１６に登録する（Ｓ１８）。
【００４８】
関数破壊レジスタ登録部１１３は、退避・復帰命令挿入部１１２で退避・復帰命令を挿入した後に、関数内で値が破壊されるレジスタ（破壊レジスタ）の集合を求め、その関数のラベル名と破壊レジスタの集合との組を関数破壊レジスタテーブル１１６に登録する（Ｓ２０）。
【００４９】
なお、関数呼び出し非破壊レジスタ登録部１１１における処理および関数破壊レジスタ登録部１１３における処理については、後に詳述する。
以上説明した翻訳対象の関数に対する処理を中間コードに含まれるすべての翻訳対象の関数について繰り返し行なう（Ｓ６〜Ｓ２２）。
【００５０】
最後に、出力部１１４は、中間コードを相対形式の機械語命令列であるオブジェクトプログラムに変換し、オブジェクトファイルとして出力する。その際、出力部１１４は、関数破壊レジスタテーブ１１５および関数非破壊レジスタテーブル１１６に記憶されている情報を関数情報セクションとしてオブジェクトファイルに付加して出力する（Ｓ２４）。
【００５１】
＜関数呼び出し非破壊レジスタ登録部１１１および関数破壊レジスタ登録部１１３の動作＞
図３は、図２に示される関数非破壊レジスタテーブル登録処理（Ｓ１８）および関数破壊レジスタテーブル登録処理（Ｓ２０）を詳細に説明したフローチャートである。
【００５２】
なお、図２では、関数呼び出し非破壊レジスタ登録部１１１により実行される関数非破壊レジスタテーブル登録処理（Ｓ１８）および関数破壊レジスタ登録部１１３により実行される関数破壊レジスタテーブル登録処理（Ｓ２０）を分けて説明したが、図３では、これら２つの処理は、一体となって処理されるものとして説明を行なう。
【００５３】
関数破壊レジスタ登録部１１３は、着目している関数Ｆ内に存在する未処理の変数ｖに割り付けられたレジスタＲを中間コードより取得する（Ｓ３４）。
関数破壊レジスタ登録部１１３は、変数ｖの値が関数Ｆ内で変更されているか否かを調べる（Ｓ３６）。変数ｖの値が関数Ｆ内で変更されていれば（Ｓ３６でＹＥＳ）、関数破壊レジスタ登録部１１３は、関数Ｆのラベル名と変数ｖに対応するレジスタＲとを関数破壊レジスタテーブル１１５に登録する（Ｓ３８）。
【００５４】
関数破壊レジスタテーブル登録処理（Ｓ３８）の後、または変数ｖの値が関数Ｆ内で変更されていなければ（Ｓ３６でＮＯ）、関数呼び出し非破壊レジスタ登録部１１１は、変数ｖの存続区間に関数Ｇの呼び出しが存在する場合に、呼び出される関数Ｇのラベル名と変数ｖに対応するレジスタＲとを関数非破壊レジスタテーブル１１６に登録する（Ｓ４２）。
【００５５】
関数呼び出し非破壊レジスタ登録部１１１は、関数非破壊レジスタテーブルへの登録処理（Ｓ４２）を変数ｖの存在区間に存在する呼び出される関数のすべてについて実行する（Ｓ４０〜Ｓ４４）。
また、関数破壊レジスタ登録部１１３および関数呼び出し非破壊レジスタ登録部１１１は、関数破壊レジスタテーブルおよび関数非破壊レジスタテーブルへの登録処理（Ｓ３４〜Ｓ４４）を着目している関数Ｆに含まれるすべての変数について実行する（Ｓ３２〜Ｓ４６）。
【００５６】
関数破壊レジスタ登録部１１３は、関数Ｆが関数の間接呼び出しを１つでも含むか否かを調べる（Ｓ４８）。ここで、関数の間接呼び出しとは、いわゆるＣ言語におけるポインタを介した関数呼び出しのことである。
関数の間接呼び出しが含まれている場合には（Ｓ４８でＹＥＳ）、呼び出される関数が何であるかが分からない。このため、関数破壊レジスタ登録部１１３は、関数Ｆにおける破壊レジスタの集合を標準的に値が破壊されるレジスタ（以下「標準破壊レジスタ」という。）の集合と定義する（Ｓ５０）。その後、処理を終了する。
【００５７】
関数Ｆに関数の間接呼び出しが含まれていない場合には（Ｓ４８でＮＯ）、関数破壊レジスタ登録部１１３は、関数Ｆに未処理の関数呼び出しが存在するか否かを調べる（Ｓ５２）。
未処理の関数呼び出しが存在する場合には（Ｓ５２でＹＥＳ）、関数破壊レジスタ登録部１１３は、呼び出される関数Ｈの情報を取得する（Ｓ５４）。関数破壊レジスタ登録部１１３は、着目している関数Ｆと呼び出される関数Ｈとが同じか否かを調べる（Ｓ５６）。すなわち、関数Ｆが再帰的に関数Ｆを呼び出しているか否かを調べる。
【００５８】
関数Ｆと関数Ｈとが異なれば（Ｓ５６でＮＯ）、関数破壊レジスタ登録部１１３は、呼び出される側の関数Ｈの破壊レジスタ集合を、呼び出す側の関数Ｆの破壊レジスタ集合に加える（Ｓ５８）。すなわち、関数破壊レジスタ登録部１１３は、関数Ｆのラベル名と関数Ｈの破壊レジスタ集合とを組として関数破壊レジスタテーブル１１５に登録する。これは、関数Ｈで値が破壊されるレジスタの集合は、関数Ｆで値が破壊されるレジスタの集合と言い換えることができるためである。関数破壊レジスタ登録部１１３は、その後、関数呼び出し判断処理（Ｓ５２）に制御を戻す。
【００５９】
未処理の関数呼び出しが存在しなければ（Ｓ５２でＮＯ）、関数呼び出し非破壊レジスタ登録部１１１および関数破壊レジスタ登録部１１３は処理を終了する。
【００６０】
＜コンパイル装置１００の第１の具体的動作例＞
以上説明したコンパイル装置１００に、具体的なソースファイルを入力した場合の動作について説明する。
図４は、図１に示されるソースファイル１０１ａに含まれるソースプログラム１２１ａの内容を示す図である。また、図５は、ソースファイル１０２ａに含まれるソースプログラム１２２ａの内容を示す図である。説明を簡単にするためにライブラリファイル１０５は、ないものとする。
【００６１】
ソースプログラム１２１ａおよび１２２ａはともにＣ言語で記載されており、ソースプログラム１２１ａには関数ｆの関数定義が記述されている。また、ソースプログラム１２２ａには関数ｆの関数呼び出しを含む関数ｇの関数定義が記述されている。
【００６２】
（ソースプログラム１２１ａのコンパイル）
まずソースファイル１０１ａを入力としてオブジェクトファイル１０１ｂを生成する場合のコンパイル装置１００の動作について説明する。ソースプログラム１２１ａは、引数として渡された変数ａを変数ｘに代入するというプログラムである。
【００６３】
この場合、オブジェクトファイルを入力としないので、関数情報入力部１０６による処理（図２のＳ２）は実行されない。このため、関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６には何もデータが記憶されていない。
【００６４】
入力部１０７は、翻訳対象のソースプログラム１２１ａを読み込み、ソースプログラム１２１ａ内の関数定義をコンパイル装置での処理に適した形式である中間コードに変換する（図２のＳ４）。この処理は、従来のコンパイル装置において一般的に実施されている技術を用いるものである。このため、その詳細な説明はここでは繰返さない。
【００６５】
次に、関数呼び出し破壊レジスタ決定部１０８が、中間コードに含まれる関数呼び出しによって値が破壊されるレジスタを決定する（図２のＳ１０）。しかし、ここでは、関数ｆには関数呼び出しが含まれないため、何も処理が行われない。
【００６６】
関数非破壊レジスタ決定部１０９は、関数ｆの呼び出しの前後で値を破壊してはならないレジスタ、すなわち、関数ｆで値が破壊されてはならないレジスタ（非破壊レジスタ）を決定する（図２のＳ１２）。非破壊レジスタの決定は、関数非破壊レジスタテーブル１１６を参照して行われる。
【００６７】
関数非破壊レジスタテーブル１１６に関数ｆのラベル名が登録されていない場合は、関数呼び出し規約で常に値が保証されるレジスタ（以下、「保証レジスタ」と呼ぶ。）を関数ｆにおける非破壊レジスタとする。関数非破壊レジスタテーブル１１６に関数ｆのラベル名が登録されている場合は、そのラベル名と組になって登録されている非破壊レジスタ集合に含まれるすべてのレジスタと保証レジスタとを関数ｆにおける非破壊レジスタとする。ここでは、関数非破壊レジスタテーブル１１６には、関数ｆのラベル名は登録されていない。このため、保証レジスタが、関数ｆにおける非破壊レジスタとして決定される。
【００６８】
このコンパイル装置１００では、関数内で保証レジスタを使用する場合には、関数の入り口で保証レジスタの値をスタックに退避し、関数の出口でスタックに退避された値を保証レジスタに復帰する。このようにすることにより、保証レジスタに記憶された値は破壊されないことが保証される。
【００６９】
次に、レジスタ割り付け部１１０は、関数ｆの変数に対してレジスタを割り付ける（図２のＳ１４）。この処理は、従来のコンパイル装置において一般的に実施されている技術を用いる。このため、その詳細な説明はここでは繰返さない。図６にレジスタ割り付け後の関数ｆの中間コード１２１ｂの一例を示す。中間コード１２１ｂでは、ソースプログラム１２１ａの変数ａにレジスタｒ０が対応付けられている。
【００７０】
次に、退避・復帰命令挿入部１１２は、関数ｆで破壊してはならないレジスタの値が破壊されていた場合には、関数ｆの中間コードの先頭にそのレジスタの値をスタックに退避する命令を挿入し、関数ｆの中間コードの最後にその値をスタックからレジスタに復帰する命令を挿入する（図２のＳ１６）。ここでは、関数ｆには、値が破壊されるレジスタは存在しないため、値を破壊してはならないレジスタも存在しない。このため、何も行なわれない。
【００７１】
次に、関数呼び出し非破壊レジスタ登録部１１１は、関数ｆに含まれる関数呼び出しをまたいで生存しているレジスタ（非破壊レジスタ）を検出し、呼び出される関数のラベル名とレジスタとの組を関数非破壊レジスタテーブル１１６に登録する（図２のＳ１８）。ここでは、関数ｆには関数呼び出しが含まれないため、何も行なわれない。
【００７２】
次に関数破壊レジスタ登録部１１３は、関数ｆで値が破壊されるレジスタ集合を求め、関数ｆのラベル名と破壊されるレジスタ集合との組を関数破壊レジスタテーブル１１５に登録する（図２のＳ２０）。ここでは、関数ｆで値が破壊されるレジスタは存在しないため、関数ｆのラベル名「＿ｆ」と空集合との組が関数破壊レジスタテーブル１１５に登録される。図７は、当該組を登録後の関数破壊レジスタテーブル１１５の様子を示す。
【００７３】
最後に出力部１１４は、関数ｆの翻訳結果の機械語命令列に、関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６の情報を関数情報セクションとして付加してオブジェクトファイル１０１ｂとして出力する（図２のＳ２４）。
【００７４】
ここでは、関数非破壊レジスタテーブル１１６には、何も登録されていないので、図７に示される関数破壊レジスタテーブル１１５の内容のみが関数情報セクションとされる。図８は、出力結果であるオブジェクトファイル１０１ｂの内容を示す図である。オブジェクトファイル１０１ｂには、関数ｆに対するオブジェクトプログラムの後に、関数情報セクションが設けられている。ここで、関数情報セクションの内容「．ｂｒｅａｋｒｅｇｉｎｆｏ  ＿ｆ，ｎｏｒｅｇ」は、関数ｆの破壊レジスタがないことを示している。
【００７５】
（ソースプログラム１２２ａのコンパイル）
次に、現在作成されたオブジェクトファイル１０１ｂとソースファイル１０２ａとを入力としてオブジェクトファイル１０２ｂを生成する場合のコンパイル装置１００の動作説明をする。
【００７６】
関数情報入力部１０６は、オブジェクトファイル１０１ｂを読み込み、関数情報セクションの内容を関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６に登録する（図２のＳ２）。オブジェクトファイル１０１ｂの関数情報セクションには、図８に示されるように関数ｆの破壊レジスタ集合が空集合であるという情報が格納されているので、この情報が関数破壊レジスタテーブル１１５に登録される。関数情報セクションの情報登録後の関数破壊レジスタテーブル１１５の内容は図７のようになる。
【００７７】
次に入力部１０７は、ソースファイル１０２ａに含まれる翻訳対象のソースプログラム１２２ａを読み込み、中間コードに変換する（図２のＳ４）。
次に関数呼び出し破壊レジスタ決定部１０８は、関数呼び出しの前後で値が破壊されるレジスタを決定する（図２のＳ１０）。関数ｇでは、関数ｆの関数呼び出しが存在するので、関数ｆの呼び出しによる破壊レジスタを決定する。破壊レジスタの決定は、関数破壊レジスタテーブル１１５を参照して行われる。関数破壊レジスタテーブル１１５に関数呼び出しで呼び出される関数ｆのラベル名が登録されている場合は、その関数ｆと組となっている破壊レジスタ集合に含まれるすべてのレジスタを破壊レジスタとする。関数ｆのラベル名が登録されていない場合には、保証レジスタを除くすべてのレジスタを破壊レジスタとする。ここでは、図７に示すように関数ｆのラベル名が関数破壊レジスタテーブル１１３に登録されており、組となっている破壊レジスタ集合は空集合なので、関数ｆの呼び出しによる破壊レジスタはないと決定される。
【００７８】
次に関数非破壊レジスタ決定部１０９は、関数ｇの呼び出しの前後で値を破壊してはならないレジスタ、すなわち関数ｇで値が破壊されてはならないレジスタ（非破壊レジスタ）を決定する（図２のＳ１２）。非破壊レジスタの決定は、関数非破壊レジスタテーブル１１６を参照して行なわれる。関数非破壊レジスタ登録部１０９の処理の詳細はソースプログラム１２１ａのコンパイル時と同様であるためその詳細な説明はここでは繰返さない。ここでは、関数非破壊レジスタテーブル１１６には、関数ｇは登録されていないため、保証レジスタが、関数ｇにおける非破壊レジスタとして決定される。
【００７９】
次に、レジスタ割り付け部１１０は、関数ｇの変数に対してレジスタを割り付ける（図２のＳ１４）。関数ｆの呼び出しで破壊されるレジスタはないと決定されているため、その情報を利用してレジスタ割り付けが行なわれる。
図９にレジスタ割り付け後の関数ｇの中間コード１２２ｂの一例を示す。中間コード１２２ｂでは、ソースプログラムの変数ａおよび変数ｒｅｓｕｌｔにレジスタｒ０が対応付けられ、変数ｂにレジスタｒ１が対応付けられている。ここで、２つの変数（変数ａおよび変数ｒｅｓｕｌｔ）に１つのレジスタｒ０が対応付けられているのは、レジスタ割り付けの結果、転送元と転送先とが同一である転送命令を削除し、コード長の削減を行なったためである。
【００８０】
次に、退避・復帰命令挿入部１１２は、関数ｇで非破壊レジスタの値が破壊されていた場合には、関数ｇの中間コードの先頭にそのレジスタの値をスタックに退避する命令を挿入し、関数ｇの中間コードの最後にその値をスタックからレジスタに復帰する命令を挿入する（図２のＳ１６）。ここでは、関数内ｇで値が破壊されるレジスタはレジスタｒ０のみであり、レジスタｒ０は、関数非破壊レジスタ登録部１０９で決定される非破壊レジスタ集合に含まれていない。このため、何も行わない。
【００８１】
次に、関数呼び出し非破壊レジスタ登録部１１１は、関数ｇ内で呼び出される関数ｆをまたいで生存しているレジスタｒ０を検出し、関数ｆのラベル名「＿ｆ」とレジスタｒ０とを関数非破壊レジスタテーブル１１６に登録する（図２のＳ１８）。図１０にデータ登録後の関数非破壊レジスタテーブル１１６の一例を示す。なお、関数非破壊レジスタテーブル１１６へのデータの登録は、すでにラベル名が登録されている場合には、ラベル名に対応する非破壊レジスタ集合に非破壊レジスタを追加登録する。ラベル名が登録されていない場合には、ラベル名と、ラベル名に対応する非破壊レジスタ集合とを新たに登録する。
【００８２】
次に関数破壊レジスタ登録部１１３は、関数ｇで値が破壊されるレジスタ集合を求め、関数ｇのラベル名と破壊されるレジスタ集合との組を関数破壊レジスタテーブル１１５に登録する（図２のＳ２０）。ここでは、関数ｇで値が破壊されるレジスタはレジスタｒ０のみであるため、関数ｇのラベル名「＿ｇ」とレジスタｒ０との組が関数破壊レジスタテーブル１１５に登録される。図１１は、当該組を登録後の関数破壊レジスタテーブル１１５の様子を示している。ソースプログラム１２１ａに対する処理で登録された関数ｆに対するラベル名と破壊レジスタ集合との組に加えて、関数ｇに対するラベル名「＿ｇ」と破壊レジスタ集合「ｒ０」との組があらたに登録されている。
【００８３】
最後に出力部１１４は、関数ｇの翻訳結果の機械語命令列に、関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６の情報を関数情報セクションとして付加してオブジェクトファイル１０２ｂとして出力する（図２のＳ２４）。
【００８４】
ここでは、図１０に示される関数非破壊レジスタテーブル１１６の内容および図１１に示される関数破壊レジスタテーブル１１５の内容が関数情報セクションとされる。図１２は、出力結果であるオブジェクトファイル１０２ｂの内容を示す図である。オブジェクトファイル１０２ｂには、関数ｇに対するオブジェクトプログラムの後に、関数情報セクションが設けられている。ここで、関数情報セクションの内容について説明する。「．ｂｒｅａｋｒｅｇｉｎｆｏ  ＿ｆ，ｎｏｒｅｇ」は、関数ｆの破壊レジスタがないことを示している。「．ｂｒｅａｋｒｅｇｉｎｆｏ  ＿ｇ，ｒ０」は、関数ｇの破壊レジスタがｒ０であることを示している。「．ｎｏｂｒｅａｋｒｅｇｉｎｆｏ  ＿ｆ，ｒ０」は、関数ｆの保証レジスタ以外の非破壊レジスタがｒ０であることを示している。
【００８５】
（第１の具体的動作例のまとめ）
以上説明した第１の具体的動作例をまとめると図１３に示されるようになる。すなわち、ソースファイル１０１ａに含まれるソースプログラム１２１ａをコンパイル装置１００でコンパイルすることによりオブジェクトファイル１０１ｂが生成される。オブジェクトファイル１０１ｂに含まれる情報セクションによって、関数ｆで破壊されるレジスタがないことが示されている。この情報が、ソースプログラム１２２ａに含まれるソースファイル１０２ａのコンパイル時に使用され、オブジェクトファイル１０２ｂが作成される。すなわち、関数ｇでは、関数ｆを呼び出しており、かつ関数ｆをまたいで存在するレジスタｒ０が存在するが、関数ｆではレジスタの値が破壊されないことがあらかじめ分かっている。このため、関数ｆの呼び出しの前後で、レジスタｒ０の値をスタックに退避および復帰させる必要がない。このため、処理ステップの短いオブジェクトプログラムを作成することが可能になる。
【００８６】
＜コンパイル装置１００の第２の具体的動作例＞
次に、第１の具体的動作具体例で説明した図４に示されるソースファイル１０１ａのソースプログラム１２１ａの内容を変更した場合のコンパイル装置１００の処理について説明する。
【００８７】
図１４は、ソースファイル１０１ａに含まれる変更後のソースプログラム１２３ａの内容を示す図である。更新後の関数ｆでは、変数ａの値に１を加算し、変数ｘに代入するという処理が実行される。
以下、コンパイル装置１００に、図１２に示されるオブジェクトファイル１０２ｂと変更後のソースファイル１０１ａとを入力として、あらたなオブジェクトファイル１０１ｂを生成する処理について説明する。
【００８８】
関数情報入力部１０６は、オブジェクトファイル１０２ｂを読み込み、関数情報セクションの内容を関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６に登録する（図２のＳ２）。オブジェクトファイル１０２ｂの関数情報セクションには、図１２に示されるように、関数ｆの破壊レジスタ集合が空集合であるという情報と、関数ｇの破壊レジスタ集合がｒ０であるという情報とが格納されている。このため、この情報を関数破壊レジスタテーブル１１５に登録する。登録後の関数破壊レジスタテーブル１１５の内容は、図１１に示されるようになる。また、オブジェクトファイル１０２ｂの関数情報セクションには、関数ｆの非破壊レジスタ集合がｒ０であるという情報が格納されている。このため、この情報を関数非破壊レジスタテーブル１１６に登録する。登録後の関数非破壊レジスタテーブル１１６の内容は、図１０に示されるようになる。
【００８９】
次に入力部１０７は、ソースファイル１０１ａから、翻訳対象のソースプログラム１２３ａを読み込み、中間コードに変換する（図２のＳ４）。
次に関数呼び出し破壊レジスタ決定部１０８は、関数呼び出しの前後で値が破壊されるレジスタを決定する（図２のＳ１０）。関数ｆには関数呼び出しが含まれないため何も行わない。
【００９０】
次に関数非破壊レジスタ決定部１０９は、関数ｆの呼び出しの前後で値を破壊してはならないレジスタ、すなわち関数ｆで値が破壊されてはならないレジスタ（非破壊レジスタ）を決定する（図２のＳ１２）。非破壊レジスタの決定は、関数非破壊レジスタテーブル１１６を参照して行われる。関数非破壊レジスタ登録部１０９の処理の詳細は第１の具体的動作例の場合と同様であるためその詳細な説明はここでは繰返さない。ここでは、関数非破壊レジスタテーブル１１６に、関数ｆのラベル名「＿ｆ」と非破壊レジスタ集合としてレジスタｒ０が登録されている。このため、レジスタｒ０および保証レジスタが関数ｆにおける非破壊レジスタとして決定される。
【００９１】
次にレジスタ割り付け部１１０は、関数ｆの変数に対してレジスタを割り付ける（図２のＳ１４）。レジスタｒ０は関数ｆにおける非破壊レジスタであると決定されているため、この情報を利用してレジスタ割り付けが行なわれる。すなわち、関数ｆにおいて、レジスタｒ０を破壊しないようにレジスタ割り付けが行なわれる。
【００９２】
図１５にレジスタ割り付け後の関数ｆの中間コード１２３ｂの一例を示す。変数ｒ０が破壊してはならないレジスタであるため、余分なレジスタの退避・復帰コードを生成しないため、加算結果がレジスタｒ１に格納される。なお、レジスタｒ１は保証レジスタ以外のレジスタである。
【００９３】
次に退避・復帰命令挿入部１１２は、関数ｆで非破壊レジスタの値が破壊されていた場合には、関数ｆに退避命令および復帰命令を挿入する処理を行なう（図２のＳ１６）。関数ｆで値が破壊されるレジスタｒ１は非破壊レジスタではないため、何も行なわれない。
【００９４】
関数呼び出し非破壊レジスタ登録部１１１は、関数非破壊レジスタテーブル１１６への登録処理（図２のＳ１８）を行なうが、関数ｆには関数呼び出しが含まれないため、何も行なわれない。
次に関数破壊レジスタ登録部１１３は、関数ｆで値が破壊されるレジスタ集合を求め、その関数のラベル名と破壊されるレジスタ集合の組を関数破壊レジスタテーブル１１５に登録する（図２のＳ２０）。関数ｆでは、レジスタｒ１の値が破壊されるため、関数ｆのラベル名「＿ｆ」とレジスタｒ１とが関数破壊レジスタテーブル１１５に登録される。図１６はデータ登録後の関数破壊レジスタテーブル１１５の様子を示している。関数ラベル名「＿ｆ」に対する破壊レジスタ集合が空集合であったのが、レジスタｒ１が要素として加えられている。
【００９５】
最後に出力部１１４は、関数ｆの翻訳結果の機械語命令列に、関数破壊レジスタテーブル１１５および関数非破壊レジスタテーブル１１６の情報を関数情報セクションとして付加してオブジェクトファイル１０１ｂとして出力する（図２のＳ２４）。
【００９６】
ここでは、図１０に示される関数非破壊レジスタテーブル１１６の内容および図１１に示される関数破壊レジスタテーブル１１５の内容が関数情報セクションとされる。図１７は、出力結果であるオブジェクトファイル１０２ｂの内容を示す図である。オブジェクトファイル１０２ｂには、関数ｆに対するオブジェクトプログラムの後に、関数情報セクションが設けられている。たとえば、「．ｂｒｅａｋｒｅｇｉｎｆｏ  ＿ｆ，ｒ１」は、関数ｆの破壊レジスタがｒ１であることを示している。
（第２の具体的動作例のまとめ）
以上説明した第２の具体的動作例をまとめると図１８に示されるようになる。すなわち、オブジェクトファイル１０２ｂに含まれる情報セクションによって、関数ｆではレジスタｒ０を破壊してはならないことがあらかじめ分かっている。このため、関数ｆではレジスタｒ０の値を破壊しないように、あらたにレジスタｒ１を使用したオブジェクトプログラムが作成される。
【００９７】
以上説明したように、コンパイル装置１００によると、既にコンパイル済みの関数における破壊レジスタおよび非破壊レジスタの情報を用いてレジスタ割り付けが行なわれ。このため、あるソースファイルを変更した場合には、そのファイルのみを再コンパイルすればよい。このため、プログラムの開発効率を向上させることができる。
【００９８】
＜コンパイル装置１００の変形例＞
以上、本発明のコンパイル装置１００について実施形態に基づいて説明したが、本発明に係るコンパイル装置１００はこのような実施形態に限られるものではない。
【００９９】
たとえば、関数呼び出し非破壊レジスタ登録部１１１は、保証レジスタを含む非破壊レジスタ集合を登録するようにしてもよいし、保証レジスタを除く非破壊レジスタを登録するようにしてもよい。非破壊レジスタがすべて保証レジスタである場合には、登録を行わないようにしてもよい。このように、登録する対象を制限することにより、コンパイル時に必要なメモリ量およびテーブル探索に必要な時間を短縮することができる。また、オブジェクトファイル内の関数情報セクションの容量を削減することもできる。なお、関数破壊レジスタ登録部１１３についても同様である。
【０１００】
また、入力部１０７で、ソースプログラム内の関数定義を中間コードに変換した後で、関数間の呼び出し関係を解析し、関数情報を最大限に利用できるように関数の翻訳順序を決定してもよい。例えば、呼び出し側の関数の翻訳を先に行ない、呼び出される側の関数の翻訳を後に行なうように翻訳順序を決定してもよい。翻訳順序を適宜変更することにより、最適なコードを得ることが可能となる。
【０１０１】
さらに、関数情報入力部１０６は、ある関数に対してあるレジスタが破壊レジスタ集合および非破壊レジスタ集合の双方に登録されている場合には、エラーメッセージを出力し、翻訳処理を終了させるようにしてもよい。この場合、ソースプログラムのコンパイルの途中で関数情報の矛盾を検出できるので、早い段階でコンパイルをやり直すことができ、プログラムの開発効率が向上する。
【０１０２】
さらにまた、ライブラリファイルおよびオブジェクトファイルに含まれる関数情報セクションを別ファイルとしてもよい。この場合、関数情報入力部１０６は、オブジェクトファイルから関数破壊レジスタ情報および関数非破壊レジスタ情報を得る代わりに、関数情報セクションのみが含まれたファイルを読み込む。
【０１０３】
＜リンク装置の構成＞
図１９は、本発明の実施の形態に係るリンク装置２００の構成を示す機能ブロック図である。
リンク装置２００は、オブジェクトファイル（たとえば、オブジェクトファイル１０１ｂ、１０２ｂ）に含まれる相対形式の機械語命令列であるオブジェクトプログラムおよびライブラリファイル（たとえば、ライブラリファイル１０５）に含まれるライブラリプログラムを入力として受け、当該オブジェクトプログラムおよびライブラリプログラムを連結し、ターゲットマシン上で実行可能な実行形式のプログラムを作成する装置である。
【０１０４】
関数情報取得部２０１は、オブジェクトファイルおよびライブラリファイルに含まれる関数破壊レジスタ情報と関数非破壊レジスタ情報とを読み込む。
関数情報検査部２０２は、関数ごとに関数破壊レジスタ情報および関数非破壊レジスタ情報に矛盾がないか否かを調べる。
【０１０５】
メッセージ出力部２０３は、関数破壊レジスタ情報および関数非破壊レジスタ情報に矛盾がある場合に、エラーメッセージを出力する。
連結部２０４は、オブジェクトプログラムと、ライブラリプログラムとを連結して実行形式のプログラムを作成する。
【０１０６】
オブジェクトファイル１０１ｂ、オブジェクトファイル１０２ｂおよびライブラリファイル１０５には、上述のように関数破壊レジスタ情報と関数非破壊レジスタ情報とからなる関数情報セクションが含まれる。
なお、リンク装置２００は、実際には、コンピュータ（図示せず）上で実行されるプログラムであるリンカとして実現される。
【０１０７】
＜リンク装置の動作＞
次に、上述した構成を備えるリンク装置の動作について説明する。
図２０は、リンク装置２００の全体的な動作を示すフローチャートである。
関数情報取得部２０１は、複数のオブジェクトファイル（たとえば、オブジェクトファイル１０１ｂ、１０２ｂ）およびライブラリ（たとえば、ライブラリ１０５）からそれぞれ関数破壊レジスタ情報および関数非破壊レジスタ情報を読み込む（Ｓ６２）。
【０１０８】
関数情報検査部２０２は、関数情報取得部２０１で読み込んだ関数破壊レジスタ情報および関数非破壊レジスタ情報について、各関数について、破壊レジスタ集合と非破壊レジスタ集合との積集合を求める（Ｓ６６）。すなわち、関数情報検査部２０２は、破壊レジスタ集合と非破壊レジスタ集合との双方に登録されているレジスタを求める。
【０１０９】
関数情報検査部２０２は、上述の積集合が空集合か否かを調べる（Ｓ６８）。当該積集合が空集合であれば（Ｓ６８でＹＥＳ）、着目している関数に対する関数破壊レジスタ情報および関数非破壊レジスタ情報に矛盾がないと判断し、当該関数に対する処理を終了する。以上の処理をすべての関数について行なう（Ｓ６４〜Ｓ７０）。
【０１１０】
上述のループ処理（Ｓ６４〜Ｓ７０）の途中で、着目している関数に対する破壊レジスタ集合と非破壊レジスタ集合との積集合が空集合ではないと判断された場合には（Ｓ６８でＮＯ）、メッセージ出力部２０３は、関数名とその関数破壊レジスタ情報が存在するオブジェクトファイルの名称とその関数非破壊レジスタ情報が存在するオブジェクトファイルの名称とを含むエラーメッセージを、図示しないコンピュータのディスプレイなどに出力し（Ｓ７４）、処理を終了する。破壊レジスタ集合と非破壊レジスタ集合との積集合が空集合ではないということは、ひとつの関数の中に破壊されるレジスタと破壊されてはならないレジスタとが同時に存在することとなり矛盾するからである。このような問題は、ユーザがオブジェクトファイルの指定の間違いや指定のし忘れをしたような場合、または、ライブラリファイル１０５を更新した場合などに起きやすい。
【０１１１】
すべての関数を調べた結果、関数破壊レジスタ情報と関数非破壊レジスタ情報とが矛盾しないと判断された場合には、連結部２０４は、オブジェクトプログラムおよびライブラリプログラムを連結し、ターゲットマシン上で実行可能な実行形式のプログラム２０５を作成する（Ｓ７２）。この処理は、従来のリンク装置において一般的に実施されている技術を用いるものである。このため、その詳細な説明はここでは繰返さない。
【０１１２】
＜リンク装置２００の第１の具体的動作例＞
以上説明したリンク装置２００に、具体的なオブジェクトファイルおよびライブラリファイルを入力した場合の動作について説明する。
この具体的動作例では、図１７に示される内容のオブジェクトファイル１０１ｂおよび図１２に示される内容のオブジェクトファイル１０２ｂを入力とした場合のリンク装置２００の動作について説明する。
関数情報取得部２０１は、オブジェクトファイル１０１ｂおよびオブジェクトファイル１０２ｂの各々の関数情報セクションから、関数破壊レジスタ情報と関数非破壊レジスタ情報とを読み込む（図２０のＳ６２）。ここでは、オブジェクトファイル１０１ｂの関数情報セクションから、関数ｆの破壊レジスタ集合がレジスタｒ１であり、関数ｇの破壊レジスタ集合がレジスタｒ０であり、関数ｆの非破壊レジスタ集合がｒ０および保証レジスタであることが読み取られる。また、ブジェクトファイル１０２ｂの関数情報セクションから、関数ｆの破壊レジスタ集合が空集合であり、関数ｇの破壊レジスタ集合がレジスタｒ０であり、関数ｆの非破壊レジスタ集合がレジスタｒ０と保証レジスタであることが読み取られる。
【０１１３】
次に、関数情報検査部２０２は、関数ｆおよび関数ｇの各々について、破壊レジスタ集合と非破壊レジスタ集合との積集合を求め、積集合が空集合であるか否かを調べる（図２０のＳ６６、Ｓ６８）。関数ｆについては、破壊レジスタ集合（レジスタｒ１）と非破壊レジスタ集合（レジスタｒ０および保証レジスタ）との積集合は空集合である。また、関数ｇについては、非破壊レジスタ情報がオブジェクトファイル１０１ｂおよび１０２ｂのいずれにも存在しないため、破壊レジスタ集合と非破壊レジスタ集合との積集合は空集合であると判断される。
【０１１４】
エラーメッセージ出力部２０３は、関数情報検査部２０２で破壊レジスタ集合と非破壊レジスタ集合とが矛盾しないと判断されたため、エラー出力処理（図２０のＳ７４）を実行しない。
連結部２０４は、メッセージ出力部２０３でエラーメッセージが出力されなかったため、オブジェクトファイル１０１ｂおよびオブジェクトファイル１０２ｂにそれぞれ含まれるオブジェクトプログラムを連結し、ターゲットマシン上で実行可能な実行形式のプログラム２０５を作成する（図２０のＳ７２）。
【０１１５】
＜リンク装置２００の第２の具体的動作例＞
次に、図２１に示される内容のオブジェクトファイル１０１ｂおよび図１２に示される内容のオブジェクトファイル１０２ｂを入力とした場合のリンク装置２００の動作について説明する。なお、図２１に示される内容のオブジェクトファイル１０１ｂは、図１４に示される変更後のソースプログラム１２３ａを入力として、コンパイル装置１００により生成される。
【０１１６】
関数情報取得部２０１は、オブジェクトファイル１０１ｂおよびオブジェクトファイル１０２ｂの各々の関数情報セクションから、関数破壊レジスタ情報と関数非破壊レジスタ情報とを読み込む（図２０のＳ６２）。ここでは、オブジェクトファイル１０１ｂの関数情報セクションから、関数ｆの破壊レジスタ集合がレジスタｒ０であること読み取られる。また、オブジェクトファイル１０２ｂの関数情報セクションから、関数ｆの破壊レジスタ集合が空集合であり、関数ｇの破壊レジスタ集合がレジスタｒ０であり、関数ｆの非破壊レジスタ集合がレジスタｒ０と保証レジスタであることが読み取られる。
【０１１７】
次に、関数情報検査部２０２は、関数ｆおよび関数ｇの各々について、破壊レジスタ集合と非破壊レジスタ集合との積集合を求め、積集合が空集合であるか否かを求める（図２０のＳ６６、Ｓ６８）。関数ｆについては、破壊レジスタ集合（レジスタｒ０）と非破壊レジスタ集合（レジスタｒ０および保証レジスタ）との積集合（レジスタｒ０）は空集合ではない。また、関数ｇについては、非破壊レジスタ情報がオブジェクトファイル１０１ｂおよび１０２ｂのいずれにも存在しないため、破壊レジスタ集合と非破壊レジスタ集合との積集合は空集合であると判断される。関数ｆについての上述の積集合が空集合ではないため、関数情報検査部２０２は、関数ｆに対する破壊レジスタ集合と非破壊レジスタ集合との間に矛盾があると判断する。
【０１１８】
エラーメッセージ出力部２０３は、関数情報検査部２０２で関数ｆに関する破壊レジスタ集合と非破壊レジスタ集合との間に矛盾があると判断されたため（図２０のＳ６８でＮＯ）、関数名ｆとその関数破壊レジスタ情報が存在するオブジェクトファイル（オブジェクトファイル１０１ｂおよび１０２ｂ）の名称とその関数非破壊レジスタ情報が存在するオブジェクトファイル（オブジェクトファイル１０２ｂ）の名称とを含むエラーメッセージを、コンピュータのディスプレイなどに出力し（図２０のＳ７４）、処理を終了する。
【０１１９】
プログラマーは、このエラーメッセージを見て、オブジェクトファイル１０１ｂまたは１０２ｂをコンパイル装置１００で再度コンパイルし、オブジェクトファイル１０１ｂおよびオブジェクトファイル１０２ｂをリンク装置２００でリンクすることにより、正しい実行形式のプログラム２０５を得ることができる。
【０１２０】
＜リンク装置２００の変形例＞
以上、本発明のリンク装置２００について実施形態に基づいて説明したが、本発明に係るリンク装置２００はこのような実施形態に限られるものではない。
たとえば、上述の実施形態では、関数の破壊レジスタ集合と非破壊レジスタ集合とに矛盾がある場合には、エラーメッセージを出力し、処理を終了するようにしているが、リンク装置２００がオブジェクトプログラムを修正して正しく動作する実行形式のプログラム２０５を生成するようにしてもよい。
【０１２１】
図２２は、図２１に示されるオブジェクトファイル１０１ｂに含まれるオブジェクトプログラムの修正後の図である。以下、図２１および図２２に示されるオブジェクトプログラムを参照しながら、オブジェクトプログラムの修正方法の一例について説明する。例えば、図２１に示される関数ｆの定義内の機械語命令列の先頭に、破壊レジスタ集合に含まれる非破壊レジスタ（レジスタｒ０）をスタックへ退避させる命令「ｐｕｓｈ  ｒ０」を挿入し、関数ｆからの復帰命令「ｒｅｔ」の直前に、スタックに格納された値を非破壊レジスタ（レジスタｒ０）に復帰させる命令「ｐｏｐ  ｒ０」を挿入する。このような方法により作成されたオブジェクトプログラムが図２２に示される。
【０１２２】
＜まとめ＞
以上説明したように、本実施の形態に係るコンパイル装置によると、既にコンパイル済みのソースプログラムに対する関数破壊レジスタ情報および関数非破壊レジスタ情報に基づいて、他のソースプログラム対するコンパイルが行なわれる。また、コンパイル結果とともにそのソースプログラムに対する関数破壊レジスタ情報および関数非破壊レジスタ情報がさらに作成される。このように、既にコンパイル済みのソースプログラムに関するレジスタの情報を他のソースプログラムのコンパイルに役立てている。このため、あるソースプログラムを修正した場合には、そのソースプログラムのみを再コンパイルすることにより、所望のオブジェクトプログラムを生成することができる。
【０１２３】
また、上述のリンク装置によると、複数のオブジェクトプログラムを実行形式のプログラムに変換する際に、関数破壊レジスタ情報および関数非破壊レジスタ情報に矛盾があれば、メッセージを出力したり、自身で適切な実行形式のプログラムを作成したりする。このため、不適切な実行形式のプログラムの作成を防ぐことができる。
【０１２４】
【発明の効果】
本発明によると、ソースプログラムの変更を行なった場合であっても、そのソースプログラムのみを再コンパイルすれば所望のオブジェクトファイルを生成できるコンパイル装置を提供することができる。
【０１２５】
また、関数破壊レジスタ情報および関数非破壊レジスタ情報を参照してレジスタ割り付けを行なっているため、効率のよいオブジェクトプログラムを生成することができる。特に、処理ステップの短いオブジェクトプログラムを生成することができる。
【０１２６】
さらに、プログラムの開発効率の高いコンパイル装置を提供することができる。
さらにまた、コンパイル時に必要な破壊レジスタテーブルおよび非破壊レジスタテーブルのメモリ量およびそれらのテーブル探索に必要な時間を短縮することができる。また、コンパイル装置より出力される関数破壊レジスタ情報および関数非破壊レジスタ情報を含むファイルの容量を削減することもできる。
【０１２７】
また、複数のオブジェクトプログラムを実行形式のプログラムに変換する際に、不適切な実行形式のプログラムの作成を防ぐことができるリンク装置を提供することができる。
以上のように、本発明に係るコンパイル装置によると、関数に変更が生じた場合には、その関数を含むソースプログラムのみを再コンパイルすればよい、また、リンク装置によると、無矛盾な実行形式のプログラムを効率よく生成することが可能となる。このため、特に、ゲームプログラムのように、大規模でかつ頻繁にデバッグが行なわれるコンピュータプログラム用のコンパイラとして、その実用的価値は極めて高い。
【図面の簡単な説明】
【図１】本発明の実施の形態に係るコンパイル装置１００の構成を示す機能ブロック図である。
【図２】コンパイル装置１００の全体的な動作を示すフローチャートである。
【図３】図２に示される関数非破壊レジスタテーブル登録処理および関数破壊レジスタテーブル登録処理を詳細に説明したフローチャートである。
【図４】ソースファイル１０１ａに含まれるソースプログラム１２１ａの内容を示す図である。
【図５】ソースファイル１０２ａに含まれるソースプログラム１２２ａの内容を示す図である。
【図６】レジスタ割り付け後の関数ｆの中間コード１２１ｂの一例を示す図である。
【図７】関数破壊レジスタテーブル１１５の内容の一例を示す図である。
【図８】図４に示されるソースファイル１０１ａを入力として生成されるオブジェクトファイル１０１ｂの内容を示す図である。
【図９】レジスタ割り付け後の関数ｇの中間コード１２２ｂの一例を示す図である。
【図１０】関数非破壊レジスタテーブル１１６の内容の一例を示す図である。
【図１１】関数破壊レジスタテーブル１１５の内容の他の一例を示す図である。
【図１２】図８に示されるオブジェクトファイル１０１ｂおよび図５に示されるソースファイル１０２ａを入力として、本発明のコンパイル装置１００が生成するオブジェクトファイル１０２ｂの内容を示す図である。
【図１３】コンパイル装置１００の第１の具体的動作例のまとめ図である。
【図１４】ソースファイル１０１ａに含まれる変更後のソースプログラム１２３ａの内容を示す図である。
【図１５】レジスタ割り付け後の関数ｆの中間コード１２３ｂの一例を示す図である。
【図１６】関数破壊レジスタテーブル１１５の内容のさらに他の一例を示す図である。
【図１７】図１２に示されるオブジェクトファイル１０２ｂおよび図１４に示される変更後のソースファイル１０１ａを入力として、本発明のコンパイル装置１００が生成するオブジェクトファイル１０１ｂの内容を示す図である。
【図１８】コンパイル装置１００の第２の具体的動作例のまとめ図である。
【図１９】本発明の実施の形態に係るリンク装置２００の構成を示す機能ブロック図である。
【図２０】リンク装置２００の全体的な動作を示すフローチャートである。
【図２１】図１４に示される変更後のソースプログラム１２３ａを入力とした場合に、コンパイル装置１００が生成するオブジェクトファイル１０１ｂの内容を示す図である。
【図２２】図２１に示されるオブジェクトファイル１０１ｂに含まれるオブジェクトプログラムの修正後の図である。
【図２３】従来のコンパイラの動作の一例を示す図である。
【図２４】従来のコンパイラの動作の他の一例を示す図である。
【図２５】従来のコンパイラの動作のさらに他の一例を示す図である。
【符号の説明】
２２，３４，４６  コンパイラ
１００  コンパイル装置
１０１ａ，１０２ａ  ソースファイル
２０ｂ，３２ｂ，４２ｂ，４４ｂ，１０１ｂ，１０２ｂ  オブジェクトファイル
１０５  ライブラリファイル
１０６  関数情報入力部
１０７  入力部
１０８  関数呼び出し破壊レジスタ決定部
１０９  関数非破壊レジスタ決定部
１１０  レジスタ割り付け部
１１１  関数呼び出し非破壊レジスタ登録部
１１２  退避・復帰命令挿入部
１１３  関数破壊レジスタ登録部
１１４  出力部
１１５  関数破壊レジスタテーブル
１１６  関数非破壊レジスタテーブル
２０ａ，３２ａ，４２ａ，４４ａ，１２１ａ，１２２ａ，１２３ａ  ソースプログラム
１２１ｂ，１２２ｂ，１２３ｂ  中間コード
２００  リンク装置
２０１  関数情報取得部
２０２  関数情報検査部
２０３  メッセージ出力部
２０４  連結部
２０５  実行形式のプログラム
【図１】
2004362056.tif 000003
【図２】
2004362056.tif 000004
【図３】
2004362056.tif 000005
【図４】
2004362056.tif 000006
【図５】
2004362056.tif 000007
【図６】
2004362056.tif 000008
【図７】
2004362056.tif 000009
【図８】
2004362056.tif 000010
【図９】
2004362056.tif 000011
【図１０】
2004362056.tif 000012
【図１１】
2004362056.tif 000013
【図１２】
2004362056.tif 000014
【図１３】
2004362056.tif 000015
【図１４】
2004362056.tif 000016
【図１５】
2004362056.tif 000017
【図１６】
2004362056.tif 000018
【図１７】
2004362056.tif 000019
【図１８】
2004362056.tif 000020
【図１９】
2004362056.tif 000021
【図２０】
2004362056.tif 000022
【図２１】
2004362056.tif 000023
【図２２】
2004362056.tif 000024
【図２３】
2004362056.tif 000025
【図２４】
2004362056.tif 000026
【図２５】
2004362056.tif 000027