(57)【特許請求の範囲】
【請求項１】
メモリアクセスを含むバイナリコードを最適化するコンパイル方法であって、コンピュータに、
前記バイナリコード内に含まれるコール（call）命令で呼ばれるコードをインラインすることに応じて、前記各コール命令及びインラインされたコードにコール番号を付与するステップであって、当該コール番号について、呼ぶ方のコール命令のコール番号を親とし、呼ばれる方のコール命令のコール番号を子とする親子関係情報をさらに作成するステップを含む、前記付与するステップと、
スタックポインターがエスケープしていた場合に、当該エスケープしたスタックポインターをベースアドレスとするメモリアクセスのうち、当該エスケープを引き起こした命令に付与されたコール番号と、当該コール番号の祖先のコール番号とに属しているメモリアクセスのローカル変数アクセスへの置換を禁止し、一方、残りの禁止しなかったメモリアクセスをローカル変数アクセスに置換するステップであって、前記祖先のコール番号は前記親子関係情報から特定される、前記置換するステップと
を実行させることを含む、前記方法。
【請求項２】
メモリアクセスを含むバイナリコードを最適化するコンパイル方法であって、コンピュータに、
前記バイナリコード内に含まれるコール（call）命令で呼ばれるコードをインラインすることに応じて、前記各コール命令及びインラインされたコードにコール番号を付与するステップであって、当該コール番号について、呼ぶ方のコール命令のコール番号を親とし、呼ばれる方のコール命令のコール番号を子とする親子関係情報をさらに作成するステップを含む、前記付与するステップと、
前記メモリアクセスのうち、各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換するステップと、
を実行させることを含み、
各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換する前記ステップが、
前記バイナリコード内においてスタックポインターとしてのレジスタ（以下、第１のレジスタという）を見つけて、当該スタックポインターを他のレジスタ（以下、第２のレジスタという）に保存するステップと、
前記バイナリコード内において、前記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該見つけたメモリアクセスについて、前記第２のレジスタの値からのオフセットを計算するステップと、
前記各メモリアクセスについて、前記コール番号と前記第２のレジスタの値からのオフセットとの組を基にローカル変数を識別するための番号（以下、ローカル変数番号）を作成するステップと、
前記作成されたローカル変数番号に基づいて、前記各レジスタの値が退避されるスタック領域内へのメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該メモリアクセスを当該割り当てられたローカル変数アクセスに置換するステップと
を含む、前記方法。
【請求項３】
前記禁止しなかったメモリアクセスをローカル変数アクセスに置換する前記ステップが、
前記バイナリコード内においてスタックポインターとしてのレジスタ（以下、第１のレジスタという）を見つけて、当該スタックポインターを他のレジスタ（以下、第２のレジスタという）に保存するステップと、
前記バイナリコード内において、第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該メモリアクセスについて、前記第２のレジスタの値からのオフセットを計算するステップと、
前記各メモリアクセスについて、前記コール番号と前記第２のレジスタの値からのオフセットの組を基にローカル変数を識別するための番号（以下、ローカル変数番号）を作成するステップと、
前記作成されたローカル変数番号に基づいて、前記禁止しなかったメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該禁止しなかったメモリアクセスを当該割り当てられたローカル変数アクセスに置換するステップと
を含む、請求項１に記載の方法。
【請求項４】
前記スタックポインターは、
スタックポインターの値がメモリ内に書き込まれていること、
インラインされないコール命令があること、及び
例外を起こしうる命令があること
の１つ又はそれらの組み合わせである場合にエスケープしている、請求項１に記載の方法。
【請求項５】
前記コンピュータに、
バイトコード内に含まれるコール命令のインラインしたメソッドの入口部又は出口部について、当該入口部又は出口部の外側と内側とで同じオフセットを有するメモリアクセスがある場合にローカル変数のコピーを前記入口部又は前記出口部にそれぞれ生成するステップをさらに実行させることを含む、請求項２又は３に記載の方法。
【請求項６】
前記コンピュータに、
スタックポインターがエスケープしていなく、且つスタックポインターを使ったメモリアクセスが全てなくなった場合に、スタックポインターの値を増減させる命令を削除するステップをさらに実行させることを含む、請求項１に記載の方法。
【請求項７】
メモリアクセスを含むバイナリコードを最適化するコンパイル方法であって、コンピュータに、
前記メモリアクセスのうち、各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換するステップ
を実行させることを含み、
各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換する前記ステップが、
前記バイナリコード内においてスタックポインターとしてのレジスタ（以下、第１のレジスタという）を見つけて、当該スタックポインターを他のレジスタ（以下、第２のレジスタという）に保存するステップと、
前記バイナリコード内において、前記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該見つけたメモリアクセスについて、前記第２のレジスタの値からのオフセットを計算するステップと、
前記計算されたオフセットのうち、オフセットが同じであるメモリアクセスの集合を取得するステップと、
前記取得した集合のメモリアクセスによりアクセスされるスタック領域がエイリアスされない領域であるかどうかを、前記取得した集合内の各メモリアクセスによりアクセスされる領域が前記各レジスタの値が退避されるスタック領域内への前記メモリアクセスのオフセット値域に入っているか否かによって判断するステップと
を含む、前記方法。
【請求項８】
メモリアクセスを含むバイナリコードを最適化するコンピュータであって、
前記バイナリコード内に含まれるコール（call）命令で呼ばれるコードをインラインすることに応じて、前記各コール命令及びインラインされたコードにコール番号を付与する番号付与部であって、当該コール番号について、呼ぶ方のコール命令のコール番号を親とし、呼ばれる方のコール命令のコール番号を子とする親子関係情報をさらに作成する、前記番号付与部と、
スタックポインターがエスケープしていた場合に、当該エスケープしたスタックポインターをベースアドレスとするメモリアクセスのうち、当該エスケープを引き起こした命令に付与されたコール番号と、当該コール番号の祖先のコール番号とに属しているメモリアクセスのローカル変数アクセスへの置換を禁止し、一方、残りの禁止しなかったメモリアクセスをローカル変数アクセスに置換する置換部であって、前記祖先のコール番号は前記親子関係情報から特定される、前記置換部と
を備えている、前記コンピュータ。
【請求項９】
メモリアクセスを含むバイナリコードを最適化するコンピュータであって、
前記バイナリコード内に含まれるコール（call）命令で呼ばれるコードをインラインすることに応じて、前記各コール命令及びインラインされたコードにコール番号を付与する番号付与部であって、当該コール番号について、呼ぶ方のコール命令のコール番号を親とし、呼ばれる方のコール命令のコール番号を子とする親子関係情報をさらに作成する、前記番号付与部と、
前記メモリアクセスのうち、各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換する置換部と
を備えており、
前記置換部は、
前記バイナリコード内においてスタックポインターとしてのレジスタ（以下、第１のレジスタという）を見つけて、当該スタックポインターを他のレジスタ（以下、第２のレジスタという）に保存し、
前記バイナリコード内において、前記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該見つけたメモリアクセスについて、前記第２のレジスタの値からのオフセットを計算し、
前記各メモリアクセスについて、前記コール番号と前記第２のレジスタの値からのオフセットとの組を基にローカル変数を識別するための番号（以下、ローカル変数番号）を作成し、
前記作成されたローカル変数番号に基づいて、前記各レジスタの値が退避されるスタック領域内へのメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該メモリアクセスを当該割り当てられたローカル変数アクセスに置換する、
前記コンピュータ。
【請求項１０】
前記置換部が、
前記バイナリコード内においてスタックポインターとしてのレジスタ（以下、第１のレジスタという）を見つけて他のレジスタ（以下、第２のレジスタという）に保存し、
前記バイナリコード内において、第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該メモリアクセスについて、前記第２のレジスタの値からのオフセットを計算し、
前記各メモリアクセスについて、前記コール番号と前記第２のレジスタの値からのオフセットの組を基にローカル変数を識別するための番号（ローカル変数番号）を作成し、
前記作成されたローカル変数番号に基づいて、前記禁止しなかったメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該禁止しなかったメモリアクセスを当該割り当てられたローカル変数アクセスに置換する、請求項８に記載のコンピュータ。
【請求項１１】
前記スタックポインターは、
スタックポインターの値がメモリ内に書き込まれていること、
インラインされないコール命令があること、及び
例外を起こしうる命令があること
の１つ又はそれらの組み合わせである場合にエスケープしている、請求項８に記載のコンピュータ。
【請求項１２】
バイトコード内に含まれるコール命令のインラインしたメソッドの入口部又は出口部について、当該入口部又は出口部の外側と内側とで同じオフセットを有するメモリアクセスがある場合にローカル変数のコピーを前記入口部又は前記出口部にそれぞれ生成する生成部をさらに備えている、請求項８又は９に記載のコンピュータ。
【請求項１３】
スタックポインターがエスケープしていなく、且つスタックポインターを使ったメモリアクセスが全てなくなった場合に、スタックポインターの値を増減させる命令を削除する削除部をさらに備えている、請求項８に記載のコンピュータ。
【請求項１４】
メモリアクセスを含むバイナリコードを最適化するコンピュータであって、
前記メモリアクセスのうち、各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換する置換部
を備えており、
前記置換部が、
前記バイナリコード内においてスタックポインターとしてのレジスタ（以下、第１のレジスタという）を見つけて、当該スタックポインターを他のレジスタ（以下、第２のレジスタという）に保存し、
前記バイナリコード内において、前記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該見つけたメモリアクセスについて、前記第２のレジスタの値からのオフセットを計算し、
前記計算されたオフセットのうち、オフセットが同じであるメモリアクセスの集合を取得し、
前記取得した集合のメモリアクセスによりアクセスされるスタック領域がエイリアスされない領域であるかどうかを、前記取得した集合内の各メモリアクセスによりアクセスされる領域が前記各レジスタの値が退避されるスタック領域内への前記メモリアクセスのオフセット値域に入っているか否かによって判断する、前記コンピュータ。
【請求項１５】
コンピュータに、請求項１〜７のいずれか一項に記載の方法の各ステップを実行させるコンピュータ・プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、バイナリコードを最適化するコンパイル方法、及びそのコンパイラシステム、並びにコンピュータ・プログラムに関する。
【背景技術】
【０００２】
バイナリコードはしばしば、レジスタに対するセーブ（save）命令及びリストア（restore）命令を含む。例えば、ＩＢＭ（商標）のz/Architectureのアセンブラ・ニーモニックである、ＳＴＭ（store multiple）及びＬＭ（load multiple）である。そして、当該バイナリコードにおいて、レジスタをスタックに保存し、そして復帰するために、メモリアクセスが多く生成される。そこで、コンピュータ資源のパフォーマンス向上のために、これらメモリアクセスをレジスタアクセスに置き換えて高速化することが行われている。
【０００３】
下記特許文献１は、コンピュータ処理システムにおいてスタック参照をリネームする方法を記載する（第４カラム、１７〜２０行）。当該方法の第１の態様は、アーキテクチャ的に定義されたスタックアクセス方法を使用するスタック参照を検出するステップと、当該スタック参照をプロセッサ内部レジスタに対する参照に置き換えるステップとを含む（第４カラム、２１〜２７行）。当該方法の第２の態様は、コンピュータ処理システムのプロセッサ内部レジスタとメイン・メモリとの間のアーキテクテッド状態を同期化するステップをさらに含む（第４カラム、２８〜３１行）。しかしながら、特許文献１に記載の方法は、コンピュータシステム中に組み込まれる新たなハードウェアの仕組みであり、命令実行時において行われる処理を変形する処理である。
【０００４】
下記非特許文献１は、冗長ロード（load）命令除去（RLR）最適化分析を記載する（２３〜２８頁、第４章「トレースに対する冗長ロード命令除去」）。しかしながら、非特許文献１は、ストア（store）命令の最適化（除去等）を行っていない。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】米国特許第７０８５９１４号明細書
【非特許文献】
【０００６】
【非特許文献１】Joshua Jacobs, “Improving Memory Performance through Runtime Optimization”, [online], May 2002, インターネット＜URL:http://groups.csail.mit.edu/cag/rio/josh-meng-thesis.pdf＞
【発明の概要】
【発明が解決しようとする課題】
【０００７】
コンピュータ資源のパフォーマンス向上のために、メモリアクセスをレジスタアクセスに置き換えて高速化するための新たな手法が求められている。また、多くの場合、顧客はソースコードでもある既存のバイナリコードを再コンパイルしたくないか、又は再コンパイルすることができない。さらに、バイナリコード内に含まれるコール（call）命令で呼ばれるコードがコンパイラにより多段にインライン展開された場合であっても、ストア命令及びロード命令のいずれもが効果的に最適化する手法が求められている。
【課題を解決するための手段】
【０００８】
スタックエリアは自分のスレッド以外からはアクセスされないという性質を有する。そこで、本発明者らは、このスタックエリアに注目して、バイナリコードの最適化を行うことを試みた。
まず、本発明者らは、エスケープ解析を使った最適化を抑える主な理由がスタックポインターのセーブ命令及びリストア命令であることを発見した。本発明者らはまた、これらのセーブ命令及びリストア命令が実際にはエイリアスされないことを発見した。これらの発見は、バイナリコードを最適化するために重要である。本発明は、これらの発見に基づいてなされた。すなわち、本発明は、これらのセーブ命令及びリストア命令をまず最適化することにより、エスケープ命令を削減させることができた。
【０００９】
本発明は、メモリアクセスを含むバイナリコードを最適化するコンパイル方法を提供する。当該方法は、コンピュータ、特にはコンパイラ装置によって実行されうる。当該方法は、上記メモリアクセスのうち、各レジスタの値が退避されるスタック領域、例えばレジスタ・セーブ・エリア内へのメモリアクセスについて最適化を行う。また、当該方法は、上記メモリアクセスのうち、各レジスタの値が退避されるスタック領域以外のメモリアクセスについてさらに最適化を行う。当該方法において、バイナリコード内に含まれるcall命令で呼ばれるコードをインラインすることに応じて、前記各コール命令及びインラインされたコードに付与されたcall番号を使用しうる。
【００１０】
また、本発明は、コンピュータ、特にはコンパイラ装置に上記コンパイル方法を実行させるコンピュータ・プログラムを提供する。
【００１１】
また、本発明は、メモリアクセスを含むバイナリコードを最適化するコンピュータ、特にはコンパイラ装置を提供する。
【発明の効果】
【００１２】
本発明のコンパイル方法では、各レジスタの値が退避されるスタック領域内へのメモリアクセスを最適化することによって、エスケープを引き起こす命令を削減することが可能である。
また、本発明のコンパイラ方法は特には、多段にインライン展開された場合であっても、ストア命令及びロード命令のいずれをも効果的に最適化することが可能である。本発明のコンパイラ方法は特に、バイトコード内に含まれるcall命令が呼ばれるコードがインラインされる場合に有用である。
【図面の簡単な説明】
【００１３】
【図１】本発明の実施形態におけるコンピュータ・ハードウェアの基本的なブロック図を示す。
【図２】本発明の実施形態における、コンパイラの機能ブロック図を示す。
【図３】本発明が組み込まれうる１つの実施態様であるＪａｖａコンパイラを示す。
【図４Ａ】本発明の第１の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
【図４Ｂ】図４Ａのステップ４０４のサブルーチンanalyze_uses(def, offset)の第１の実施態様を示す。
【図４Ｃ】図４Ａのステップ４０４のサブルーチンanalyze_uses(def, offset)の第２の実施態様を示す。
【図４Ｄ】図４Ａのステップ４０５のサブルーチンpropagate()の実施態様を示す。
【図５Ａ】本発明の第２の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
【図５Ｂ】図５Ａのステップ５０４のサブルーチンanalyze_uses(def, offset)の第１の実施態様を示す。
【図５Ｃ】図５Ａのステップ５０４のサブルーチンanalyze_uses(def, offset)の第２の実施態様を示す。
【図５Ｄ】図５Ａのステップ５０５のサブルーチンpropagate()の実施態様を示す。
【図６Ａ】本発明の第３の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
【図６Ｂ】図６Ａのステップ６０５のサブルーチンanalyze_uses(def, offset)の実施態様を示す。
【図６Ｃ】図６Ａのステップ６０６のサブルーチンpropagate()の実施態様を示す。
【図７Ａ】本発明の第４の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
【図７Ｂ】図７Ａのステップ７０５のサブルーチンanalyze_uses(def, offset)の実施態様を示す。
【図７Ｃ】図７Ａのステップ７０６のサブルーチンpropagate()の実施態様を示す。
【図７Ｄ】図７Ａのステップ７０８のサブルーチンanalyze_accesses()の実施態様を示す。
【図７Ｅ】図７Ａのステップ７１０のサブルーチンgenerate_copy()の実施態様を示す。
【図８Ａ】本発明の第１〜第４の実施態様におけるローカル変数の割り当てのフローチャートを示す。
【図８Ｂ】本発明の第３の実施態様（図６Ａ〜図６Ｃ）及び本発明の第４の実施態様（図７Ａ〜図７Ｅ）におけるローカル変数の割り当てのフローチャートを示す。
【図９Ａ】call番号を設定しない場合（９０１）及びcall番号を設定する場合（９０２）におけるローカル変数アクセスへの置換の禁止の相違を示す。
【図９Ｂ】多段にインラインされている状態を示す。
【図１０】変換対象であるバイナリコードと、当該バイナリコードに本発明の実施態様の最適化を適用した後に生成されるコードを示す。
【発明を実施するための形態】
【００１４】
以下に、本発明の代表的な第１〜第４の実施態様を説明するとともに、当該実施態様が後に述べる各図面どのように対応するかについて括弧書きで説明する。次に、各図面に従って本発明の第１〜第４の実施形態をさらに説明する。なお、本発明の第１〜第４の実施形態は、本発明の好適な形態を説明するためのものであり、本発明の範囲をここで示すものに限定する意図はないことを理解されたい。
【００１５】
本発明の実施形態において、バイナリコード（図２、２１１）は最適化対象コードである。
【００１６】
本発明の実施態様において、メモリアクセスは、バイナリコード（図２、２１１）に含まれる。本発明の実施態様において、スタックアクセス、すなわちメモリアクセスを２つのカテゴリに分ける。すなわち、各レジスタの値が退避されるスタック領域、例えばレジスタ・セーブ・エリア内へのメモリアクセスと、それ以外のメモリアクセスである。
それ以外のメモリアクセスには、下記がある。
（１）エスケープしていないスタックポインターを介したメモリアクセスである。
（２）スタックポインターがエスケープしていた場合に、当該エスケープしたスタックポインターをベースアドレスとするメモリアクセスのうち、（ｉ）当該エスケープを引き起こした命令に付与されたcall番号と、当該call番号の祖先のcall番号とに属しているメモリアクセス、及び（ｉｉ）（ｉ）以外のメモリアクセスである。call番号とは、バイナリコード内に含まれるcall命令で呼ばれるコードをインラインすることに応じて、各コール命令及びインラインされたコードに付与される番号であり、当該call番号は、呼ぶ方のコール命令のコール番号を親とし、呼ばれる方のコール命令のコール番号を子とする親子関係情報に従う。
【００１７】
本発明では、上記２つのカテゴリに分けたメモリアクセスのうち、各レジスタの値が退避されるスタック領域へのメモリアクセスについてまず最適化をおこなうことが好ましい（下記（Ａ））。その後に、それ以外のメモリアクセスについて最適化をおこなうことが好ましい（下記（Ｂ）又は（Ｃ））。
本発明の実施態様において、メモリアクセスをローカル変数アクセスに置換する態様は、下記（Ａ）〜（Ｃ）の３通りである。
（Ａ）各レジスタの値が退避されるスタック領域へのメモリアクセスをローカル変数アクセスに置換する。当該メモリアクセスについては、スタックポインターがエスケープしているかどうかに関係なく、その全てのメモリアクセスをローカル変数アクセスに置換する。
（Ｂ）スタックポインターがエスケープしていないことを条件に、上記（１）のメモリアクセスをローカル変数アクセスに置換する。
（Ｃ）スタックポインターがエスケープしていた場合に、上記（２）（ｉ）のメモリアクセスのローカル変数アクセスへの置換を禁止し、一方、上記（２）（ｉｉ）のメモリアクセスをローカル変数アクセスに置換する。
本発明の第１の実施態様は上記（Ａ）であり、図４Ａ〜図４Ｄに示されている。
本発明の第２の実施態様は上記（Ａ）と上記（Ｂ）とを組み合わせたものであり、図５Ａ〜図５Ｄに示されている。
本発明の第３の実施態様は、コール命令にcall番号を付与することと、上記（Ａ）とを組み合わせたものであり、図６Ａ〜図６Ｃに示されている。
本発明の第４の実施態様は、コール命令にcall番号を付与することと、上記（Ａ）及び上記（Ｃ）とを組み合わせたものであり、図７Ａ〜図７Ｅに示されている。
【００１８】
本発明の１つの実施態様の方法において、コンピュータ（図１、１０１）は、（ａ）各レジスタの値が退避されるスタック領域内へのメモリアクセスをコンパイラ内のローカル変数アクセスに置換するステップ（図４Ａ、ステップ４０６；図５Ａ、ステップ５０６）を実行する。ステップ（ａ）でバイナリコードの最適化を終了する場合、当該最適化は図４Ａ〜図４Ｄに示す第１の実施態様である。そして、コンピュータ（図１、１０１）は、上記置換されたローカル変数をレジスタ割り当ての対象とし、結果的に上記置換されたローカル変数にレジスタアドレスが割り当てられる。
【００１９】
本発明の実施形態において、「各レジスタの値が退避されるスタック領域」とは、実際にはエイリアスされることがないと分かっている領域であり、オペレーティング・システムのリンケージによって決められる。「各レジスタの値が退避されるスタック領域」は例えば、レジスタ・セーブ・エリアであり、さらに具体的には、プロセッサ内の各レジスタをセーブ又はリストアするためのレジスタ・セーブ・エリアである。
【００２０】
コンピュータ（図１、１０１）はまた、任意的に、（ｂ）スタックポインターがエスケープしていないことを条件に、当該エスケープしていないスタックポインターを介したメモリアクセスをコンパイラ内のローカル変数アクセスに置換するステップ（図５Ａ、ステップ５０７）をさらに実行してもよい。上記ステップ（ａ）に加えて、当該ステップ（ｂ）を実行する場合、当該最適化は図５Ａ〜図５Ｄに示す第２の実施態様である。当該ステップ（ｂ）は、ステップ（ａ）の実行よりも前に実行されてもよい。そして、コンピュータ（図１、１０１）は、上記置換されたローカル変数をレジスタ割り当ての対象とし、結果的に上記置換されたローカル変数にレジスタアドレスが割り当てられる。
【００２１】
本発明の１つの実施態様において、上記ステップ（ａ）は、
上記バイナリコード内においてスタックポインターとしてのレジスタ（第１のレジスタ）を見つけて、当該スタックポインターを他のレジスタ（第２のレジスタ）に保存するステップと（図４Ａ、ステップ４０３；図５Ａ、ステップ５０３）、
上記バイナリコード内において、上記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、そして当該見つけたメモリアクセスについて、上記第２のレジスタの値からのオフセットを計算するステップと（図４Ａ、ステップ４０４及び４０５；図５Ａ、ステップ５０４及び５０５）、
上記計算されたオフセットのうち、オフセットが同じであるメモリアクセスの集合を取得するステップと（図４Ｂ及び図４Ｃ、ステップ４２０及び４４０；図５Ｂ及び図５Ｃ、ステップ５２０及び５４０）、
上記取得した集合のメモリアクセスによりアクセスされるスタック領域がエイリアスされない領域であるかどうかを、上記取得した集合の各メモリアクセスによりアクセスされる領域が前記各レジスタの値が退避されるスタック領域内への前記メモリアクセスのオフセット値域に入っているか否かによって判断するステップと（図４Ａ、ステップ４０６；図５Ａ、ステップ５０６）
を含む。スタックポインターとしてのレジスタは、システムによって定められているスタックポインター用のレジスタ又は特定のパターンで定義されるレジスタでありうる。特定のパターンで定義されるレジスタとは、他のスレッドから参照されることがないとわかるデータ構造へのポインタを得るための、特定の命令列によって定義されるレジスタをいう。
【００２２】
本発明の１つの実施態様において、上記スタックポインターは下記の１つ又はそれらの組み合わせである場合にエスケープする：
（１）スタックポインターの値がメモリ内に書き込まれていること、
（２）インラインされないcall命令があること、及び
（３）例外を起こしうる命令があること。
上記ステップ（ｂ）は、エスケープするスタックポインターをリストに格納するステップ（図４Ｃ、ステップ４４６；図５Ｃ、ステップ５４６）をさらに含んでもよい。
上記ステップ（ｂ）はまた、上記スタックポインターがエスケープしていないことを上記リストが空集合であることによって判断するステップ（図５Ａ、ステップ５０７）をさらに含んでもよい。
【００２３】
本発明の他の実施態様の方法において、コンピュータ（図１、１０１）は、（Ａ）バイナリコード内に含まれるcall命令で呼ばれるコードをインラインすることに応じて、上記各call命令及びインラインされたコードにcall番号、例えば通し番号を付与するステップ（図６Ａ、ステップ６０２；図７Ａ、ステップ７０２）であって、当該call番号について、呼ぶ方のcall命令のcall番号を親とし、呼ばれる方のcall命令のcall番号を子とする親子関係情報、例えば木構造のグラフをさらに作成するステップを含む、上記付与するステップと、（Ｂ）各レジスタの値が退避されるスタック領域内へのメモリアクセスを、コンパイラ内のローカル変数アクセスに置換するステップ（図６Ａ、ステップ６０７；図７Ａ、ステップ７０７）とを実行する。そして、上記ステップ（Ｂ）は、上記ステップ（Ａ）で作成されたcall番号を下記の通り使用する。すなわち、本発明の１つの実施態様において、上記ステップ（Ｂ）の置換することは、
上記バイナリコード内においてスタックポインターとしてのレジスタ（第１のレジスタ）を見つけて、当該スタックポインターを他のレジスタ（第２のレジスタ）に保存するステップと（図６Ａ、ステップ６０４；図７Ａ、ステップ７０４）、
上記バイナリコード内において、上記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該見つけたメモリアクセスについて、上記第２のレジスタの値からのオフセットを計算するステップと（図６Ａ、ステップ６０５及び６０７；図７Ａ、ステップ７０５及び７０６）、
上記各メモリアクセスについて、上記call番号と上記第２のレジスタの値からのオフセットとの組を基にローカル変数を識別するための番号（ローカル変数番号）を作成するステップと（図８Ｂ）、
上記作成されたローカル変数番号に基づいて、上記各レジスタの値が退避されるスタック領域内へのメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該メモリアクセスを当該割り当てられたローカル変数アクセスに置換するステップと（図７Ａ、ステップ７０７）
を含む。ステップ（Ａ）及び（Ｂ）でバイナリコードの最適化を終了する場合、当該最適化は、図６Ａ〜図６Ｃに示す第３の実施態様である。そして、コンピュータ（図１、１０１）は、上記置換されたローカル変数をレジスタ割り当ての対象とし、結果的に上記置換されたローカル変数にレジスタアドレスが割り当てられる。
【００２４】
本発明の１つの実施態様において、コンピュータ（図１、１０１）はまた、任意的に、（Ｃ）スタックポインターがエスケープしていた場合に、当該エスケープしたスタックポインターをベースアドレスとするメモリアクセスのうち、当該エスケープを引き起こした命令（すなわち、エスケープした命令）に付与されたcall番号と、当該call番号の祖先のcall番号（当該祖先のcall番号は上記親子関係情報から特定される）とに属しているメモリアクセスのローカル変数アクセスへの置換を禁止し（図７Ａ、ステップ７５３）、一方、残りの禁止しなかったメモリアクセスをコンパイラ内のローカル変数アクセスに置換するステップ（図７Ｄ、ステップ７０９）をさらに実行してもよい。ステップ（Ａ）〜（Ｃ）でバイナリコードの最適化を終了する場合、当該最適化は、図７Ａ〜図７Ｅに示す第４の実施態様である。そして、コンピュータ（図１、１０１）は、上記置換されたローカル変数をレジスタ割り当ての対象とし、結果的に上記置換されたローカル変数にレジスタアドレスが割り当てられる。
【００２５】
本発明の１つの実施態様において、上記ステップ（Ｃ）の禁止しなかったメモリアクセスをローカル変数アクセスに置換するステップが、
上記バイナリコード内においてスタックポインターとしてのレジスタ（第１のレジスタ）を見つけて、当該スタックポインターを他のレジスタ（第２のレジスタ）に保存するステップと（図７Ａ、ステップ７０４）、
上記バイナリコード内において、第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該メモリアクセスについて、上記第２のレジスタの値からのオフセットを計算するステップと（図７Ａ、ステップ７０５及び７０６）、
上記各メモリアクセスについて、上記call番号と上記第２のレジスタの値からのオフセットの組を基にローカル変数を識別するための番号（ローカル変数番号）を作成するステップと（図８Ｂ）、
上記作成されたローカル変数番号に基づいて、上記禁止しなかったメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該禁止しなかったメモリアクセスを当該割り当てられたローカル変数アクセスに置換するステップと（図７Ａ、ステップ７０９）
を含む。
【００２６】
本発明の１つの実施態様において、上記スタックポインターは、下記の１つ又はそれらの組み合わせである場合にエスケープしている；
（１）スタックポインターの値がメモリ内に書き込まれていること、
（２）インラインされないコール命令があること、及び
（３）例外を起こしうる命令があること。
【００２７】
本発明の１つの実施態様において、上記他の実施態様の方法は、コンピュータ（図１、１０１）が、上記バイトコード内に含まれるコール命令のインラインしたメソッドの入口部について、当該入口部の外側と内側とで同じオフセットを有するメモリアクセスがある場合にローカル変数のコピーを当該入口部に生成するステップ（図７Ｅ、ステップ７６３、７６４及び７６６）をさらに実行することを含んでもよい。また、上記他の実施態様の方法は、コンピュータ（図１、１０１）が、上記バイトコード内に含まれるコール命令のインラインしたメソッドの出口部について、当該出口部の外側と内側とで同じオフセットを有するメモリアクセスがある場合にローカル変数のコピーを当該出口部に生成するステップ（図７Ｅ、ステップ７６８、７６９及び７７１）をさらに実行することを含んでもよい。
【００２８】
本発明の１つの実施態様において、上記他の実施態様の方法は、コンピュータ（図１、１０１）が、スタックポインターがエスケープしていなく、且つスタックポインターを使ったメモリアクセスが全てなくなったことに応じて、スタックポインターの値を増減させる命令を削除するステップ（図７Ａ、ステップ７１１）をさらに実行することを含んでもよい。
【００２９】
本発明の１つの実施態様の、バイナリコードを最適化するコンピュータ（図１、１０１）において、当該コンピュータは、ＣＰＵ（図１、１０２）とメイン・メモリ（図１、１０３）とを備えており、上記バイナリコードに含まれるメモリアクセスのうち、各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換する第１の置換部（図２、２０６）をさらに備えている。コンピュータ（図１、１０１）は、任意的に、スタックポインターがエスケープしていないことを条件に、当該エスケープしていないスタックポインターを介したメモリアクセスをローカル変数アクセスに置換する第３の置換部（図２、２０６）をさらに備えている。
【００３０】
本発明の１つの実施態様において、第１の置換部（図２、２０６）は、
上記バイナリコード内においてスタックポインターとしてのレジスタ（第１のレジスタ）を見つけて、当該スタックポインターを他のレジスタ（第２のレジスタ）に保存し、
上記バイナリコード内において、上記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該見つけたメモリアクセスについて、上記第２のレジスタの値からのオフセットを計算し、
上記計算されたオフセットのうち、オフセットが同じであるメモリアクセスの集合を取得し、
上記取得した集合のメモリアクセスによりアクセスされるスタック領域がエイリアスされない領域であるかどうかを、上記取得した集合内の各メモリアクセスによりアクセスされる領域が前記各レジスタの値が退避されるスタック領域内への前記メモリアクセスのオフセット値域に入っているか否かによって判断する。
【００３１】
本発明の１つの実施態様において、上記スタックポインターは下記の１つ又はそれらの組み合わせである場合にエスケープする：
（１）スタックポインターの値がメモリ内に書き込まれていること、
（２）インラインされないcall命令があること、及び
（３）例外を起こしうる命令があること。
第３の置換部（図２、２０６）は、エスケープするスタックポインターをリストに格納する。
第３の置換部（図２、２０６）はまた、上記スタックポインターがエスケープしていないことを上記リストが空集合であることによって判断する。
【００３２】
本発明の他の実施態様の、バイナリコードを最適化するコンピュータ（図１、１０１）は、
上記バイナリコード内に含まれるコール（call）命令で呼ばれるコードをインラインすることに応じて、上記各コール命令及びインラインされたコードにcall番号を付与するcall番号付与部（図２、２０５）と、
各レジスタの値が退避されるスタック領域内へのメモリアクセスを、ローカル変数アクセスに置換する第１の置換部（図２、２０６）と
を備えていてもよい。call番号付与部（図２、２０５）は、当該call番号について、呼ぶ方のコール命令のcall番号を親とし、呼ばれる方のコール命令のcall番号を子とする親子関係情報をさらに作成する。
コンピュータ（図１、１０１）はまた、スタックポインターがエスケープしていた場合に、当該エスケープしたスタックポインターをベースアドレスとするメモリアクセスのうち、当該エスケープを引き起こした命令に付与されたcall番号と、当該call番号の祖先のcall番号とに属しているメモリアクセスのローカル変数アクセスへの置換を禁止し、一方、残りの禁止しなかったメモリアクセスをローカル変数アクセスに置換する第２の置換部（図２、２０６）をさらに備えていてもよい。上記祖先のcall番号は、上記親子関係情報から特定される。
【００３３】
本発明の１つの実施態様において、上記call番号付与部（図２、２０５）をさらに備えており、第１の置換部（図２、２０６）が、
上記バイナリコード内においてスタックポインターとしてのレジスタ（第１のレジスタ）を見つけて、当該スタックポインターを他のレジスタ（第２のレジスタ）に保存し、
上記バイナリコード内において、上記第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該見つけたメモリアクセスについて、上記第２のレジスタの値からのオフセットを計算し、
上記各メモリアクセスについて、上記call番号と上記第２のレジスタの値からのオフセットとの組を基にローカル変数を識別するための番号（ローカル変数番号）を作成し、
上記作成されたローカル変数番号に基づいて、上記各レジスタの値が退避されるスタック領域内へのメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該メモリアクセスを当該割り当てられたローカル変数アクセスに置換する。
【００３４】
本発明の１つの実施態様において、第２の置換部（図２、２０６）が、
上記バイナリコード内においてスタックポインターとしてのレジスタ（第１のレジスタ）を見つけて他のレジスタ（第２のレジスタ）に保存し、
上記バイナリコード内において、第１のレジスタをベースレジスタとして使用しているメモリアクセスを見つけ、当該メモリアクセスについて、上記第２のレジスタの値からのオフセットを計算し、
上記各メモリアクセスについて、上記call番号と上記第２のレジスタの値からのオフセットの組を基にローカル変数を識別するための番号（ローカル変数番号）を作成し、
上記作成されたローカル変数番号に基づいて、上記禁止しなかったメモリアクセスのローカル変数アクセスへの割り当てを決めて、当該禁止しなかったメモリアクセスを当該割り当てられたローカル変数アクセスに置換する。
【００３５】
本発明の１つの実施態様において、上記スタックポインターは下記の１つ又はそれらの組み合わせである場合にエスケープしている：
（１）スタックポインターの値がメモリ内に書き込まれていること、
（２）インラインされないcall命令があること、及び
（３）例外を起こしうる命令があること。
【００３６】
本発明の１つの実施態様において、コンピュータ（図１、１０１）は、上記バイトコード内に含まれるコール命令のインラインしたメソッドの入口部又は出口部について、当該入口部又は出口部の外側と内側とで同じオフセットを有するメモリアクセスがある場合にローカル変数のコピーを上記入口部又は上記出口部にそれぞれ生成する生成部をさらに備えていてもよい。
【００３７】
本発明の１つの実施態様において、コンピュータ（図１、１０１）は、スタックポインターがエスケープしていなく、且つスタックポインターを使ったメモリアクセスが全てなくなったことに応じて、スタックポインターの値を増減させる命令を削除する削除部をさらに備えていてもよい。
【００３８】
以下では、図面に従って、本発明の第１〜第４の実施形態をさらに説明する。また、以下の図を通して、特に断らない限り、同一の符号は、同一の対象を指す。
【００３９】
図１は、本発明の実施形態におけるコンピュータ・ハードウェアの基本的なブロック図を示す。
コンピュータ（１０１）は、ＣＰＵ（１０２）とメイン・メモリ（１０３）とを備えており、これらはバス（１０４）に接続されている。ＣＰＵ（１０２）は好ましくは、３２ビット又は６４ビットのアーキテクチャに基づくものであり、例えば、インテル社のＣｏｒｅ  ｉ（商標）シリーズ、Ｃｏｒｅ  ２（商標）シリーズ、Ａｔｏｍ（商標）シリーズ、Ｘｅｏｎ（商標）シリーズ、Ｐｅｎｔｉｕｍ（登録商標）シリーズ、Ｃｅｌｅｒｏｎ（登録商標）シリーズ、ＡＭＤ社のＰｈｅｎｏｍ（商標）シリーズ、Ａｔｈｌｏｎ（商標）シリーズ、Ｔｕｒｉｏｎ（商標）シリーズ又はＳｅｍｐｒｏｎ（商標）が使用されうる。バス（１０４）には、ディスプレイ・コントローラ（１０５）を介して、ディスプレイ（１０６）、例えば液晶ディスプレイ（ＬＣＤ）が接続されうる。ディスプレイ（１０６）は、コンピュータの管理のために、通信回線を介してネットワークに接続されたコンピュータについての情報と、そのコンピュータ上で動作中のソフトウェアについての情報を、適当なグラフィック・インタフェースで表示するために使用される。バス（１０４）にはまた、ＳＡＴＡ又はＩＤＥコントローラ（１０７）を介して、ディスク（１０８）、例えばハードディスク又はシリコン・ディスクと、ドライブ（１０９）、例えばＣＤ、ＤＶＤ又はＢＤドライブとが接続されうる。バス（１０４）にはさらに、キーボード・マウスコントローラ（１１０）又はＵＳＢバス（図示せず）を介して、キーボード（１１１）及びマウス（１１２）が接続されうる。
【００４０】
ディスク（１０８）には、オペレーティング・システム、Ｊ２ＥＥなどのＪａｖａ（登録商標）処理環境、Ｊａｖａ（登録商標）アプリケーション、Ｊａｖａ（登録商標）仮想マシン（ＶＭ）、Ｊａｖａ（登録商標）ＪＩＴコンパイラを提供するプログラム、その他のプログラム、及びデータが、メイン・メモリにロード可能に記憶されている。
ドライブ（１０９）は、必要に応じて、ＣＤ−ＲＯＭ、ＤＶＤ−ＲＯＭ又はＢＤからプログラムをディスク（１０８）にインストールするために使用される。
【００４１】
通信インタフェース（１１４）は、例えばイーサネット（登録商標）・プロトコルに従う。通信インタフェース（１１４）は、通信コントローラ（１１３）を介してバス（１０４）に接続され、コンピュータ（１０１）を通信回線（１１５）に物理的に接続する役割を担い、コンピュータ（１０１）のオペレーティング・システムの通信機能のＴＣＰ／ＩＰ通信プロトコルに対して、ネットワーク・インタフェース層を提供する。なお、通信回線は、有線ＬＡＮ環境、或いは例えばＩＥＥＥ８０２．１１ａ／ｂ／ｇ／ｎなどの無線ＬＡＮ接続規格に基づく無線ＬＡＮ環境であってもよい。
【００４２】
図２は、本発明の実施形態における、コンパイラ（２０１）の機能ブロック図を示す。
コンパイラ（２０１）は、外部からバイナリコード（２１１）を受け取り、バイナリコード（２１１）をコンピュータにより実行可能な実行プログラム（２１４）に変換する。バイナリコード（２１１）から実行プログラム（２１４）への変換において、コンパイラ（２０１）は、コンピュータ資源を有効に活用するために、最適化を行う。最適化によって、実行プログラムの実行速度を高速化したり、実行プログラムのサイズを低減させたりすることが可能である。
【００４３】
コンパイラ（２０１）は、フロントエンド処理部（２０２）、最適化処理部（２０３），及びコード生成部（２０４）を備えている。フロントエンド処理部（２０２）は外部からバイナリコード（２１１）を受信すると、当該受信したバイナリコード（２１１）を最適化処理に適した中間コード（２１２）に変換する。そして、フロントエンド処理部（２０２）は、中間コード（２１２）を最適化処理部（２０３）に送信する。最適化処理部（２０３）は、中間コード（２１２）に対して、各種の最適化を行う。最適化処理部（２０３）は、中間コード（２１２）を最適化した最適化済プログラム（２１３）をコード生成部（２０４）に送信する。コード生成部（２０４）は、最適化済プログラム（２１３）を、コンピュータ及びオペレーティング・システムにより実行可能な実行プログラム（２１４）に変換し、外部に出力する。
【００４４】
本実施形態において、バイナリコード（２１１）は最適化対象コードであり、例えば、Ｊａｖａ（登録商標）のソースコードである。バイナリコード（２１１）は例えば、次のような性質を有していてもよい。
−  アプリケーション・コード（アプリケーション・エミュレーション）
−  当該バイナリコードを呼ぶコードの性質として、次の２つを有する：
・スタックの頂上（Top of stack）を超えたアクセスを行わない、
・スタックポインターレジスタには、スタックポインター以外の値を入れない、
【００４５】
本実施形態において、中間コード（２１２）は例えば、バイトコード、又はＲＴＬ（Register Transfer Language）といった中間言語（中間表現ともいう）によるコードである。バイトコードは例えば、Ｊａｖａ（登録商標）のソースコードに所定の変換を行ったＪａｖａ（登録商標）バイトコード、.NET Frameworkである。ＲＴＬは、ＧＮＵコンパイラコレクションが使用する中間言語である。最適化対象コードは、中間言語により記述されたプログラムの全体であってもよいし、又は当該プログラムで記述されたプログラムの一部であってもよい。当該プログラムの一部とは例えば、特定の処理のみを行うモジュール又はオブジェクトでありうる。
【００４６】
最適化処理部（２０３）は、置換部（２０６）を備えている。最適化処理部（２０３）はまた、call番号付与部（２０５）をさらに備えていてもよい。call番号付与部（２０５）は、本発明の第３の実施態様及び第３の実施態様において使用され、任意の構成である。最適化処理部（２０３）はまた、生成部をさらに備えていてもよい（図示せず）。最適化処理部（２０３）はまた、削除部をさらに備えていてもよい（図示せず）。
【００４７】
call番号付与部（２０５）は、バイナリコード内に含まれるcall命令で呼ばれるコードをインライン展開することに応じて、各call命令にcall番号を付与する。また、call番号付与部（２０５）は、call番号の親子関係情報を作成する。作成された親子関係情報は例えば、メモリ（１０３）又は記憶装置（１０８）に格納されうる。
【００４８】
置換部（２０６）は、最適化処理部（２０３）がcall番号付与部（２０５）を備えていない場合、メモリアクセスのうち、各レジスタの値が退避されるスタック領域内へのメモリアクセスをローカル変数アクセスに置換すること、及び任意的に、スタックポインターがエスケープしていないことを条件に、当該エスケープしていないスタックポインターを介したメモリアクセスをローカル変数アクセスに置換することを行う。なお、置換部（２０６）は、前者の置換を行う第１の置換部と、後者の置換を行う第３の置換部とにそれぞれ分けられていてもよい。
置換部（２０６）はまた、最適化処理部（２０３）がcall番号付与部（２０５）を備えている場合、各レジスタの値が退避されるスタック領域内へのメモリアクセスを、ローカル変数アクセスに置換すること、及び任意的に、スタックポインターがエスケープしていた場合に、当該エスケープしたスタックポインターをベースアドレスとするメモリアクセスのうち、当該エスケープを引き起こした命令に付与されたcall番号と、当該call番号の祖先のcall番号とに属しているメモリアクセスのローカル変数アクセスへの置換を禁止し、一方、残りの禁止しなかったメモリアクセスをローカル変数アクセスに置換する。なお、置換部（２０６）は、前者の置換を行う第１の置換部と、後者の置換を行う第２の置換部とに分けられていてもよい。
置換部（２０６）は、第１の置換部、第２の置換部、及び第３の置換部の全てをそなえていてもよい。そして、ユーザによってバイナリコードの最適化がcall番号を使用して行われないことが選択された場合に、第１の置換部と第３の置換部とが使用されるようにし、一方、ユーザによってバイナリコードの最適化がcall番号を使用して行われないことが選択された場合に、第１の置換部と第２の置換部とが使用されるようにしてもよい。
【００４９】
生成部は、バイトコード内に含まれるコール命令のインラインしたメソッドの入口部又は出口部について、オフセットが重なる場合にローカル変数のコピーを上記入口部又は上記出口部にそれぞれ生成する。
【００５０】
削除部は、スタックポインターがエスケープしていなく、且つスタックポインターを使ったメモリアクセスが全てなくなった場合に、スタックポインターの値を増減させる命令を削除する。
【００５１】
図３は、本発明が組み込まれうる１つの実施態様であるＪａｖａ（登録商標）コンパイラを示す。
Ｊａｖａ（登録商標）で書かれたＪａｖａアプリケーション（３０１）は、バイトコード（３１１）と呼ばれる中間言語に変換される。従って、Ｊａｖａアプリケーション（３０１）は、Ｊａｖａ（登録商標）  ＶＭ（３０２）を実装する環境さえ用意すればどのような計算機上でも実行できる。一方、バイトコード（３１１）を実行する計算機上では、インタープリットするためにオーバーヘッドが問題になる。そこで、ジャスト・イン・タイム（Just-In-Time、ＪＩＴ）コンパイラ（３０３）は、バイトコード（３１１）を実行時に動的に機械語に変換（コンパイル）してネイティブコード（３１２）に変換するために高速実行を可能にする。
【００５２】
図４Ａは、本発明の第１の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
ステップ４０１では、フロントエンド処理部（２０２）は、バイナリコード（２１１）を中間コード（２１２）に変換する。下記の最適化処理において、基本的にこの中間コード（２１２）に対して処理が行われる。但し、バイナリコード（２１１）と中間コード（２１２）との間には対応関係がある。従って、最適化処理において必要なときには、バイナリコード（２１１）を参照することが可能である。
ステップ４０２では、最適化処理部（２０３）は、中間コード（２１２）からＵＤ／ＤＵ連鎖（Use-Definition Chain／Definition-Use Chain）を作成する。ＵＤ連鎖とは、参照定義連鎖を意味し、変数の参照について、そこで参照される値がどの命令で定義されるか又は定義される可能性があるかを命令の集合として表現したものである。ＤＵ連鎖とは定義参照連鎖を意味し、各変数の定義について、そこで定義された値がどの命令で参照される又は参照される可能性があるかを命令の集合として表現したものである。ＵＤ連鎖により得られた結果は、ステップ４１３（図４Ｂ）及びステップ４３３（図４Ｃ）において使用される。ＤＵ連鎖により得られた結果は、ステップ４０４において使用される。
ステップ４０３では、最適化処理部（２０３）は、バイナリコード（２１１）のスタックポインターの値が加減命令（例えば、足し算命令）によって変更される場合が有るために、当該変更前のスタックポインターの値（以下、元のSP値という）を、別のレジスタ（ａ１）内に保存する。すなわち、元のSP値を別のレジスタ（ａ１）にバックアップする。元のSP値を別のレジスタ（ａ１）にバックアップする目的は、各メモリアクセスについて、元のSP値からの相対オフセットを求める場合に、当該元のSP値を使用するためである。別のレジスタ（ａ１）は例えば、ＣＰＵのレジスタ内又はメイン・メモリ（１０３）内に設けられる。なお、ステップ４０３では、バイナリコード（２１１）を使用している。これは、上記したように、バイナリコード（２１１）と中間コード（２１２）との間には対応関係があるので、中間コード（２１２）からバイナリコード（２１１）の情報を見ることが出来るからである。
ステップ４０４では、最適化処理部（２０３）は、ＤＵ連鎖を使用し、スタックポインターの全ての使用位置を解析する。当該解析のフローチャートは、図４Ｂ又は図４Ｃのサブルーチンにおいて別途示されている。SPの定義defとoffsetはサブルーチンanalyze_usesの引数であって、呼び出し側が各値を設定する。
ステップ４０５では、最適化処理部（２０３）は、図４Ｂ又は図４Ｃにおいて作成されたメモリアクセスのリスト（ｃ１）に登録された個々のストア命令に対応するロード命令に、図４Ｂ又は図４Ｃの各ストア命令のオフセット情報（ｂ１）を伝播する。当該伝播のフローチャートは、図４Ｄのサブルーチンにおいて別途示されている。図４Ｄのステップ４５５において、各ストア命令のオフセット情報（ｂ１）が実際に伝播されている。伝播は、load結果が格納されるレジスタをスタックポインターであると扱い、その際のストア命令に書き込まれたスタックポインターのオフセット情報をストア命令時のオフセット情報からコピーすることである。ここで、オフセット情報は例えば、オフセット値、対応するメモリアクセス（複数）、ローカル変数の３種類の情報を有する。
ステップ４０６では、オフセット情報（ｂ１）を基に、実際にはエイリアスされることがないと分かっている（知られている）領域、例えばレジスタ・セーブ・エリア（レジスタ退避領域ともいう）について、各メモリアクセスをコンパイラ内のローカル変数アクセスに置き換える。エイリアスでない領域であるかどうかは、オフセット情報（ｂ１）内の各メモリアクセスによりアクセスされる領域が前記各レジスタの値が退避されるスタック領域内への前記メモリアクセスのオフセット値域に入っているか否かによって判断される。上記アクセスされる領域がオフセットと値域に入っている場合、メモリアクセスによりアクセスされるスタック領域はエイリアスされない領域である。一方、上記アクセスされる領域がオフセットと値域に入っていない場合、メモリアクセスによりアクセスされるスタック領域はエイリアスされる領域である。上記ローカル変数は、図８Ａに従い決められる。そして、置換されたローカル変数アクセスがレジスタアクセスに置き換えられる。実際にはエイリアスされることがないと分かっている（知られている）同じメモリアクセスは、各レジスタの値が退避されるスタック領域内へのメモリアクセスでもある。
本発明の第１の実施態様による最適化では、レジスタ・セーブ・エリアのみを最適化し、それ以外のメモリアクセスについては最適化を行っていない。
【００５３】
図４Ｂは、図４Ａのステップ４０４のサブルーチンanalyze_uses(def,offset)の第１の実施態様を示す。
SPの定義defは、基本的には、プログラムの先頭にあるスタックポインターの値である。また、SPの定義defは、プログラム中に明示的に現れてない場合、メソッドの入口部にスタックポインターのdefがあるとして処理を行う。また、SPの定義defは、スタックポインターと見なせる特定のパターンである。
ステップ４１１は、サブルーチンanalyze_uses(def, offset)の開始である。defは、スタックポインターの定義defである。
ステップ４１２では、最適化処理部（２０３）は、defの全てのuse（レジスタ）について、ステップ４１３〜４２３の処理を繰り返して行う。
ステップ４１３では、最適化処理部（２０３）は、ＵＤ連鎖を使用し、useのところからdefを見に行って、useの定義がdefのみかどうかを判定する。useの定義がdefのみである場合、当該処理はステップ４１４に進む。一方、useの定義がdefのみでない場合、当該処理はステップ４１５に進む。
ステップ４１４では、最適化処理部（２０３）は、useが定数Cとの足し算命令のソースオペランドであるかどうかを判定する。なお、定数を引く命令はあらかじめ足し算に変換しているものとする。useが定数Cとの足し算命令のソースオペランドでない場合、当該処理はステップ４１６に進む。一方、useが定数Cとの足し算命令のソースオペランドである場合、当該処理はステップ４１７に進む。
ステップ４１５では、最適化処理部（２０３）は、useの定義がdefのみでないので、最適化を中止する。従って、コンパイル処理は、最適化処理部（２０３）での最適化処理を中止し、次の処理（図２、２０４）へ進む。
ステップ４１６では、最適化処理部（２０３）は、useがメモリアクセスへのベースレジスタかどうかを判定する。useがメモリアクセスへのベースレジスタでない場合、当該処理はステップ４１８に進む。一方、useがメモリアクセスへのベースレジスタである場合、当該処理はステップ４１９に進む。
ステップ４１７では、最適化処理部（２０３）は、足し算の結果が格納されるレジスタと、ステップ４１１でパラメータとして渡されてきたオフセットに定数Ｃを加えた値とをパラメータとして、ステップ４１１への再帰呼び出しを行う。当該処理は、最適化呼び出しから戻ってきたら、ステップ４２３に戻る。
ステップ４１８では、最適化処理部（２０３）は、useがストア命令で格納される値であるかどうかを判定する。useがストア命令で格納される値でない場合、当該処理はステップ４２１に進む。一方、useがストア命令で格納される値である場合、当該処理はステップ４２２に進む。
ステップ４１９では、最適化処理部（２０３）は、ステップ４１６で見つけたメモリアクセスである中間コード上の命令に書かれているベースレジスタとオフセットを、別レジスタ（ａ１）と当該別レジスタ（ａ１）からのオフセットにそれぞれ変更する。
ステップ４２０では、別レジスタ（ａ１）からのオフセット値を基に、ステップ４１６で見つけたメモリアクセス、及びそのオフセット値をオフセット情報（ｂ１）に登録する。具体的には、オフセット値を検索し、オフセット集合内（ａ１）に同じオフセット値がある場合、同じオフセットを有するメモリアクセスを１つの要素とみる。それによって、オフセットが同じであるメモリアクセスの集合が得られる。一方、オフセット値が異なるメモリアクセスを、別の要素とみる。それによって、上記と異なるオフセット値を有し、当該異なるオフセットが同じであるメモリアクセスの集合が得られる。上記１つの要素又は上記別の要素についてのオフセット情報（ｂ１）は例えば、オフセット値、対応するメモリアクセス（複数）、ローカル変数の３種類の情報を有する。なお、ローカル変数は、メモリアクセスのローカル変数への置換処理において、図８Ａに示すフローチャートに従い生成される。オフセット情報（ｂ１）は例えば、メイン・メモリ（１０３）内に格納される。そして、当該処理は、ステップ４２３に進む。
ステップ４２１では、最適化処理部（２０３）は、useがコピー命令のソースオペランドであるかどうかを判定する。useがコピー命令のソースオペランドでない場合、当該処理はステップ４２３に進む。一方、useがコピー命令のソースオペランドである場合、当該処理はステップ４２４に進む。
ステップ４２２では、最適化処理部（２０３）は、ステップ４１８で見つけたストア命令であるメモリアクセスをリスト（ｃ１）に登録する。リスト（ｃ１）は例えば、メイン・メモリ（１０３）内に格納される。
ステップ４２３では、最適化処理部（２０３）は、ステップ４１２〜４２２までのステップを繰り返すために、ステップ４１２に戻る。
ステップ４２４では、最適化処理部（２０３）は、コピー先のレジスタと、ステップ４１１でパラメータとして渡されてきたオフセットとをパラメータとして、再帰呼び出しを行う。当該処理は、最適化呼び出しから戻ってきたら、ステップ４２３に戻る。
ステップ４２５は、サブルーチンanalyze_uses(def, offset)の終了である。
【００５４】
図４Ｃは、図４Ａのステップ４０４のサブルーチンanalyze_uses(def, offset)の第２の実施態様を示す。
図４Ｃは、ステップ４４３及び４４６が追加されている以外は、図４Ｂと同じである。すなわち、図４Ｃのステップ４３１〜４４２、４４４、４４５及び４４７は、図４Ｂのステップ４１１〜４２２、４２４、４２３及び４２５にそれぞれ対応する。従って、以下では、図４Ｃで追加されたステップ４４３及び４４６のみを説明する。
ステップ４４１では、最適化処理部（２０３）は、useがコピー命令のソースオペランドであるかどうかを判定する。useがコピー命令のソースオペランドでない場合、当該処理はステップ４４３に進む。一方、useがコピー命令のソースオペランドである場合、当該処理はステップ４４４に進む。
ステップ４４３では、最適化処理部（２０３）は、useがエスケープの条件であるかどうかを判定する。useがエスケープの条件でない場合、当該処理はステップ４４５に進む。一方、useがエスケープの条件である場合、当該処理はステップ４４６に進む。
ステップ４４６では、エスケープ条件であるuse場所の命令をエスケープリスト（ｄ１）に登録する。すなわち、登録された場所がエスケープする場所である。エスケープリスト（ｄ１）は例えば、メイン・メモリ（１０３）内に格納される。または、エスケープ条件であるuse又はuse場所の命令にフラグを付してもよい。
【００５５】
図４Ｄは、図４Ａのステップ４０５のサブルーチンpropagate()の実施態様を示す。
ステップ４５１は、サブルーチンpropagate()の開始である。
ステップ４５２では、最適化処理部（２０３）は、図４Ｂのステップ４２２のメモリアクセスのリスト（ｃ１）又は図４Ｃのステップ４４２のメモリアクセスのリスト（ｃ１）の個々のストア命令（以下、storeともいう）について、ステップ４５３〜４５８の処理を繰り返し行う。
ステップ４５３では、最適化処理部（２０３）は、storeに対応するロード命令について、ステップ４５４から４５７の処理を繰り返し行う。
ステップ４５４では、最適化処理部（２０３）は、ロード命令に対応する書き込みがstoreのみかを判定する。ロード命令に対応する書き込みがstoreのみである場合、ステップ４５５に進む。一方、ロード命令に対応する書き込みがstoreのみでない場合、ステップ４５６に進む。
ステップ４５５では、最適化処理部（２０３）は、各ストア命令のオフセット情報（ｂ１）を伝播する。最適化処理部（２０３）は、は、load結果が格納されるレジスタをスタックポインターであると扱い、その際のストア命令に書き込まれたスタックポインターのオフセット情報をストア命令時のオフセット情報からコピーすることで伝播を行う。すなわち、最適化処理部（２０３）は、load結果が格納されるレジスタと、storeに書き込まれたスタックポインターのオフセットとをパラメータとして渡し（伝播である）、ステップ４１１（図４Ｂ）又はステップ４３１（図４Ｃ）へのサブルーチンコールを行う。当該処理は、最適化呼び出しから戻ってきたら、ステップ４５７に戻る。
ステップ４５６では、最適化処理部（２０３）は、最適化を中止する。従って、コンパイル処理は、最適化処理部（２０３）での最適化処理を中止し、次の処理（図２、２０４）へ進む。
ステップ４５７では、最適化処理部（２０３）は、ステップ４５４〜４５５までのステップを繰り返すために、ステップ４５３に戻る。
ステップ４５８では、最適化処理部（２０３）は、ステップ４５３〜４５７までのステップを繰り返すために、ステップ４５２に戻る。
ステップ４５９は、サブルーチンpropagate()の終了である。
【００５６】
図５Ａは、本発明の第２の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
図５Ａは、ステップ５０７〜５０８が追加されている以外は、図４Ａと同じである。すなわち、図４Ａのステップ４０１〜４０６は、図５Ａのステップ５０１〜５０６にそれぞれ対応する。従って、以下では、図５Ａで追加されたステップ５０７及び５０８のみを説明する。
ステップ５０７では、最適化処理部（２０３）は、ステップ５０５の後で、スタックポインターがエスケープしていないことを条件に、それ以外のスタックポインターを使ったメモリアクセスをローカル変数アクセスに置き換える。
スタックポインターがエスケープしていないことは、エスケープするスタックポインターを格納したリストが空集合であることによって判定される。スタックポインターがエスケープすることは、（１）スタックポインターの値がメモリ内に書き込まれていること、（２）インラインされないcall命令があること、及び（３）例外を起こしうる命令があること１つ又はそれらの組み合わせである場合である。
ステップ５０８では、最適化処理部（２０３）は、ステップ５０５の後で、且つスタックポインターを使ったメモリアクセスが全てなくなっているならば、スタックポインターの値を増減させる命令を削除する。スタックポインターの値を増減させる命令は例えば、下記図５Ｂのステップ５１４で示す定数Ｃとの足し算命令である。
【００５７】
図５Ｂは、図５Ａのステップ５０４のサブルーチンanalyze_uses(def,offset)の第１の実施態様を示す。
図５Ｂのステップ５１１〜５２５の各ステップは、図４Ｂのステップ４１１〜４２５の各ステップにそれぞれ対応する。従って、本明細書では、図５Ｂのステップ５１１〜５２５の各ステップの説明を省略する。
【００５８】
図５Ｃは、図５Ａのステップ５０４のサブルーチンanalyze_uses(def,offset)の第２の実施態様を示す。
図５Ｃのステップ５３１〜５４７の各ステップは、図４Ｃのステップ４３１〜４４７の各ステップにそれぞれ対応する。従って、本明細書では、図５Ｃのステップ５３１〜５４７の各ステップの説明を省略する。
【００５９】
図５Ｄは、図５Ａのステップ５０５のサブルーチンpropagate()の実施態様を示す。
図５Ｄのステップ５５１〜５５９の各ステップは、図４Ｄのステップ４５１〜４５９の各ステップにそれぞれ対応する。従って、本明細書では、図５Ｄのステップ５５１〜５５９の各ステップの説明を省略する。
【００６０】
図６Ａは、本発明の第３の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
ステップ６０１では、フロントエンド処理部（２０２）は、バイナリコード（２１１）を中間コード（２１２）に変換する。
ステップ６０２では、最適化処理部（２０３）は、バイナリコード（２１１）内に含まれるcall命令で呼ばれるコード（コール命令先ともいう）をインラインする際に、インラインする各call命令及びインラインされたコードに、対応するcall番号を付与する。call番号は例えば、各call命令を一意に区別することができる番号である。call番号は例えば、call番号ごとに通し番号が付けられてもよい。また、最適化処理部（２０３）は、各call命令に付与されたcall番号の親子関係情報を作成する。親子関係情報は呼ぶ方のcall命令のcall番号を親とし、呼ばれる方のcall命令のcall番号を子とする情報であり、例えば、下記図９Ａの９０３に示されているような木構造のグラフで示されうる。また、各call命令に付与されるcall番号のルートとなるcall番号は、インラインをしなかった場合のコード列に付与される番号である。
ステップ６０３では、最適化処理部（２０３）は、中間コード（２１２）からＵＤ／ＤＵ連鎖を作成する。ＵＤ／ＤＵ連鎖については、図４Ａにおいて説明したとおりである。
ステップ６０４では、最適化処理部（２０３）は、バイナリコード（２１１）のスタックポインターの元の値（元のSP値）を、別のレジスタ（ａ３）内に保存する。すなわち、元のSP値を別のレジスタ（ａ３）にバックアップする。別のレジスタ（ａ３）は例えば、ＣＰＵのレジスタ内、又はメイン・メモリ（１０３）内に設けられる。
ステップ６０５では、最適化処理部（２０３）は、ＤＵ連鎖を使用し、スタックポインターの全ての使用位置を解析する。当該解析のフローチャートは、図６Ｂのサブルーチンにおいて別途示されている。
ステップ６０６では、最適化処理部（２０３）は、図６Ｂにおいて作成されたメモリアクセスのリスト（ｃ３）に登録された個々のストア命令に対応するロード命令に、図６Ｂのオフセット情報（ｂ３）を伝播する。当該伝播のフローチャートは、図６Ｃのサブルーチンにおいて別途示されている。
ステップ６０７では、オフセット情報（ｂ３）を基に、実際にはエイリアスされることがないと分かっている（知られている）同じ領域、例えばレジスタ・セーブ・エリア（レジスタ退避領域ともいう）について、各メモリアクセスをコンパイラ内のローカル変数アクセスに置き換える。詳細には、レジスタをスタックへの保存又は復帰を行うエリアをアクセスする各メモリアクセスについて、ローカル変数情報を基にローカル変数への割り当てを決め、当該ローカル変数アクセスに置き換える。当該ローカル変数は、図８Ａ又は図８Ｂに従い決められる。当該置換されたローカル変数アクセスがレジスタアクセスに置き換えられる。実際にはエイリアスされることがないと分かっている（知られている）同じメモリアクセスは、各レジスタの値が退避されるスタック領域内へのメモリアクセスでもある。
本発明の第３の実施態様による最適化では、バイナリコード内に含まれるメモリアクセスのうち、レジスタ・セーブ・エリアのみを最適化し、それ以外のメモリアクセスについては最適化を行わない。
本発明の第３の実施態様による最適化は、コンピュータ資源のパフォーマンス向上だけでなく、間接分岐のターゲット・アドレスを分析する上でも有用である。
【００６１】
図６Ｂは、図６Ａのステップ６０５のサブルーチンanalyze_uses(def,offset)の実施態様を示す。
図６Ｂのステップ６１１〜６２７の各ステップは、図４Ｃのステップ４３１〜４４７の各ステップ又は図５Ｃのステップ５３１〜５４７の各ステップにそれぞれ対応する。従って、本明細書では、図６Ｂのステップ６１１〜６２７の各ステップの説明を省略する。
【００６２】
図６Ｃは、図６Ａのステップ６０６のサブルーチンpropagate()の実施態様を示す。
図６Ｃのステップ６３１〜６３９の各ステップは、図４Ｄのステップ４５１〜４５９の各ステップ又は図５Ｄのステップ５５１〜５５９の各ステップにそれぞれ対応する。従って、本明細書では、図６Ｃのステップ６３１〜６３９の各ステップの説明を省略する。
【００６３】
図７Ａは、本発明の第４の実施態様である、バイナリコードを最適化するコンパイル方法のフローチャートを示す。
図７Ａは、ステップ７０７において「置換されたメモリアクセスを削除」すること及びステップ７０８〜７１１が追加されている以外は、図６Ａと同じである。すなわち、図６Ａのステップ６０１〜６０６は、図７Ａのステップ７０１〜７０６にそれぞれ対応する。従って、以下では、図７Ａで追加（又は変更）されたステップ７０７〜７１１のみを説明する。
ステップ７０７では、オフセット情報（ｂ４）を基に、実際にはエイリアスされることがないと分かっている（知られている）同じ領域、例えばレジスタ・セーブ・エリア（レジスタ退避領域ともいう）について、各メモリアクセスをコンパイラ内のローカル変数アクセスに置換する。詳細には、レジスタをスタックへの保存又は復帰を行うエリアをアクセスする各メモリアクセスについて、ローカル変数情報を基にローカル変数への割り当てを決め、当該ローカル変数アクセスに置換する。当該ローカル変数は、図８Ａ又は図８Ｂに従い決められる。当該置換されたローカル変数アクセスがレジスタアクセスに置換される。そして、（ｄ４）から置換されたメモリアクセスが削除される。置換されたメモリアクセスを削除する理由は、メモリアクセスがローカル変数に置き換えられることによって、エスケープした条件から外れるためである。
ステップ７０８では、最適化処理部（２０３）は、メモリアクセス置換判断を行う。当該置換判断のフローチャートは、図７Ｄのサブルーチンにおいて別途示されている。
ステップ７０９では、最適化処理部（２０３）は、ステップ７０８において置換禁止リスト(ｅ４)に記憶されているメモリアクセス以外のメモリアクセスをローカル変数アクセスに置換する。
ステップ７１０では、最適化処理部（２０３）は、call番号の切れ目（境目）にローカル変数のコピーを生成する。これは、スタックへのメモリアクセスのオフセットがアクセスする場所が同じだけれども、ローカル変数が違う場合があるために、値を切れ目で統一するためである。詳細には、call番号の切れ目（メソッドの入口部、メソッドの出口部）でオフセットが重なるものがあるならば、ローカル変数のコピーを当該切れ目に生成する。当該コピーの生成のフローチャートは、図７Ｅのサブルーチンにおいて別途示されている。ステップ７１０は、下記図８Ｂに示すcall番号とスタックポインターからのオフセットとの組（ローカル変数情報ともいう）を基にローカル変数への割り当てが決められた場合に実行されうる。下記図８Ａに示すオフセットのみを使用する場合、call番号に関わらず、同じメモリアクセスへは同じローカル変数が割り当てられるので、ステップ７１０を実行する必要はない。
ステップ７１１では、最適化処理部（２０３）は、ステップ７０６の後で、且つスタックポインターを使ったメモリアクセスが全てなくなっているならば、スタックポインターの値を増減させる命令を削除する。スタックポインターの値を増減させる命令は例えば、下記図７Ｂのステップ７２４で示す定数Ｃとの足し算命令である。ステップ７１１は、任意のステップであり、必ずしも最適化において実行する必要はない。
【００６４】
図７Ｂは、図７Ａのステップ７０５のサブルーチンanalyze_uses(def,offset)の実施態様を示す。
図７Ｂのステップ７２１〜７３７は、図４Ｃのステップ４３１〜４４７の各ステップ、図５Ｃのステップ５３１〜５４７の各ステップ、又は図６Ｂのステップ６１１〜６２７の各ステップにそれぞれ対応する。従って、本明細書では、図７Ｂのステップ７２１〜７３７の各ステップの説明を省略する。
【００６５】
図７Ｃは、図７Ａのステップ７０６のサブルーチンpropagate()の実施態様を示す。
図７Ｃのステップ７４１〜７４９の各ステップは、図４Ｄのステップ４５１〜４５９の各ステップ、図５Ｄのステップ５５１〜５５９の各ステップ、又は図６Ｃのステップ６３１〜６３９の各ステップにそれぞれ対応する。従って、本明細書では、図７Ｃのステップ７４１〜７４９の各ステップの説明を省略する。
【００６６】
図７Ｄは、図７Ａのステップ７０８のサブルーチンanalyze_accesses()の実施態様を示す。
ステップ７５１は、サブルーチンanalyze_accesses()の開始である。
ステップ７５２では、最適化処理部（２０３）は、図７Ｂのステップ７３６において登録されたメモリアクセスのリスト（ｄ４）中の個々の命令について、ステップ７５３の処理を繰り返し行う。
ステップ７５３では、最適化処理部（２０３）は、（ｄ４）中の命令、すなわち、エスケープしたスタックポインターの命令を含むcall番号と当該命令を含むcall番号の祖先のcall番号とに含まれるスタックポインターベースのメモリアクセスのローカル変数アクセスへの置換を禁止することを置換禁止リスト（ｅ４）に記憶する。または、（ｄ４）中の命令に、当該メモリアクセスへの置換を禁止することを識別するためのフラグをつけておいてもよい。置換禁止リスト（ｅ４）に登録された又は上記フラグを付けられたメモリアクセスは、ステップ７０９においてローカル変数アクセスに置き換えられない。祖先のcall番号は、親子関係情報を示す例えば図９Ａの木構造（９０３）を使用し、当該ツリーの上方にたどって行くことによって特定可能である。
なお、スタックポインターがエスケープしたスタックポインターの命令の場所よりも前では、call番号と当該命令を含むcall番号の祖先のcall番号とに含まれるスタックアクセスをレジスタに置き換えるが、最新の値はメモリにもストアするようなバリエーションもありうる。
ステップ７５４では、最適化処理部（２０３）は、（ｄ４）中の個々のエスケープ命令の全てについてステップ７５３を繰り返すために、ステップ７５２に戻る。
ステップ７５５は、サブルーチンanalyze_accesses()の終了である。
【００６７】
図７Ｅは、図７Ａのステップ７１０のサブルーチンgenerate_copy()の実施態様を示す。
ステップ７６１は、サブルーチンgenerate_copy()の開始である。
ステップ７６２〜７６６は、インラインしたメソッドの入口部（入口コードともいう）についてのループ処理である。ステップ７６７〜ステップ７７０は、インラインしたメソッドの出口部についてのループ処理である。
ステップ７６２では、最適化処理部（２０３）は、それぞれのインラインしたメソッドの入口部について、インラインしたcall番号をid（変数）に入れて、ステップ７６３〜ステップ７６５を実行する。idは、変数のコピーを生成する必要があるローカル変数を見つけるために、オフセット情報とともに使用される。
ステップ７６３では、最適化処理部（２０３）は、idに対応するメモリアクセスMA1について、idの祖先であり且つ境界の外側と内側とで同じオフセットであるところのメモリアクセスMA2（すなわち、オフセットが重なる）を検索する。すなわち、最適化処理部（２０３）は、同じオフセットにidの祖先がないかを検索し、そして最初に見つかったメモリアクセスをMA2とする。
ステップ７６４では、同じオフセットであるメモリアクセスMA2がない場合（すなわち、オフセットが重ならない場合）、当該処理はステップ７６５に進む。一方、同じオフセットであるメモリアクセスMA2がある場合（すなわち、オフセットが重なる場合）、当該処理はステップ７６６に進む。
ステップ７６５では、最適化処理部（２０３）は、idの全てについてステップ７６３〜７６４のステップを繰り返すために、ステップ７６２に戻る。インラインしたcall番号の全てについてステップ７６３〜７６４のステップが繰り返された場合は、当該処理はステップ７６７に進む。
ステップ７６６では、最適化処理部（２０３）は、MA2に対応するローカル変数からMA1に対応するローカル変数へのコピーを上記インラインしたメソッドの入口部に生成する。すなわち、最適化処理部（２０３）は、祖先側からコピーする。当該ローカル変数へのコピーの生成後、当該処理はステップ７６５に進む。
ステップ７６７では、最適化処理部（２０３）は、それぞれのインラインしたメソッドの出口部（出口コードともいう）について、インラインしたcall番号をid（変数）に入れて、ステップ７６８〜ステップ７７０を実行する。
ステップ７６８では、最適化処理部（２０３）は、idの親call番号（以降、parentという）に対応するメモリアクセスMA3について、id又は当該idの子孫であり且つ同じオフセットであるところのメモリアクセスMA4（すなわち、オフセットが重なる）を検索する。すなわち、最適化処理部（２０３）は、同じオフセットにidの子孫がないかを検索し、そして最初に見つかったメモリアクセスをMA4とする。
ステップ７６９では、同じオフセットであるメモリアクセスMA4がない場合（すなわち、オフセットが重ならない場合）、当該処理はステップ７７０に進む。一方、同じオフセットであるメモリアクセスMA4がある場合（すなわち、オフセットが重なる場合）、当該処理はステップ７７１に進む。
ステップ７７０では、最適化処理部（２０３）は、idの全てについてステップ７６８〜７６９のステップを繰り返すために、ステップ７６７に戻る。インラインしたcall番号の全てについてステップ７６８〜７６９のステップが繰り返された場合は、当該処理はステップ７７２に進む。
ステップ７７１では、最適化処理部（２０３）は、MA4に対応するローカル変数からMA3に対応するローカル変数へのコピーを上記インラインしたメソッドの出口部に生成する。すなわち、最適化処理部（２０３）は、子孫側からコピーする。当該ローカル変数へのコピーの生成後、当該処理はステップ７７０に進む。
ステップ７７２は、サブルーチンgenerate_copy()の終了である。
【００６８】
図８Ａは、本発明の第１〜第４の実施態様におけるローカル変数の割り当てのフローチャートを示す。
当該フローチャートにおいて、スタックへの各メモリアクセスについて、スタックポインターからのオフセットのみを基に、ローカル変数への割り当てが決められる。
ステップ８０１は、ローカル変数割り当てを開始する。
ステップ８０２では、最適化処理部（２０３）は、ステップ８０１の引数であるオフセットをオフセット情報集合(b1,b2,b3,b4)から検索する。オフセット情報集合は例えば、図４Ｂ及び図４Ｃのｂ１（４２０）、図５Ｂ及び図５Ｃのｂ２（５２０）、図６Ｂのｂ３（６２０）、図７Ｂのｂ４（７３０）である。
ステップ８０３では、最適化処理部（２０３）は、上記オフセットが上記オフセット集合内にあるかどうかを検査する。オフセットがない場合、当該処理はステップ８０４に進む。一方、オフセットがある場合、当該処理はステップ８０５に進む。
ステップ８０４では、最適化処理部（２０３）は、新たにローカル変数を作成し、その情報をオフセット情報集合のオフセット対応部分に格納する。最適化処理部（２０３）は、戻り値（ret）として、当該新たに作成されたローカル変数を取得する。
ステップ８０５では、最適化処理部（２０３）は、戻り値（ret）として、対応するローカル変数を取得する。ここで、「対応する」とは、オフセット情報の要素内のローカル変数に格納されている情報である。
ステップ８０６では、最適化処理部（２０３）は、ステップ８０４又はステップ８０５からの戻り値（ret）をローカル変数として割り当てる。
【００６９】
図８Ｂは、本発明の第３の実施態様（図６Ａ〜図６Ｃ）及び本発明の第４の実施態様（図７Ａ〜図７Ｅ）におけるローカル変数の割り当てのフローチャートを示す。
当該フローチャートにおいて、スタックへの各メモリアクセスについて、call番号とスタックポインターからのオフセットとの組（ローカル変数情報ともいう）を基に、ローカル変数への割り当てが決められる。
ステップ８１１は、ローカル変数割り当てを開始する。
ステップ８１２では、最適化処理部（２０３）は、call番号と上記オフセットとの組（ローカル変数情報）をオフセット情報集合から検索する。
ステップ８１３では、最適化処理部（２０３）は、検索された集合内に上記組（ローカル変数情報）があるかどうかを検査する。上記組（ローカル変数情報）がない場合、当該処理はステップ８１４に進む。一方、上記組（ローカル変数情報）がある場合、当該処理はステップ８１５に進む。
ステップ８１４では、最適化処理部（２０３）は、新たにローカル変数を作成し、その情報をオフセット情報集合のcall番号とオフセットとの組（ローカル変数情報）の対応部分に格納する。そして、最適化処理部（２０３）は、戻り値（ret）として、当該新たに作成されたローカル変数を取得する。
ステップ８１５では、最適化処理部（２０３）は、戻り値（ret）として、対応するローカル変数を取得する。
ステップ８１６では、最適化処理部（２０３）は、ステップ８１４又はステップ８１５からの戻り値（ret）をローカル変数として割り当てる。
【００７０】
図８Ｂのローカル変数の割り当ては、スタックポインターからのオフセットに加えて、call番号を使用している点で、図８Ａのローカル変数の割り当てと異なる。図８Ｂの割り当ては、以下の理由により図８Ａの割り当てに比べて最適化に対する長所を有する。図８Ａの割り当てではオフセットが同じであればcall番号にかかわらず、同じローカル変数が割り当てられる。一方、図８Ｂの割り当てではオフセットが同じであってもcall番号が変わると異なるローカル変数が割り当てられる。本発明の実施態様において、スタックポインターレジスタがエスケープしているかどうかによって、当該エスケープに関わる最適化に影響が及ぼされる。従って、異なるcall番号であるならば、その中のメモリアクセスに別々のローカル変数を割り当てた方が、実行速度（性能）が良くなる。例えば、図８Ｂの処理において、call番号が違うために、同じオフセットのメモリアクセスが変数Ａと変数Ｂとに分かれたとする。変数Ａに関連付けられたメモリアクセスが１０個あり、変数Ｂに関連付けられたメモリアクセスが２０個あったとする。変数Ａがエスケープしていた場合、影響するメモリアクセスは１０個である。すなわち、変数Ａに関連付けられたメモリアクセスの数と同じである。一方、図８Ａの処理では変数Ａと変数Ｂとが統合され、変数Ｃとなる。変数Ｃに関連付けられたメモリアクセスは３０個である。すなわち、統合される前の、変数Ａに関連付けられたメモリアクセスの数と変数Ｂに関連付けられたメモリアクセスの総数である。従って、変数Ｃがエスケープした場合、影響するメモリアクセスは３０個となる。そのために、図８Ａの割り当てよりも、図８Ｂの割り当てを使った方が当該割り当ての後に行われる最適化にとって都合がよい。
【００７１】
図９Ａは、call番号を設定しない場合（９０１）及びcall番号を設定する場合（９０２）におけるローカル変数アクセスへの置換の禁止の相違を示す。
図９Ａでは、call命令、return命令、store命令、load命令と各線との関係を記載していないが、図９Ｂで示されている例示と同じである。従って、図９Ｂについてまず説明する。
【００７２】
図９Ｂは、バイナリコード内に含まれるコール命令で呼ばれるコードが多段にインラインされている状態を例示する。
多段のインラインには例えば、if文又はloop文が含まれていてもよい。
call命令（９１１）は、左から右への矢印で示されている。当該矢印は、callの深さに対応する。call命令（９１１）によって、callの深さが深くなる。call命令（９１１）の次にstore命令（９１３）が実行される。
return命令（９１２）は、右から左への矢印で示されている。当該矢印は、callの深さに対応する。return命令（９１２）によって、callの深さが浅くなる。return命令（９１２）の次にload命令（９１４）が実行される。
store命令（９１３）は、上から下への線（二重線）で示されている。
load命令（９１４）は、上から下への線（三重線）で示されている。
【００７３】
図９Ａに戻って説明する。
call番号を設定しない場合（９０１）は、本発明の第１の実施態様（図４Ａ〜図４Ｄ）及び本発明の第２の実施態様（図５Ａ〜図５Ｄ）に対応する。
call番号を設定する場合（９０２）は、本発明の第３の実施態様（図６Ａ〜図６Ｃ）及び本発明の第４の実施態様（図７Ａ〜図７Ｅ）に対応する。
call番号を設定しない場合（９０１）、スタックポインターが９０１に示す時点でエスケープすると、ローカル変数アクセスへの置換の禁止が、バイナリコードに含まれるメモリアクセスのうち、レジスタ・セーブ・エリア以外のメモリアクセス全体に及ぶ（塗り潰し部分）。
call番号を設定する場合（９０２）、call番号の親子関係を考慮するために、call番号の親子関係を示すグラフ（９０３）が作成される。９０２では、call番号が丸数字（１〜６）で示されている。ツリーグラフ（９０３）は、９０２に示される場合のcall番号（１〜６）の親子関係を示すグラフである。スタックポインターが９０２に示す時点でエスケープした場合には、ローカル変数アクセスへの置換の禁止がcall番号１及び３に含まれるメモリアクセスにとどまり、それ以外のcall番号２及び４〜６に含まれるメモリアクセスに及ばない。よって、ローカル変数アクセスへの置換の禁止が全体でなくその一部で済む（塗り潰し部分）。従って、call番号を設定する場合はローカル変数アクセスへの置換の禁止が一部で済む（塗り潰し部分）ことから、最適化がそれ以外の部分では行われる点でcall番号を設定しない場合に比べて有利である。
この最適化によって、パフォーマンスだけでなく間接分岐のターゲット・アドレスを分析するためにも有用である。
【００７４】
図１０は、変換対象であるバイナリコードと、当該バイナリコードに本発明の実施態様最適化を適用した後に生成されるコードを示す。
バイナリコード（１００１）は、変換対象のコードである。０１〜２９の各数字は、説明用に付した番号である。
２つのSTM（store multiple）（０１、０７）はそれぞれ、レジスタ・セーブ・エリアへ各レジスタをストアしている命令である。
(SP off)（０１、０７）は、元のSP値からの相対オフセットを表す。
２つのLM（load memory）（２５、２８）はそれぞれ、レジスタ・セーブ・エリア内の値をレジスタにロードを行っている命令である。
STM（０１、０７）にそれぞれ、R15 escapesとある。これらは、現時点ではスタックポインターがエスケープしているが、将来的には、最適化によりストアが消えるために、R15がescapeしなくなることを示す。
また、LM（２５、２８）にそれぞれ、R15 is loadedとある。これらは、スタックポインターがロードされたことによってSP offの値が変化する（-192 => -96等）ことを示す。これは、図７Ｃに示すオフセット伝播によって変更されたことを表す。
【００７５】
バイナリコード（１００１）に、本発明の第１の実施態様に従う最適化を適用した。その結果、最適化されたコード（１００２）が生成された。１０１〜１３９の各数字は、説明用に付した番号である。斜線文字は、当該最適化によって、変更されたコードを示す。
L1〜L4（１０１、１０２、１０３及び１０４）への代入は、最初に出てくるSTM（０１）からの変換結果である。
L5〜L8（１０９、１１０、１１１及び１１２）への代入は、上記STM（０１）の次に出てくるSTM（０７）からの変換結果である。
R4 = L7（１２８）は、最初に出てくるL R4, 0x98(R0,R15)（２４）からの変換結果である。
R12 = L5からR15 = L8まで（１２９、１３０、１３１及び１３２）は、最初に出てくるLM（２５）からの変換結果である。
R4 = L3（１３４）は、上記L R4, 0x98(R0,R15)（２４）の次に出てくるL R4,0x98(R0,R15)（２７）からの変換結果である。
R12 = L15からR15 = L4まで（１３５、１３６、１３７及び１３８）は、上記LM（２５）の次に出てくるLM（２８）からの変換結果である。
また、バイナリコード（１００１）で示されるコードの場合において、本発明の第２〜第４の各実施態様に従う最適化を適用した場合、最適化された各コードは本発明の第１の実施態様に従う最適化を適用した場合に得られる最適化コード（１００２）と同じである。
【００７６】
実施例
ジャスト・イン・タイム（ＪＩＴ）コンパイラに、本発明の第１の実施態様による最適化方法のプロトタイプを実装した。最適化されたバイナリコード（１００２）の実行速度は、同一ハードウェア環境において、最適化前のバイナリコード（１００１）の実行速度と比べて約２倍のパフォーマンス改善が観察された。
また、ＪＩＴコンパイラに、本発明の第２〜第４の各実施態様に従う最適化方法を実装した場合においても、本発明の第１の実施態様に従う最適化方法と同様の結果が得られた。
【図１】
0005583514.tif 000002
【図２】
0005583514.tif 000003
【図３】
0005583514.tif 000004
【図４Ａ】
0005583514.tif 000005
【図４Ｂ】
0005583514.tif 000006
【図４Ｃ】
0005583514.tif 000007
【図４Ｄ】
0005583514.tif 000008
【図５Ａ】
0005583514.tif 000009
【図５Ｂ】
0005583514.tif 000010
【図５Ｃ】
0005583514.tif 000011
【図５Ｄ】
0005583514.tif 000012
【図６Ａ】
0005583514.tif 000013
【図６Ｂ】
0005583514.tif 000014
【図６Ｃ】
0005583514.tif 000015
【図７Ａ】
0005583514.tif 000016
【図７Ｂ】
0005583514.tif 000017
【図７Ｃ】
0005583514.tif 000018
【図７Ｄ】
0005583514.tif 000019
【図７Ｅ】
0005583514.tif 000020
【図８Ａ】
0005583514.tif 000021
【図８Ｂ】
0005583514.tif 000022
【図９Ａ】
0005583514.tif 000023
【図９Ｂ】
0005583514.tif 000024
【図１０】
0005583514.tif 000025