(57)【要約】【課題】レジスタ退避の実行回数を少なくする。【解決手段】ソースファイルＤ１に含まれる変数をレジスタに割付け、関数毎にアセンブラコードを生成し、レジスタを使用している関数の出入り口にレジスタの退避コードを挿入し、第１アセンブラプログラムＤ２を生成する第１アセンブラファイル生成部と、関数内で使用されているレジスタが呼び出し関数で使用されていない場合、前記第１アセンブラファイルＤ２に記述されたレジスタの退避コードを前記呼び出し関数の出入り口に移動させ、第２アセンブラプログラムＤ３を生成する第２アセンブラファイル生成部とを備える。【選択図】図３
2011141676.tif 000002
【特許請求の範囲】
【請求項１】
単一のファイルに記述されているソースプログラムに含まれる変数をレジスタに割り付け、関数毎にアセンブラコードを生成し、レジスタを使用している関数の出入り口にレジスタの退避コードを挿入し、第１アセンブラプログラムを生成する第１アセンブラファイル生成部と、
関数内で使用されているレジスタが呼び出し関数で使用されていない場合、前記第１アセンブラファイルに記述されたレジスタの退避コードを前記呼び出し関数の出入り口に移動させ、第２アセンブラプログラムを生成する第２アセンブラファイル生成部と、
を備えることを特徴とする言語処理装置。
【請求項２】
単一のファイルに記述されているソースプログラムに対して字句・構文解析を実行する字句・構文解析部と、
前記字句・構文解析部による解析結果に基づいて前記ソースプログラムに含まれる関数間の呼び出し関係を記述した関数呼出情報を生成する関数呼出抽出部と、
前記字句・構文解析部による解析結果に基づいて前記ソースプログラムに含まれる変数にレジスタを割付けるレジスタ割付部と、
前記レジスタ割付部による割付け結果に基づいて、前記ソースプログラムに含まれる関数内で値が変わらない保証レジスタの関数毎の保証レジスタ情報を生成する保証レジスタ抽出部と、
前記レジスタ割付部による割付け結果に基づいて、前記ソースプログラムから、保証レジスタを使用している関数の出入り口に前記使用されている保証レジスタの内容を保護するための退避コードを挿入した第１アセンブラプログラムを生成する第１アセンブラコード生成部と、
前記関数呼出情報および前記保証レジスタ情報に基づいて、退避コードを挿入されている関数から該関数の呼び出し元の関数に移動させることが可能であるか否かを判定し、退避コードの移動先の関数を示す退避コード情報を生成する退避コード情報生成部と、
前記保証レジスタ情報および前記退避コード情報に基づいて、前記第１アセンブラプログラムに記述されている退避コードを移動させ、第２アセンブラプログラムを生成する移動処理部と、
を備えることを特徴とする言語処理装置。
【請求項３】
単一のファイルに記述されているソースプログラムに対して字句・構文解析を実行し、
前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる関数間の呼び出し関係を記述した関数呼出情報を生成し、
前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる変数にレジスタを割付け、
前記変数の割付け結果に基づいて、前記ソースプログラムに含まれる関数内で値が変わらない保証レジスタの関数毎の保証レジスタ情報を生成し、
前記変数の割付け結果に基づいて、前記ソースプログラムから、保証レジスタを使用している関数の出入り口に前記使用されている保証レジスタの内容を保護するための退避コードを挿入した第１アセンブラプログラムを生成し、
前記関数呼出情報および前記保証レジスタ情報に基づいて、退避コードを挿入されている関数から該関数の呼び出し元の関数に移動させることが可能であるか否かを判定し、退避コードの移動先の関数を示す退避コード情報を生成し、
前記保証レジスタ情報および前記退避コード情報に基づいて、前記第１アセンブラプログラムに記述されている退避コードを移動させ、第２アセンブラプログラムを生成する、
ことを特徴とする言語処理方法。
【請求項４】
前記退避コード情報を生成するは、
一時的な移動先の関数を退避コード毎に示す一時情報を生成し、
前記一時情報に基づいて判定し、前記判定の実行結果毎に前記一時情報に反映する単位処理を繰り返し実行し、
前記判定の実行結果毎の反映前後で前記一時情報が変化しなくなったとき、前記反映の前後で変化しなくなった一時情報を前記退避コード情報とする、
を含む、
ことを特徴とする請求項３に記載の言語処理方法。
【請求項５】
コンピュータで実行可能な複数の命令を含むコンピュータプログラムプロダクトであって、前記複数の命令は、
単一のファイルに記述されているソースプログラムに対して字句・構文解析を実行し、
前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる関数間の呼び出し関係を記述した関数呼出情報を生成し、
前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる変数にレジスタを割付け、
前記変数の割付け結果に基づいて、前記ソースプログラムに含まれる関数内で値が変わらない保証レジスタの関数毎の保証レジスタ情報を生成し、
前記変数の割付け結果に基づいて、前記ソースプログラムから、保証レジスタを使用している関数の出入り口に前記使用されている保証レジスタの内容を保護するための退避コードを挿入した第１アセンブラプログラムを生成し、
前記関数呼出情報および前記保証レジスタ情報に基づいて、退避コードを挿入されている関数から該関数の呼び出し元の関数に移動させることが可能であるか否かを判定し、退避コードの移動先の関数を示す退避コード情報を生成し、
前記保証レジスタ情報および前記退避コード情報に基づいて、前記第１アセンブラプログラムに記述されている退避コードを移動させ、第２アセンブラプログラムを生成する、
ことを前記コンピュータに実行させる、
ことを特徴とするコンピュータプログラムプロダクト。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、言語処理装置、言語処理方法およびコンピュータプログラムプロダクトに関する。
【背景技術】
【０００２】
高級言語で記述されたソースプログラムからターゲットプロセッサ用のアセンブラコード（アセンブラプログラム）を生成するコンパイラは、ソースコードに記述された変数をレジスタに割付けて、アセンブリ言語で記述された命令のオペランドとする。コンパイラが変数に割付けるレジスタには、関数の呼び出しがあった場合に、関数の呼び出しを跨いで値が変わらないことが保証されるレジスタ（保証レジスタ）と、関数の呼び出しを跨いで値が変わる可能性があるレジスタと、の二種類がある。どのレジスタを保証レジスタとするかは、ターゲットプロセッサ毎にＡＢＩ（Applications  Binary  Interface）によって規定されている。
【０００３】
コンパイラには、呼び出された側の関数内で保証レジスタが使用されている場合、関数の呼び出しを跨いでレジスタの値が変わらないことを保証するために、レジスタ内容を退避／復帰させるコード（以下、退避コード）をこの関数の出入り口に生成する機能を有するものがある。なお、関数を呼び出す側の関数を呼び出し関数といい、呼び出される側の関数を被呼び出し関数ということとする。
【０００４】
一方、ターゲットプロセッサにおいては、退避コードの実行はメモリアクセスを伴うため、退避コードの実行回数が少ないほど実行速度が速くなる。したがって、コンパイラには退避コードの実行回数が少なくするようにアセンブラコードを最適化することが望まれる。
【０００５】
退避コードを最適化する技術として、特許文献１には、被呼び出し関数内で保証レジスタの値が破壊されても対象とするプログラム全体の動作が変わらないと判断できる場合、この被呼び出し関数内から該当する退避コードを削除する技術が開示されている。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開平１１−２７２４７３号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
本発明は、レジスタ退避の実行回数を少なくしたアセンブラコードを作成する言語処理装置、言語処理方法およびコンピュータプログラムプロダクトを提供することを目的とする。
【課題を解決するための手段】
【０００８】
本願発明の一態様によれば、単一のファイルに記述されているソースプログラムに含まれる変数をレジスタに割り付け、関数毎にアセンブラコードを生成し、レジスタを使用している関数の出入り口にレジスタの退避コードを挿入し、第１アセンブラプログラムを生成する第１アセンブラファイル生成部と、関数内で使用されているレジスタが呼び出し関数で使用されていない場合、前記第１アセンブラファイルに記述されたレジスタの退避コードを前記呼び出し関数の出入り口に移動させ、第２アセンブラプログラムを生成する第２アセンブラファイル生成部と、を備えることを特徴とする言語処理装置が提供される。
【０００９】
また、本願発明の一態様によれば、単一のファイルに記述されているソースプログラムに対して字句・構文解析を実行する字句・構文解析部と、前記字句・構文解析部による解析結果に基づいて前記ソースプログラムに含まれる関数間の呼び出し関係を記述した関数呼出情報を生成する関数呼出抽出部と、前記字句・構文解析部による解析結果に基づいて前記ソースプログラムに含まれる変数にレジスタを割付けるレジスタ割付部と、前記レジスタ割付部による割付け結果に基づいて、前記ソースプログラムに含まれる関数内で値が変わらない保証レジスタの関数毎の保証レジスタ情報を生成する保証レジスタ抽出部と、前記レジスタ割付部による割付け結果に基づいて、前記ソースプログラムから、保証レジスタを使用している関数の出入り口に前記使用されている保証レジスタの内容を保護するための退避コードを挿入した第１アセンブラプログラムを生成する第１アセンブラコード生成部と、前記関数呼出情報および前記保証レジスタ情報に基づいて、退避コードを挿入されている関数から該関数の呼び出し元の関数に移動させることが可能であるか否かを判定し、退避コードの移動先の関数を示す退避コード情報を生成する退避コード情報生成部と、前記保証レジスタ情報および前記退避コード情報に基づいて、前記第１アセンブラプログラムに記述されている退避コードを移動させ、第２アセンブラプログラムを生成する移動処理部と、を備えることを特徴とする言語処理装置が提供される。
【００１０】
また、本願発明の一態様によれば、単一のファイルに記述されているソースプログラムに対して字句・構文解析を実行し、前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる関数間の呼び出し関係を記述した関数呼出情報を生成し、前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる変数にレジスタを割付け、前記変数の割付け結果に基づいて、前記ソースプログラムに含まれる関数内で値が変わらない保証レジスタの関数毎の保証レジスタ情報を生成し、前記変数の割付け結果に基づいて、前記ソースプログラムから、保証レジスタを使用している関数の出入り口に前記使用されている保証レジスタの内容を保護するための退避コードを挿入した第１アセンブラプログラムを生成し、前記関数呼出情報および前記保証レジスタ情報に基づいて、退避コードを挿入されている関数から該関数の呼び出し元の関数に移動させることが可能であるか否かを判定し、退避コードの移動先の関数を示す退避コード情報を生成し、前記保証レジスタ情報および前記退避コード情報に基づいて、前記第１アセンブラプログラムに記述されている退避コードを移動させ、第２アセンブラプログラムを生成する、ことを特徴とする言語処理方法が提供される。
【００１１】
また、本願発明の一態様によれば、コンピュータで実行可能な複数の命令を含むコンピュータプログラムプロダクトであって、前記複数の命令は、単一のファイルに記述されているソースプログラムに対して字句・構文解析を実行し、前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる関数間の呼び出し関係を記述した関数呼出情報を生成し、前記字句・構文解析の実行結果に基づいて前記ソースプログラムに含まれる変数にレジスタを割付け、前記変数の割付け結果に基づいて、前記ソースプログラムに含まれる関数内で値が変わらない保証レジスタの関数毎の保証レジスタ情報を生成し、前記変数の割付け結果に基づいて、前記ソースプログラムから、保証レジスタを使用している関数の出入り口に前記使用されている保証レジスタの内容を保護するための退避コードを挿入した第１アセンブラプログラムを生成し、前記関数呼出情報および前記保証レジスタ情報に基づいて、退避コードを挿入されている関数から該関数の呼び出し元の関数に移動させることが可能であるか否かを判定し、退避コードの移動先の関数を示す退避コード情報を生成し、前記保証レジスタ情報および前記退避コード情報に基づいて、前記第１アセンブラプログラムに記述されている退避コードを移動させ、第２アセンブラプログラムを生成する、ことを前記コンピュータに実行させる、ことを特徴とするコンピュータプログラムプロダクトが提供される。
【発明の効果】
【００１２】
本発明によれば、レジスタ退避の実行回数を少なくしたアセンブラコードを作成することができるという効果を奏する。
【図面の簡単な説明】
【００１３】
【図１】コンパイル装置に入力されるソースコードの一例を説明する図。
【図２】ソースコードから生成されるアセンブラコードの例を説明する図。
【図３】第１の実施の形態のコンパイル装置の構成を示す図。
【図４】第１の実施の形態のコンパイル装置のハードウェア構成を説明する図。
【図５】ソースコードおよび該ソースコードから生成されるアセンブラコードの一例を説明する図。
【図６】第１の実施の形態のコンパイル方法を説明するフローチャート。
【図７】関数呼出情報の一例を示す図。
【図８】保証レジスタ情報の一例を示す図。
【図９】退避コード情報生成部が退避コード情報を生成する動作を説明するフローチャート。
【図１０】退避コード情報の一例を示す図。
【図１１】第２アセンブラコードの一例を示す図。
【図１２−１】複数の被呼び出し関数から同一の保証レジスタに関する退避コードが同一の呼び出し関数に移動する場合の具体例を説明するための図。
【図１２−２】複数の被呼び出し関数から同一の保証レジスタに関する退避コードが同一の呼び出し関数に移動する場合の具体例を説明するための図。
【図１３】第１アセンブラコードと第２アセンブラコードとを比較する図。
【図１４】第１の実施の形態のコンパイル装置の他のハードウェア構成を説明する図。
【図１５】第１の実施の形態のコンパイル装置の他のハードウェア構成を説明する図。
【図１６】第２の実施の形態のコンパイル・アセンブル装置の構成を示す図。
【発明を実施するための形態】
【００１４】
以下に添付図面を参照して、本発明の実施の形態にかかる言語処理装置、言語処理方法およびコンピュータプログラムプロダクトを詳細に説明する。なお、これらの実施の形態により本発明が限定されるものではない。
【００１５】
（第１の実施の形態）
本発明の第１の実施の形態は、ソースプログラム（ソースコード）をファイル毎にアセンブリ言語へ変換してアセンブラコード（アセンブラプログラム）を生成するコンパイル装置（コンパイラ）に適用される。第１の実施の形態のコンパイル装置は、被呼び出し関数内で保証レジスタが使用されている場合、該保証レジスタの内容に対する退避コードをこの被呼び出し関数の出入り口に生成する機能（退避コード生成機能）を備えていることとする。まず、図１および図２を参照して、第１の実施の形態の特徴を説明する。
【００１６】
図１は、第１の実施の形態のコンパイル装置に入力されるソースコードの一例を示す図である。この例では、Ｃ言語で記述されたソースコード１０１中には、関数subおよび関数testが定義されている。関数testは、ループ処理を含んでおり、このループ処理内で関数subを呼び出すようになっている。
【００１７】
第１の実施の形態のコンパイラは、まず、退避コード生成機能を使用してソースコード１０１からアセンブラコード（第１アセンブラコード）を生成する。そして、コンパイラは、退避コードの実行回数が少なくなるように第１アセンブラコードを修正し、第１の実施の形態による最終的な生成物としてのアセンブラコード（第２アセンブラコード）を生成する。
【００１８】
図２は、ソースコード１０１から生成されるアセンブラコードの例を示す図である。なお、この例においては、ターゲットプロセッサに関するＡＢＩによって、レジスタ「$8」を保証レジスタとすることが決められていることとする。
【００１９】
アセンブラコード１０２は、ソースコード１０１から生成された第１アセンブラコードの一例である。なお、コンパイラは、関数sub内においては$8を使用し、関数test内においては$8を使用しないようにレジスタ割付を行ったこととする。アセンブラコード１０２に示すように、$8の使用によって内容が破壊されないように、関数subの入口に、$8の内容をスタックに退避させる命令「push $8」が記述され、関数subの出口に、退避させた内容を$8に復帰させる命令「pop $8」が記述されている。以降、このようなpush、popの対を退避コードと呼ぶこととする。関数testには、$8を使用していないので$8に関する退避コードは記述されていない。関数testに対応するブロックには、関数subを呼び出す命令「call _sub」が記述されている。
【００２０】
ソースコード１０１では、関数subは、関数testが備えるforループ内で呼び出される。つまり、「call _sub」および関数subはforループの条件を満たす回数分繰り返し実行される。アセンブラコード１０２では、ターゲットプロセッサは、関数subを呼び出す毎に$8の退避／復帰を行うことになる。
【００２１】
アセンブラコード１０３は、アセンブラコード１０２から生成された第２アセンブラコードの例である。図示するように、第１アセンブラコード１０２では関数subの出入り口に記述されていた退避コードが第２アセンブラコード１０３では関数subを呼び出す関数testの出入り口に移動している。
【００２２】
アセンブラコード１０３によれば、ターゲットプロセッサは、関数testにおいて入り口で$8を退避してから、ループを実行し、関数の出口で$8を復帰させることになる。この場合、アセンブラコード１０２の場合に比べて退避コードの実行回数が関数testのループの回数分から1回で済む。
【００２３】
このように、本発明の第１の実施の形態は、被呼び出し関数の出入り口に記述されている保証レジスタの退避コードを呼び出し関数の出入り口に移動させることによって、退避コードの実行回数を少なくしたアセンブラコードを生成できるようにしたことが主たる特徴となっている。なお、第１アセンブラコードに含まれている退避コードを移動させる処理を、退避コード移動処理ということとする。
【００２４】
図３は、第１の実施の形態のコンパイル装置の構成図である。コンパイル装置２００には、ソースコードが記述されたファイルであるソースファイルＤ１が入力される。コンパイル装置２００は、入力されたソースファイルＤ１に基づいて第１アセンブラコードが記述されたファイルである第１アセンブラファイルＤ２を生成する。そして、コンパイル装置２００は、第１アセンブラコードに対して退避コード移動処理を施して、第２アセンブラコードが記述されたファイルである第２アセンブラファイルＤ３を出力する。コンパイル装置２００は、１つのソースファイルＤ１から１つの第２アセンブラファイルＤ３を生成する。
【００２５】
コンパイル装置２００は、第１アセンブラファイルＤ２を生成するための構成（第１アセンブラファイル生成部）として、字句・構文解析部２０１と、レジスタ割付部２０２と、アセンブラコード生成部２０３と、を備えている。
【００２６】
字句・構文解析部２０１、レジスタ割付部２０２、およびアセンブラコード生成部２０３の機能は、一般的に入手可能なコンパイル装置に備えられる各構成の機能と同じである。字句・構文解析部２０１の字句解析では、入力されたソースファイルＤ１に含まれる夫々の字句をＲＡＭなどに展開する。そして、字句・構文解析部２０１の構文解析では、展開された夫々の字句の意味、字句の組み合わせにより生じるソースファイルD1に記述されたプログラム上の意味（関数、変数、代入文関係など）を認識する。
【００２７】
レジスタ割付部２０２は、字句・構文解析部２０１による解析結果に基づいて、ソースファイルＤ１に含まれる夫々の変数にレジスタを割付ける。アセンブラコード生成部２０３は、レジスタ割付部２０２によるレジスタ割付け結果に基づいてアセンブラコードを生成し、第１アセンブラファイルＤ２を作成する。ここで、アセンブラコード生成部２０３は、変数に対して保証レジスタを割り付けた場合に、この関数の出入り口にこの保証レジスタの退避コードを挿入する。
【００２８】
さらに、コンパイル装置２００は、第１アセンブラファイルＤ２から第２アセンブラファイルＤ３を生成するための構成（第２アセンブラファイル生成部）として、関数呼出抽出部２０４と、保証レジスタ抽出部２０５と、退避コード情報生成部２０６と、退避コード移動処理部２０７と、を備えている。
【００２９】
関数呼出抽出部２０４は、字句・構文解析部２０１による解析結果に基づいて、ソースファイルＤ１に含まれる関数間の呼び出し関係の情報、各関数について他のファイルから呼び出される関数かの情報、動的呼出となっている可能性があるかの情報を抽出する。関数呼出抽出部２０４は、抽出した呼び出し関係を関数呼出情報Ｄ４として作成する。
【００３０】
保証レジスタ抽出部２０５は、レジスタ割付部２０２によるレジスタ割付け結果に基づいて、関数内で使用されている保証レジスタの関数毎のリストである保証レジスタ情報Ｄ５を作成する。
【００３１】
退避コード情報生成部２０６は、関数呼出情報Ｄ４と保証レジスタ情報Ｄ５とに基づいて、関数内で使用されている保証レジスタに対する退避コードが移動可能であるか否かを関数毎に判定する。より詳しくは、退避コード情報生成部２０６は、着目した関数が保証レジスタを使用し、かつこの関数を呼び出す呼び出し関数でこの保証レジスタを使用している関数がない場合、この保証レジスタに対する退避コードは移動可能であると判定する。さらに、退避コード情報生成部２０６は、退避コード移動処理前における退避コードの位置（すなわちアセンブラコード生成部２０３によって退避コードが挿入される位置）および退避コード移動処理後における退避コードの位置を記述した退避コード情報Ｄ６を生成する。
【００３２】
退避コード移動処理部２０７は、退避コード情報Ｄ６に基づいて第１アセンブラファイルＤ２に記述されている退避コードに対して退避コード移動処理を施し、第２アセンブラファイルＤ３を生成する。なお、第１アセンブラファイルＤ２は最終的なアセンブラコードではないので、ファイルとして出力せず、内部情報としてメモリ上に格納された状態でもよい。
【００３３】
図４は、コンパイル装置２００のハードウェア構成図である。コンパイル装置２００は、ＣＰＵ（Central  Processing  Unit）１、ＲＯＭ（Read  Only  Memory）２、ＲＡＭ（Random  Access  Memory）３、入力部４、表示部５を備えるコンピュータ構成となっている。各々は、バスラインなどを介して夫々接続されている。
【００３４】
ＣＰＵ１は、第１の実施の形態のコンパイル方法を実行するコンピュータプログラムプロダクトであるコンパイルプログラム６を実行する。表示部５は、液晶モニタなどの表示装置であり、ＣＰＵ１からの指示に基づいて、操作画面などのユーザに対する出力情報を表示する。入力部４は、マウスやキーボードなどを備えて構成され、ユーザからの操作をコンパイル装置２００へ入力する。入力部４から入力された操作情報は、ＣＰＵ１へ送られて処理される。
【００３５】
コンパイルプログラム６は、字句・構文解析部２０１、レジスタ割付部２０２、アセンブラコード生成部２０３、関数呼出抽出部２０４、保証レジスタ抽出部２０５、退避コード情報生成部２０６、および退避コード移動処理部２０７を含むモジュール構成となっており、ＲＡＭ３にロードされることによってＲＡＭ３にこれらの構成部が生成される。
【００３６】
コンパイルプログラム６は、ＲＯＭ２内に格納されており、バスラインを介してＲＡＭ３へロードされる。図４は、コンパイルプログラム６がＲＡＭ３へロードされた状態を示している。ＣＰＵ１はＲＡＭ３内にロードされたコンパイルプログラム６を実行する。ＣＰＵ１は、外部記憶装置などから入力されたソースファイルＤ１に基づいて各種処理を実行し、この各種処理に際して生じる第１アセンブラファイルＤ２、関数呼出情報Ｄ４、保証レジスタ情報Ｄ５、退避コード情報Ｄ６などの中間データを、ＲＡＭ３内に形成されるデータ格納領域に一時的に記憶させておく。ＣＰＵ１は、データ格納領域に一時的に記憶させた前述のデータを使用して第２アセンブラファイルＤ３を作成し、ＲＡＭ３内のプログラム格納領域あるいは外部記憶装置などに出力する。なお、コンパイルプログラム６は、ＤＩＳＫなどの記憶装置に格納しておいてもよいし、ロードしてもよい。
【００３７】
なお、コンパイルプログラム６を、インターネット等のネットワークに接続されたコンピュータ上に格納し、ネットワーク経由でダウンロードさせることにより提供または配布するように構成しても良い。また、コンパイルプログラム６を、ＲＯＭ２等に予め組み込んでコンパイル装置２００に提供するように構成してもよい。
【００３８】
次に、コンパイル装置２００を用いて実現される本発明の第１の実施の形態のコンパイル方法について説明する。ここでは、レジスタ$8〜$11が保証レジスタであると定義されているプロセッサをターゲットプロセッサとする。図５（ａ）に示すソースコード（ソースファイルＤ１）が入力されたとする。図５（ａ）のソースコードによれば、関数sub、関数test、関数mainが記述されており、関数mainが関数testを呼び出し、関数testはループ処理内で関数subを呼び出すようになっている。第１アセンブラファイル生成部の処理によりソースコード（図５（ａ））から、第１アセンブラコード（図５（ｂ））が記述された第１アセンブラファイルＤ２が得られる。また、図５（ｂ）に示す第１アセンブラコードによれば、関数subの出入り口に$8の退避コードが生成され、関数testの出入り口に$9〜$11の退避コードが生成されている。この第１アセンブラコードによれば、$8の退避コードは、関数testがループ処理を実行する毎に実行されることになる。
【００３９】
図６は、第１の実施の形態のコンパイル方法を説明するフローチャートである。まず、字句・構文解析部２０１は、ソースファイルＤ１に記述されているソースファイルＤ１について解析を実行する（Ｓ１）。すると、関数呼出抽出部２０４は、字句・構文解析部２０１による解析結果に基づいて、関数間の呼び出し関係の情報、各関数について他のファイルから呼び出される関数かの情報、動的呼出となっている可能性があるかの情報を抽出し、関数呼出情報Ｄ４を作成する（Ｓ２）。
【００４０】
図７は、関数呼出情報Ｄ４の一例を示す図である。図示するように、関数呼出情報Ｄ４は、関数毎に、自身が呼び出す被呼び出し関数と自身を呼び出す呼び出し関数とが記述されるフィールドを含んでいる。例えば関数testは、関数subが被呼び出し関数、関数mainが呼び出し関数であることが示されている。
【００４１】
なお、字句・構文解析部２０１による解析は、静的な解析によって行われるものであるので、関数のポインタなどを使用した関数コールによって動的に飛び先が変わる呼出については解析することはできない。したがって、本発明の第１の実施の形態では、動的に呼び出される可能性のある関数が含む退避コードは、退避コード移動処理の対象外とする。また、入力されたソースファイルＤ１以外のファイルから呼び出される可能性のある関数が含む退避コードに対して退避コード移動処理を実行しようとすると、プログラムを構成するソースファイルをすべて解析する必要があるため、退避コード移動処理が可能であるか否かを判定する処理が複雑になり、コンパイル時間が長くなってしまう。したがって、本発明の第１の実施の形態では、他のファイルから呼び出される可能性のある関数が含む退避コードも、退避コード移動処理の対象外とする。
【００４２】
関数呼出情報Ｄ４は、関数毎に、入力されたソースファイルＤ１とは異なる他のファイルから呼び出される関数であるか否か、および自関数が動的呼び出しによって呼び出される可能性があるか否か、が記述されるフィールドを含んでいる。他のファイルから呼び出される関数であるか否かは、例えばＣ言語においては、static宣言された関数であるか否かによって判定することができる。また、Ｃ言語の場合、関数の動的呼び出しには、関数のポインタ型の変数に初期値または代入文によって該関数のアドレスが設定される必要がある。したがって、ソースファイルＤ１中に、被呼び出し関数について関数の呼び出し以外で、被呼び出し関数の参照がない場合には、そのソースファイルD1では被呼び出し関数についての動的な関数コールは発生しないと判断できる。図７の例では、例えば関数testは、static宣言されているので他のファイルから呼び出される関数ではなく、testは 関数mainでの呼び出し以外には参照されていないので動的呼び出しに呼び出される可能性がないことが示されている。
【００４３】
続いて、レジスタ割付部２０２は、字句・構文解析部２０１による解析結果に基づいて、ソースファイルＤ１に記述されている変数にレジスタを割付ける（Ｓ３）。図５（ｂ）の例では、関数subは変数i、変数rに$4、$8が夫々割付けられ、関数testは変数c、変数i、変数sumに、$9、$10、$11が夫々割付けられている。関数mainは変数を使用していないので、レジスタ割付けの対象にはならない。
【００４４】
すると、保証レジスタ抽出部２０５は、レジスタ割付部２０２によるレジスタ割付け結果に基づいて保証レジスタ情報Ｄ５を生成する（Ｓ４）。図８は、保証レジスタ情報Ｄ５の一例を示す図である。保証レジスタ情報Ｄ５は、関数subでは、保証レジスタとして使用することが規定されているレジスタのうちの$8が使用され、関数testでは$9、$10、および$11が使用されていることを示している。
【００４５】
なお、ターゲットプロセッサがコアレジスタとコプロセッサレジスタのように複数の種類を持っており、それらのレジスタについてレジスタ割付がレジスタ割付部２０２によってなされている場合がある。保証レジスタ抽出部２０５は、レジスタの種類に関係なく全ての保証レジスタに関する保証レジスタ情報Ｄ５を生成する。
【００４６】
続いて、アセンブラコード生成部２０３は、レジスタ割付部２０２によるレジスタ割付け結果に基づいて第１アセンブラファイルＤ２を生成する（Ｓ５）。ここでは図５（ｂ）に示した第１アセンブラファイルＤ２が生成される。
【００４７】
退避コード情報生成部２０６は、関数呼出情報Ｄ４および保証レジスタ情報Ｄ５に基づいて、退避コード情報Ｄ６を生成する（Ｓ６）。図９は、退避コード情報生成部２０６が退避コード情報Ｄ６を生成する動作を説明するフローチャートである。図１０は、生成される退避コード情報Ｄ６の一例を示す図である。
【００４８】
図９に示すように、退避コード情報生成部２０６は、保証レジスタ情報Ｄ５に基づいて、一時情報としての退避コード情報Ｄ６を作成する（Ｓ１１）。ここで、作成された直後の一時情報としての退避コード情報Ｄ６を初期状態の退避コード情報Ｄ６ということとする。
【００４９】
図１０（ａ）は、Ｓ１１において作成された初期状態の退避コード情報Ｄ６の例を示す図である。一時情報としての退避コード情報Ｄ６には、退避コード移動処理前の退避コード生成対象となる保証レジスタ名の関数毎の記述（移動前情報）と、退避コードの移動後の一時的な移動先を示すための保証レジスタ名の関数毎の記述（移動後情報）と、を備えている。保証レジスタ名の関数毎の記述は、該記述において保証レジスタが属する関数がその保証レジスタを退避させる退避コードの挿入位置であることを示している。初期状態の退避コード情報Ｄ６においては、移動後情報は移動前情報と等しい値であることとする。なお、移動前情報は保証レジスタ情報Ｄ５と等しいため、一時情報としての退避コード情報Ｄ６から移動前情報を省き、以降の処理においてはコンパイル装置２００は移動前情報の代わりに保証レジスタ情報Ｄ５を使用するようにしてもよい。
【００５０】
Ｓ１１の後、退避コード情報生成部２０６は、退避コード情報Ｄ６のうちから関数を１つ選択する（Ｓ１２）。そして、退避コード情報生成部２０６は、関数呼出情報Ｄ４を参照して、選択した関数が、該関数を呼び出す呼び出し関数を全て把握できる関数であるか否かを判定する（Ｓ１３）。ここで、全て把握できる関数とは、該関数を呼び出す呼び出し関数のすべてが他のファイルから呼び出される関数でなく、かつ動的呼び出しにより呼び出される可能性がない関数である。
【００５１】
すべての呼び出し関数が把握できる関数であった場合（Ｓ１３、Ｙｅｓ）、退避コード情報生成部２０６は、退避コード情報Ｄ６のうちの移動後情報を参照し、選択した関数の移動後情報にレジスタ名が記述されているか否かを判定する（Ｓ１４）。
【００５２】
選択した関数の移動後情報にレジスタ名が記述されていた場合（Ｓ１４、Ｙｅｓ）、退避コード情報生成部２０６は、選択した関数の移動後情報に記述されていたレジスタのうち、選択した関数を呼び出す呼び出し関数のうちのどの呼び出し関数の移動前情報にも同一のレジスタ名が記述されていないレジスタがあるか否かを判定する（Ｓ１５）。
【００５３】
どの呼び出し関数の移動前情報にも同一のレジスタ名が記述されていないレジスタがあった場合（Ｓ１５、Ｙｅｓ）、退避コード情報生成部２０６は、そのレジスタに対する退避コードを移動対象であると判定（決定）し（Ｓ１６）、一時情報としての退避コード情報Ｄ６を更新する（Ｓ１７）。具体的には、退避コード情報生成部２０６は、選択した関数の移動後情報から移動対象であると判定されたレジスタ名を削除し、選択した関数を呼び出すすべての呼び出し関数の移動後情報に該レジスタ名を記入する。なお、退避コード情報生成部２０６は、記入先にすでに該当するレジスタ名が存在した場合、その記入先にはそのレジスタ名を記入しない。
【００５４】
選択した関数が呼び出し関数をすべて把握できる関数ではなかった場合（Ｓ１３、Ｎｏ）、退避コード情報生成部２０６は、選択した関数には移動対象となる退避コードはない、と判定（決定）する（Ｓ１８）。
【００５５】
同様に、移動後情報にレジスタ名称が記述されていなかった場合（Ｓ１４、Ｎｏ）や、どの呼び出し関数の移動前情報にも同一のレジスタ名が記述されていないレジスタがなかった場合（Ｓ１５、Ｎｏ）、Ｓ１８へ移行する。
【００５６】
Ｓ１７またはＳ１８の後、退避コード情報生成部２０６は、すべての関数が選択済みであるか否かを判定もする（Ｓ１９）。未選択の関数がある場合（Ｓ１９、Ｎｏ）、Ｓ１２へ移行し、未選択の関数がなくなるまでＳ１２〜Ｓ１８を繰り返す。
【００５７】
すべての関数が選択済みであった場合（Ｓ１９、Ｙｅｓ）、退避コード情報生成部２０６は、Ｓ１２〜Ｓ１９の処理によって一時情報としての退避コード情報Ｄ６が更新されたか否か、を判定する（Ｓ２０）。更新された場合（Ｓ２０、Ｙｅｓ）、退避コード情報生成部２０６は、すべての関数を未選択とし（Ｓ２１）、Ｓ１２へ移行する。更新されなかった場合（Ｓ２０、Ｎｏ）、これ以上新たに移動対象となる退避コードはないので、退避コード情報生成部２０６の動作がリターンとなる。なお、１回目のＳ２０の判定処理においては、初期状態の退避コード情報Ｄ６から更新されたか否か、２回目以降のＳ２０の判定処理においては、退避コード情報生成部２０６は、前回のＳ２０の判定処理以降に一時情報としての退避コード情報Ｄ６が更新されたか否かを判定することとする。図１０（ｂ）は、Ｓ６の処理を経た後における退避コード情報Ｄ６である。
【００５８】
Ｓ６の後、退避コード移動処理部２０７は、生成された退避コード情報Ｄ６に基づいて、第１アセンブラファイルＤ２に対して退避コード移動処理を施し、第２アセンブラファイルＤ３を生成する（Ｓ７）。退避コード移動処理は、移動前情報に記述されており、かつ移動後情報に記述されていない保証レジスタを関数毎に抽出し、抽出した保証レジスタを保護するための関数毎の退避コードを移動前情報に記述されている関数の出入り口から削除するとともに、移動後情報に記述されており、かつ移動前情報に記述されていない保証レジスタを関数毎に抽出し、抽出した保証レジスタを保護するための退避コードを移動後情報に記述されている関数の出入り口に挿入することである。例えば、図１０（ｂ）の退避コード情報Ｄ６によれば、退避コード移動処理部２０７は、関数subから$8、関数testから$9〜$11に関する退避コードを削除し、関数mainに$8〜$11に関する退避コードを記入する。すなわち、$8に関する退避コードが関数subから関数mainへ移動し、$9〜$11に関する退避コードが関数testから関数mainへ移動することになる。なお、退避コード移動処理として、退避コード移動処理部２０７は、移動前情報に記述されている保証レジスタの退避コードを全て削除し、移動後情報に記述されている保証レジスタの退避コードを全て追加するようにしてもよい。
【００５９】
図１１は、生成された第２アセンブラファイルＤ３に記述されている第２アセンブラコードの例である。図５（ｂ）の第１アセンブラコードの例に記述されていた関数sub、関数testの退避コードが、図１１の第２アセンブラコードでは関数mainに移動させられていることがわかる。この第２アセンブラコードでは、関数testがループ処理を実行する毎に実行される$8の退避コードが、関数mainすなわちこのループ処理外に移動しているので、第１アセンブラコードに比べて$8の退避コードの実行回数が減少する。
【００６０】
複数の被呼び出し関数から同一の保証レジスタに関する退避コードが同一の呼び出し関数に移動する場合について説明する。図１２−１および図１２−２は、この場合の具体例を説明するための図である。
【００６１】
図１２−１（ａ）は、関数呼出情報Ｄ４の一例を示す図である。この関数呼出情報Ｄ４には、関数testは関数sub1および関数sub2を呼び出し、関数testは関数main（図示せず）から呼び出されることを示している。また、この関数呼出情報Ｄ４には、関数test、関数sub1、および関数sub2は、他のファイルから呼び出される関数ではなく、かつ動的呼出しによって呼出される可能性はないことが記述されている。
【００６２】
図１２−１（ｂ）は、初期状態の退避コード情報Ｄ６の一例を示す図である。
Ｓ１２において関数sub1が選択されると、図１２−１（ｂ）の退避コード情報Ｄ６が更新され、退避コード情報Ｄ６は、関数sub1の移動後情報から$8が削除され、関数testの移動後情報に$8が追加された状態となる（図１２−２（ｃ））。そして、再度Ｓ１２へ移行して関数sub2が選択されると、図１２−２（ｃ）の退避コード情報Ｄ６がさらに更新されて、退避コード情報Ｄ６は、関数sub2の移動後情報から$8が削除された状態となる（図１２−２（ｄ））。ここで、関数sub2の移動後情報から削除された$8が関数testの移動後情報に追加されていないのは、関数testの移動後情報には関数sub1から削除された$8がすでに追加されているためである。
【００６３】
図１３は、第１アセンブラコード（図１２−１（ｂ））と第２アセンブラコード（図１２−２（ｄ））とを比較した図である。第１アセンブラコード１０４では、関数sub1および関数sub2はともに出入り口に$8の退避コードを備えている。これに対して、第２アセンブラコード１０５では、関数testの出入り口に$8の退避コードを備えている。すなわち、第２アセンブラコード１０５は、第１アセンブラコード１０４に比べ、$8の退避コード１つ分が減少している。
【００６４】
このように、複数の被呼び出し関数から同一の保証レジスタに関する退避コードが同一の呼び出し関数に移動する場合、移動先で退避コードが重複しないようにしているので、アセンブラコードのコードサイズを減少させることができる。
【００６５】
なお、特許文献１によれば、退避コードを削除することによって退避コードの実行回数を減少させる。しかしながら、退避コードを削除するためには、その退避コードを削除してもプログラムの動作に支障がない必要がある。言い換えると、アプリケーションプログラムの最初の関数から退避コードを削除する関数の間に、そのレジスタが使用されていないことが退避コードを削除するための条件となる。これに対して、本発明の第１の実施の形態では退避コードを呼び出された関数から呼び出した関数に移動させるだけなので、呼び出した関数のさらに上位の関数から見ると、保証レジスタの値は保存されており、プログラムの動作には支障がない。すなわち、本発明の第１の実施の形態によれば、呼び出した関数でそのレジスタが使用されていないことだけが退避コードの移動の条件であるので、特許文献１の技術では退避コードが削除できない場合であっても退避コードを移動することで、特許文献１の技術よりも退避コードの実行回数をさらに少なくしたアセンブラコードを生成することができる。
【００６６】
なお、本発明の第１の実施の形態では、コアレジスタ、コプロセッサレジスタの区別なく全てのレジスタに対する保証レジスタ情報Ｄ５を作成するようにしている。コアレジスタとコプロセッサレジスタの区別があるプロセッサにおいては、ローカル関数ではコプロセッサレジスタを多用した処理を行い、それらを呼び出す上位の関数ではコプロセッサレジスタではなくコアレジスタを使用した処理を行う場合がある。このような場合においては、ローカル関数でのコプロセッサレジスタの退避コードを上位の関数に移動させることができるケースが多くなるので、退避コードの実行回数を大きく減らすことができる。
【００６７】
以上述べたように、本発明の第１の実施の形態によれば、ソースファイルＤ１から、保証レジスタを使用する関数の出入り口に前記使用される保証レジスタを保護するための退避コードを挿入した第１アセンブラファイルＤ２を生成し、第１アセンブラファイルＤ２の生成過程において出力される構文解析結果に基づいてソースファイルＤ１に含まれる関数間の呼び出し関係を記述した関数呼出情報を生成し、第１アセンブラファイルＤ２の生成過程において出力されるレジスタ割付け結果に基づいて、ソースコードに含まれる関数内で使用されている保証レジスタの関数毎のリストである保証レジスタ情報Ｄ５を生成し、関数呼出情報Ｄ４および保証レジスタ情報Ｄ５に基づいて、退避コードを該退避コードが挿入されている関数から該関数の呼び出し元の関数への移動が可能であるか否かを判定する判定処理を退避コード毎に実行して退避コードの移動後の挿入先の関数を退避コード毎に示す退避コード情報Ｄ６を生成し、退避コード情報に基づいて第１アセンブラファイルＤ２に記述されている退避コードに対して退避コード移動処理を実行して第２アセンブラコードＤ３を生成するように構成したので、被呼び出し関数の出入り口に挿入されている退避コードを呼び出し関数の出入り口に移動させることができるので、レジスタ退避の実行回数を少なくしたアセンブラコードを作成することができる。
【００６８】
また、一時的な移動先の関数を退避コード毎に示す一時情報としての退避コード情報Ｄ６を作成し、判定処理を実行する毎に一時情報としての退避コード情報Ｄ６を更新し、更新前後で一時情報としての退避コード情報Ｄ６が変化しなくなったとき、一時情報としての退避コード情報Ｄ６を退避コード移動処理を実行するための退避コード情報Ｄ６とするようにしたので、退避コードの実行回数を可及的に少なくしたアセンブラコードを作成することができる。
【００６９】
なお、以上の説明においては、スタック領域の確保・解放命令を伴ったpush、pop命令を退避コードとして説明したが、退避コードは、レジスタ内容を退避／復帰させるための命令であればどのような命令であってもよい。push、pop命令以外の退避コードとしては、たとえば、スタック領域の確保・解放命令を伴わないロード・ストア命令とスタックポインタの加減命令の組でも退避コードとして使用できる。また、ソースファイルＤ１の例としてＣ言語で記述されたプログラムを挙げたが、ソースファイルＤ１の記述言語はＣ言語以外の関数の概念があり、コンパイラによってアセンブラコードに変換される高級言語であっても構わない。
【００７０】
なお、最終的にターゲットプロセッサで動作する実行ファイルを得るためには、ユーザは、アセンブラプログラムを用いて第２アセンブラファイルＤ３をリロケータブルファイルに変換する。そして、ユーザは、リンクプログラムを用いて、ファイル毎に作成されたリロケータブルファイルをすべて結合するとともにアドレス解決を行い、実行ファイルを得る。
【００７１】
図１４に示すように、第１の実施の形態のコンパイルプログラム６は、第２アセンブラファイルＤ３をリロケータブルファイルに変換するためのアセンブルプログラム７とともにパッケージ化されたプログラムパッケージ８の一部として提供されるようにしてもよい。また、図１５に示すように、第１の実施の形態のコンパイルプログラム６は、アセンブルプログラム７、およびファイル毎に作成されたリロケータブルファイルをすべて結合するとともにアドレス解決を行うためのリンクプログラム９とともにパッケージ化されたプログラムパッケージ１０のうちの一部として提供されるようにしてもよい。
【００７２】
（第２の実施の形態）
本発明の第２の実施の形態は、ソースコードをファイル毎にリロケータブルファイルに変換するコンパイル・アセンブル装置に適用される。
【００７３】
図１６は、第２の実施の形態のコンパイル・アセンブル装置の構成図である。なお、第１の実施の形態と同様の機能を備える構成部については第１の実施の形態と同じ符号を付し、詳細な説明を省略する。
【００７４】
コンパイル・アセンブル装置３００は、入力されたソースファイルＤ１から第１アセンブラファイルＤ２とともに関数呼出情報Ｄ４および保証レジスタ情報Ｄ５を生成するコンパイル部３１０と、第１アセンブラファイルＤ２、関数呼出情報Ｄ４および保証レジスタ情報Ｄ５に基づいて第２アセンブラファイルＤ３を生成し、生成した第２アセンブラファイルＤ３からリロケータブルファイルＤ７を生成するアセンブル部３２０と、を備えている。
【００７５】
コンパイル部３１０は、ソースファイルＤ１に対して字句・構文解析を実行する字句・構文解析部２０１と、字句・構文解析部２０１による解析結果に基づいて関数呼出情報Ｄ４を生成する関数呼出抽出部２０４と、字句・構文解析部２０１による解析結果に基づいて変数をレジスタに割付けるレジスタ割付部２０２と、レジスタ割付部２０２によるレジスタ割付結果に基づいて保証レジスタ情報Ｄ５を生成する保証レジスタ抽出部２０５と、レジスタ割付部２０２によるレジスタ割付け結果に基づいて第１アセンブラファイルＤ２を生成するアセンブラコード生成部２０３と、を備えている。
【００７６】
また、アセンブル部３２０は、関数呼出情報Ｄ４および保証レジスタ情報Ｄ５に基づいて退避コード情報Ｄ６を生成する退避コード情報生成部２０６と、退避コード情報Ｄ６に基づいて第１アセンブラファイルＤ２に対して退避コード移動処理を実行し、第２アセンブラファイルＤ３を生成する退避コード移動処理部２０７と、第２アセンブラファイルＤ３からリロケータブルファイルＤ７を生成するアセンブラファイル変換部３２１と、を備えている。
【００７７】
第２の実施の形態のコンパイル・アセンブル装置３００は図１４と等しいハードウェア構成により実現される。ただし、コンパイル・アセンブル装置３００においては、関数呼出抽出部２０４、保証レジスタ抽出部２０５、退避コード情報生成部２０６、退避コード移動処理部２０７のうち、関数呼出抽出部２０４および保証レジスタ抽出部２０５がコンパイルプログラム６によって実現され、退避コード情報生成部２０６および退避コード移動処理部２０７がアセンブルプログラム７によって実現される点が第１の実施の形態と異なる。
【００７８】
このように、ソースファイルＤ１から第１アセンブラファイルＤ２を生成し、生成した第１アセンブラファイルＤ２に対して退避コード移動処理を施して退避コードの実行回数を少なくしたアセンブラファイルである第２アセンブラファイルＤ３を生成するので、結果として保証レジスタの退避／復帰の実行回数を低減したリロケータブルファイルＤ７を生成することができる。
【符号の説明】
【００７９】
１  ＣＰＵ、２  ＲＯＭ、３  ＲＡＭ、４  入力部、５  表示部、６  コンパイルプログラム、７  アセンブルプログラム、８  パッケージプログラム、９  リンクプログラム、１０  パッケージプログラム、２００  コンパイル装置、２０１  字句・構文解析部、２０２  レジスタ割付部、２０３  アセンブラコード生成部、２０４  関数呼出抽出部、２０５  保証レジスタ抽出部、２０６  退避コード情報生成部、２０７  退避コード移動処理部、３００  コンパイル・アセンブル装置、３１０  コンパイル部、３２０  アセンブル部、３２１  アセンブラファイル変換部。
【図１】
2011141676.tif 000003
【図２】
2011141676.tif 000004
【図３】
2011141676.tif 000005
【図４】
2011141676.tif 000006
【図５】
2011141676.tif 000007
【図６】
2011141676.tif 000008
【図７】
2011141676.tif 000009
【図８】
2011141676.tif 000010
【図９】
2011141676.tif 000011
【図１０】
2011141676.tif 000012
【図１１】
2011141676.tif 000013
【図１２−１】
2011141676.tif 000014
【図１２−２】
2011141676.tif 000015
【図１３】
2011141676.tif 000016
【図１４】
2011141676.tif 000017
【図１５】
2011141676.tif 000018
【図１６】
2011141676.tif 000019