(57)【要約】【課題】プログラムの設計からの見直しを必要とすることなくメモリ使用量が全体として低くなるようにプログラム変更を行う。【解決手段】本発明の一態様としてのプログラム処理方法は、解析対象となるプログラムから静的オブジェクトを検出する第１の検出ステップと、前記第１の検出ステップで検出された静的オブジェクトを使用している第１の関数と、前記第１の関数を呼び出している第２の関数とを前記解析対象となるプログラムから検出する第２の検出ステップと、前記第１の関数の個数が１個であり、また、前記第２の関数の個数が１つかつ前記第２の関数による前記第１の関数の呼び出し回数が１回のとき、前記第１の関数で使用されている前記検出された静的オブジェクトを動的オブジェクトに置換するように前記解析対象となるプログラムが変換可能であることを決定する決定ステップと、を備える。【選択図】図２９
2009053802.tif 000002
【特許請求の範囲】
【請求項１】
解析対象となるプログラムから静的オブジェクトを検出する第１の検出ステップと、
前記第１の検出ステップで検出された静的オブジェクトを使用している第１の関数と、前記第１の関数を呼び出している第２の関数とを前記解析対象となるプログラムから検出する第２の検出ステップと、
前記第１の関数の個数が１個であり、また、前記第２の関数の個数が１つかつ前記第２の関数による前記第１の関数の呼び出し回数が１回のとき、前記第１の関数で使用されている前記検出された静的オブジェクトを動的オブジェクトに置換するように前記解析対象となるプログラムが変換可能であることを決定する決定ステップと、
を備えたプログラム処理方法。
【請求項２】
解析対象となるプログラムから静的オブジェクトを検出する第３の検出ステップと、
前記第３の検出ステップで検出された静的オブジェクトを使用している第３の関数と、前記第３の関数を呼び出している第４の関数と、前記第４の関数を呼び出している第５の関数とを検出する第４の検出ステップと、
前記第４の関数の個数が１つであり、前記第５の関数の個数が１つかつ前記第５の関数による前記第４の関数の呼び出し回数が１回のとき、前記検出された静的オブジェクトに代わる動的オブジェクトを前記第４の関数でメモリ確保し前記第３の関数で使用されている静的オブジェクトを前記第４の関数でメモリ確保された動的オブジェクトへの参照に置換するように前記解析対象となるプログラムが変換可能であることを決定する決定ステップと、
を備えたプログラム処理方法。
【請求項３】
前記決定ステップは、前記第３の関数の個数が２つ以上の場合は、２つ以上の前記第３の関数を呼び出している第４の関数が同じ関数であるときのみ前記解析対象となるプログラムが変換可能であることを決定することを特徴とする請求項２に記載のプログラム処理方法。
【請求項４】
前記決定ステップは、前記検出された静的オブジェクトに代わる動的オブジェクトへの参照をレジスタを介して関数引数として前記第４の関数から前記第３の関数に渡すことが可能であるとき前記解析対象となるプログラムが変換可能であることを決定することを特徴とする請求項２または３に記載のプログラム処理方法。
【請求項５】
請求項１ないし４のいずれか一項に記載の各ステップを実行するための命令コードを記述した、コンピュータに実行させるためのプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、解析対象となるプログラムを解析処理するプログラム処理方法およびプログラムに関し、たとえば、コンパイラのように入力プログラムを変換する機能を持つプログラムに関する。
【背景技術】
【０００２】
プログラムでは、静的にメモリを確保して使うことと、動的にメモリを確保して使うことがある。以後、静的に確保したメモリの領域を静的オブジェクトと呼ぶ。同様に、動的に確保したメモリの領域を動的オブジェクトと呼ぶ。
【０００３】
静的オブジェクトの例としては、C言語でのプログラム領域や大域変数があり、動的オブジェクトの例としては、C言語での局所変数がある。
【０００４】
静的オブジェクトの特徴はプログラム実行中に常に存在していることであり、動的オブジェクトの特徴は必要な場合にのみ存在していることである。
【０００５】
静的オブジェクトの場合、その静的オブジェクトがプログラム実行中に常に必要ではない場合、本来であれば使用しなくてもよいメモリ（たとえばRAM（Random Access Memory））を使用していることになる。特に組み込み分野では、メモリの制約が厳しい傾向があり、常にメモリを占有する静的オブジェクトはできるだけ少ない方が望ましい。ただし、動的オブジェクトはプログラム実行中に必要な時のみ存在しているため、プログラム設計が適切に決められていない場合は、動的オブジェクトの適切な保存や維持が難しい。
【０００６】
このように、開発時のあいまいな設計や、従来プログラムの流用などの理由により、静的オブジェクトが必要以上に多いことがある。一度プログラムを作成した後では、静的オブジェクトを単純に動的オブジェクトに変更することは、ほとんどの場合、非常に難しい。その理由は、プログラム全体に影響が及ぶため、設計からの見直しが必要になるからである。
【特許文献１】特開２００２−９９４２５号公報
【特許文献２】特許第３１６７３８６号
【特許文献３】特開平第０６−３３２６８４号公報
【特許文献４】国際公開第２００１−０９０８８７号パンフレット
【特許文献５】特開２００５−２２８０４７号公報
【発明の開示】
【発明が解決しようとする課題】
【０００７】
本発明は、プログラムの設計からの見直しを必要とすることなくメモリ使用量が全体として低くなるようにプログラム変更を行うことを可能としたプログラム処理方法およびプログラムを提供する。
【課題を解決するための手段】
【０００８】
本発明の一態様としてのプログラム処理方法は、解析対象となるプログラムから静的オブジェクトを検出する第１の検出ステップと、前記第１の検出ステップで検出された静的オブジェクトを使用している第１の関数と、前記第１の関数を呼び出している第２の関数とを前記解析対象となるプログラムから検出する第２の検出ステップと、前記第１の関数の個数が１個であり、また、前記第２の関数の個数が１つかつ前記第２の関数による前記第１の関数の呼び出し回数が１回のとき、前記第１の関数で使用されている前記検出された静的オブジェクトを動的オブジェクトに置換するように前記解析対象となるプログラムが変換可能であることを決定する決定ステップと、を備える。
【０００９】
本発明の一態様としてのプログラム処理方法は、解析対象となるプログラムから静的オブジェクトを検出する第３の検出ステップと、前記第３の検出ステップで検出された静的オブジェクトを使用している第３の関数と、前記第３の関数を呼び出している第４の関数と、前記第４の関数を呼び出している第５の関数とを検出する第４の検出ステップと、前記第４の関数の個数が１つであり、前記第５の関数の個数が１つかつ前記第５の関数による前記第４の関数の呼び出し回数が１回のとき、前記検出された静的オブジェクトに代わる動的オブジェクトを前記第４の関数でメモリ確保し前記第３の関数で使用されている静的オブジェクトを前記第４の関数でメモリ確保された動的オブジェクトへの参照に置換するように前記解析対象となるプログラムが変換可能であることを決定する決定ステップと、を備える。
【発明の効果】
【００１０】
本発明により、プログラムの設計からの見直しを必要とすることなくメモリ使用量が全体として低くなるようにプログラム変更を行うことが可能となる。
【発明を実施するための最良の形態】
【００１１】
本発明の実施形態は、解析対象となるプログラムの構造を解析して該プログラムの情報を収集し、その情報を基にして該プログラムの静的オブジェクトを動的オブジェクトに置換するようにプログラムを変換することにより、できるだけ必要な時に必要な量のメモリ（たとえばRandom Access Memory（RAM））を使うようにして、メモリの使用量を削減することを大きな特徴の１つとする。
【００１２】
以下、本発明の実施形態を説明するに先だち、静的オブジェクトと動的オブジェクトについて簡単に説明しておく。背景技術の欄で述べたように、プログラムでは、静的にメモリを確保して使うことと、動的にメモリを確保して使うことがある。静的に確保したメモリの領域を静的オブジェクトと呼び、動的に確保したメモリの領域を動的オブジェクトと呼ぶ。静的オブジェクトの例としては、C言語でのプログラム領域や大域変数があり、動的オブジェクトの例としては、C言語での局所変数がある。静的オブジェクトの特徴は、プログラム実行中に常に存在していることである。一方、動的オブジェクトの特徴は、必要な場合にのみ存在していることである。これを示したのが図１および図２である。
【００１３】
図１は 静的オブジェクトと動的オブジェクトを持つプログラム例１を示す。このプログラム例１ではまずint glb=1が実行され、その後、main()が実行され、main()によりfunc()が呼び出される。関数の外で宣言されたint glbは静的オブジェクトをメモリ確保する命令の一例である。またfunc()で宣言されたint lclは動的オブジェクトをメモリ確保する命令の一例である。
【００１４】
図２は、図１のプログラム例１に示される（A）時点および（B）時点でのメモリ内容を示している。glbは大域変数（静的オブジェクト）であるため（A）および（B）の両時点でメモリに存在しているが、lclは局所変数（動的オブジェクト）であるため（B）時点でのみメモリに存在することとなる。
【００１５】
以下、図面を参照しながら、本発明の実施形態について詳細に説明する。
【００１６】
（実施形態１）
図２９は、本実施形態としてのコンパイラ（プログラム）により行われる処理の流れの一例を示したフローチャートである。このプログラムは、たとえば汎用のコンピュータ装置に搭載されたプロセッサによって実行されることができる。このプログラムは、ＣＤ−ＲＯＭなどの記憶媒体に記憶して、あるいはネットワークを介して配布されて、上記コンピュータに適宜インストールすることもできる。以下では、プログラム言語としてC言語を例として説明を行うが、本発明はプログラム言語には依存せず、任意のプログラム言語に適用可能である。
【００１７】
図２９のステップＳ１１では、解析対象となるプログラムから、関数の呼び出し関係および呼び出し順序と、関数毎に使用されている静的オブジェクトおよび動的オブジェクトを検出する。C言語プログラムでは、大域変数は静的オブジェクトであり、局所変数は動的オブジェクトである。解析対象となるプログラムはＣ言語で記述されたソースプログラムである。
【００１８】
一般的にコンパイラは、各関数内で使われている大域変数および局所変数を抽出でき、またそれぞれの関数内で呼び出される関数（関数の呼び出し関係）および呼び出し順序を抽出できる。
【００１９】
そこで、本ステップＳ１１では、まずソースプログラムから、関数とその関数内で使われている大域変数および局所変数を抽出し記憶する。図１のソースプログラム（プログラム例１）から取得した、関数毎に使用されている大域変数および局所変数を図３に示す。次に、ソースプログラムから、関数の呼び出し関係と呼び出しの順序とを抽出し記憶する。図１のソースプログラム（プログラム例１）から取得した、関数の呼び出し関係と呼び出し順序とを図４に示す。図３と図４の情報を合わせると、図５のように関数―変数対応情報として表すことができる。このように、図３および図４の情報は、図５のように両方を合わせて１つのデータとして持っていても、それぞれ別個に持っていても良い。以降は、図３および図４の情報を合わせた図５の情報（関数−変数対応情報）を用いて説明を行うこととする。
【００２０】
以下の各ステップＳ１２〜Ｓ１７では図５の関数−変数対応情報を基にして、各大域変数について、以下のような処理を行う。
【００２１】
ステップＳ１２では、図５の関数−変数対応情報を走査し、まだ処理の対象となっていない大域変数が残っているかどうかを調べる。複数の同じ名称の大域変数がある場合、これらのうち１つのみが処理の対象となっていればよい。まだ残っている場合は（Ｓ１２のＹＥＳ）ステップＳ１３に進み、すべての大域変数について、処理済みであれば（Ｓ１２のＮＯ）、出力ステップＳ１８に進む。
【００２２】
ステップＳ１３では、まだ処理の対象になっていない大域変数を選択する。上述のように複数の同じ名称の大域変数があるときはこれらのうち１つが選択されていれば、他については選択済みであると見なし、選択の対象とはしない。ステップＳ１３は、たとえば解析対象となるプログラムから静的オブジェクトを検出する第１の検出ステップを含む。
【００２３】
ステップＳ１４では、ステップＳ１３で選択された大域変数（以下、対象変数と呼ぶ）が使用されている関数（第１の関数）がルート関数（親関数が存在しない関数）であるかどうかを判断する。なおルート関数であるかどうかは、図５の関数−変数対応情報だけでなく、図４の情報から判断することもできる。対象変数が使用されている関数がルート関数であれば（ＹＥＳ）局所変数への置換は行わないことを決定してステップＳ１２に戻り、ルート関数でなければ（ＮＯ）、ステップＳ１５へ進む。このように対象変数が使用されている関数がルート関数である場合にステップＳ１２に戻るのは、ルート関数は、プログラム（コンパイラ）の実行中は常に実行されているため、ルート関数に含まれる大域変数を局所変数に置換してもメモリ節約にはならないからである。ただし、対象変数が使用されている関数がルート関数であった場合にステップＳ１５に進んでも何ら支障は生じないため、このようにすることも可能である。
【００２４】
ステップＳ１５では、対象変数が使用されている関数の個数を計測する。これは、図５の関数−変数対応情報だけでなく、図３の情報からも検出および計測できる。対象変数が使用されている関数が１つであれば（ＹＥＳ）、ステップＳ１６へ進み、そうでなければ（ＮＯ）、局所変数への置換は行わないことを決定してステップＳ１２へ戻る。
【００２５】
ステップＳ１６では、対象変数が使用されている関数を呼び出している他の関数（第２の関数）を検出し、他の関数が、対象変数が使用されている関数を呼び出している回数（実行回数）を計測する。これは、対象変数が使用されている関数について、図５の関数−変数対応情報における出現回数を数えることで計測できる。図５の関数−変数対応情報だけでなく、図４の情報からも出現回数は計測可能である。対象変数が使用されている関数の呼び出し回数が１回であるとき（ＹＥＳ）、ステップＳ１７へ進み、そうでなければ（ＮＯ）、局所変数の置換は可能でないことを決定してステップＳ１２へ戻る。
【００２６】
上述のステップＳ１４、Ｓ１６は、第１の検出ステップで検出された静的オブジェクトを使用している第１の関数と、第１の関数を呼び出している第２の関数とを解析対象となるプログラムから検出する第２の検出ステップを含んでいる。
【００２７】
ステップＳ１７では、対象変数は、１つの関数のみで使用されており、かつこの関数が他の関数から呼び出される回数が１回であることが判明しているため、当該対象変数を、局所変数に置換するようにソースプログラムを変換（書き換える）ことが可能であると決定し、このようにソースプログラムを変換する。より詳細には、（１）ソースプログラムから大域変数をメモリ確保する命令を削除し、（２）大域変数に代わる局所変数をメモリ確保する命令を、大域変数が使用されている関数に追加し、（３）大域変数を使用している関数で用いられている各命令に含まれる大域変数を局所変数に置換する（（３）に関しては大域変数の名称と、局所変数の名称を異ならせる場合のみ）。なお、ソースプログラムを書き換えるのではく、コンパイル途中で得られる中間プログラムを書き換えるようにすることも可能である。本ステップＳ１７の後、ステップＳ１２へ戻る。
【００２８】
このように、本フローでは、対象変数（静的オブジェクト）を使用している関数（第１の関数）の個数が１個であり（ステップＳ１５のＹＥＳ）、また、対象変数を使用している関数を呼び出している関数（第２の関数）の個数が１つかつ第２の関数による第１の関数の呼び出し回数が１回のとき（Ｓ１６のＹＥＳ）、第１の関数で使用されている対象変数を動的オブジェクトに置換するように解析対象となるプログラム（たとえばソースプログラム）を変換可能であることを決定する（Ｓ１７）。これはたとえば決定ステップに相当する。
【００２９】
ステップＳ１８では、ステップＳ１７によって変換後のソースプログラムが得られていればこれを出力する。変換後のソースプログラムをコンパイルして得られる実行プログラムを出力してもよい。出力されたプログラムは、ハードディスク等の記憶部へ記憶されてもよい。
【００３０】
ここでステップＳ１７ではソースプログラムの書き換えを行うとしたが、プログラムの書き換えを行わずに、ステップＳ１８において局所変数に置換可能な大域変数を指定するメッセージ、または該大域変数が存在するソースプログラム上の箇所を指定したメッセージを、開発者が使用するディスプレイに表示するようにしてもよい。
【００３１】
図１のソースプログラムから上記の処理を経ることによって得られた変換後のソースプログラムの例を図７に示す。なお図５の関数−変数対応情報に相当する、図７から得られる関数−変数対応情報は図６の通りである。図７のプログラムと図１のプログラムとはソース上、等価である。図７のプログラムに示される（A）時点および（B）時点でのメモリ内容を図８に示す。図８と、本実施形態を適用する前の図２とを比較すると、本実施形態によるプログラム変換の効果として、(A)時点でのメモリ使用量が8バイト（int型が4バイトである場合の数値）削減できることが分かる。なお(B)時点では本実施形態の適用前と同じである。
【００３２】
（実施形態２）
本実施形態では、コンパイラの特徴である、レジスタ割り付けの情報を活用してプログラム変換を行う。レジスタ割り付けとは、変数のようなオブジェクトに実体（レジスタやスタックなど）を割り付ける（どの変数をレジスタに割り当てるべきかなど）コンパイラ内部の処理である。本実施形態としてのコンパイラ（プログラム）による処理の流れの一例を図３０のフローチャートに示す。
【００３３】
ステップＳ２１では、解析対象となるプログラムから、関数毎に使用されている静的オブジェクトおよび動的オブジェクトと、関数の呼び出し関係および呼び出し順序と、を抽出し、関数−変数対応情報を生成する。
【００３４】
ステップＳ２２では、ステップＳ２１で生成した関数−変数対応情報を走査し、まだ処理の対象となっていない大域変数が残っているかどうかを調べる。複数の同じ名称の大域変数がある場合、これらのうち１つのみが処理の対象となっていればよい。まだ残っている場合は（Ｓ２２のＹＥＳ）ステップＳ２３に進み、すべての大域変数について、処理済みであれば（Ｓ２２のＮＯ）、出力ステップＳ３３に進む。
【００３５】
ステップＳ２３では、まだ処理の対象になっていない大域変数を選択する。上述のように複数の同じ名称の大域変数があるときはこれらのうち１つが選択されていれば、他については選択済みであると見なし、選択の対象とはしない。ステップＳ２３は、たとえば解析対象となるプログラムから静的オブジェクトを検出する第３の検出ステップを含む。
【００３６】
ステップＳ２４では、ステップＳ２３で選択された大域変数（以下、対象変数と呼ぶ）が使用されている関数（第３の関数）がルート関数（親関数がない関数）であるかどうかを判断する。対象変数が使用されている関数がルート関数であれば（ＹＥＳ）ステップＳ２２に戻り、ルート関数でなければ（ＮＯ）、ステップＳ２５へ進む。ただし、実施形態１で述べたように、対象変数が使用されている関数がルート関数であった場合にステップＳ２５に進んでも何ら支障は生じないため、このようにすることも可能である。
【００３７】
ステップＳ２５では、対象変数が使用されている関数の個数を、たとえば上記関数−変数対応情報に基づき、計測する。対象変数が使用されている関数が１つであれば（ＹＥＳ）、ステップＳ２６へ進み、そうでなければ（ＮＯ）、ステップＳ２８に進む。
【００３８】
ステップＳ２６では、対象変数が使用されている関数を呼び出している他の関数（第４の関数）を検出し、他の関数が、対象変数が使用されている関数を呼び出している回数（実行回数）を計測する。これは、対象変数が使用されている関数について、上記関数−変数対応情報における出現回数を数えることで計測できる。対象変数が使用されている関数を呼び出している回数が１回であるとき（ＹＥＳ）、ステップＳ２７へ進み、そうでなければ（ＮＯ）、ステップＳ２８に進む。
【００３９】
ステップＳ２７では、対象変数は、１つの関数のみで使用されており、かつこの関数が他の関数から呼び出される回数が１回であることが判明しているため、実施形態１と同様に、当該対象変数を、局所変数に置換するようにソースプログラムを書き換える。本ステップＳ２７の後、ステップＳ１２へ戻る。
【００４０】
ステップＳ２８では、対象変数が使用されている関数の親関数がルート関数であるかどうかを調べる。対象変数が使用されている関数の親関数がルート関数であるときはステップＳ２２に戻り、ルート関数でないときは（ＮＯ）ステップＳ２９に進む。
【００４１】
ステップＳ２９では、親関数の数が１つであるかどうかを調べ、１つでないときは（Ｓ２９のＮＯ）ステップＳ２２に戻り、１つのときは（Ｓ２９のＹＥＳ）ステップＳ３０に進む。ただしステップＳ２５で対象変数が複数の関数で使用されていると判定されたときは（Ｓ２５のＮＯ）、これら複数の関数の親関数が同一であることが必要である。
【００４２】
ステップＳ３０では、親関数を呼び出している他の関数（第５の関数）を検出し、検出した他の関数が１つであり、かつこの他の関数が親関数（第４の関数）を呼び出している回数が１回であるときは（Ｓ３０のＮＯ）、ステップＳ３１に進み、そうでないときはステップＳ２２に戻る。
【００４３】
上述のステップＳ２４、Ｓ２６、Ｓ３０は、第３の検出ステップで検出された静的オブジェクト（対象変数）を使用している第３の関数と、第３の関数を呼び出している第４の関数と、第４の関数を呼び出している第５の関数とを検出する第４の検出ステップとを含んでいる。
【００４４】
ステップＳ３１では、対象変数が使用されている関数は、関数の引数を一つ追加したとすると、その引数をレジスタで受け取ることができるかどうか（メモリを介さずに引数を受け取ることができるかどうか）を検査し、できる場合は（ＹＥＳ）、ステップＳ３２に進み、できない場合は（ＮＯ）、ステップＳ２２に戻る。引数がレジスタで受け取れるかどうかは、コンパイラ内部のアルゴリズムに従う。例えば、引数の数が８つまではレジスタで受け取るというアルゴリズムであり、現在の引数の個数が７つ以下であれば、新しい引数が一つ追加されてもレジスタで受け取ることができると判断できる。
【００４５】
ステップＳ３２では、対象変数（大域変数）に代わる局所変数を、対象変数が使用されている親関数でメモリ確保し、子関数で使用されている対象変数を親関数でメモリ確保された局所変数への参照に置換するようにソースプログラムを変換可能であることを決定し、このようにソースプログラムを変換する。具体的には、対象変数（大域変数）のメモリ確保命令（宣言）を削除し、対象変数が使用されている関数の親関数に対象変数に代わる局所変数のメモリ確保命令（宣言）を追加し、対象変数が使用されていた関数と親関数との間で、引数として局所変数への参照を渡すように、ソースプログラムを書き換える。実体を一つに維持するため、引数としては局所変数のポインタを渡すことにする。対象関数が使用されている関数では、親関数からポインタとして局所変数を受け取る。すなわち、局所変数にアクセスする場合は、引数として受け取ったポインタ経由で親関数の局所変数にアクセスする。なお、ソースプログラムを書き換えるのではく、コンパイル途中で得られる中間プログラムを書き換えるようにすることも可能である。
【００４６】
このように、本フローでは、対象変数（静的オブジェクト）を使用している関数（第３の関数）を呼び出している関数（第４の関数）の個数が１つであり（Ｓ２９のＹＥＳ）、第４の関数を呼び出している関数（第５の関数）の個数が１つかつ第５の関数による第４の関数の呼び出し回数が１回のとき（Ｓ３０のＮＯ）、対象変数に代わる動的オブジェクトを第４の関数でメモリ確保し第３の関数で使用されている対象変数を第４の関数でメモリ確保された動的オブジェクトへの参照に置換するように解析対象となるプログラム（たとえばソースプログラム）を変換可能であることを決定する（Ｓ３２）。これはたとえば決定ステップに対応する。ここで、決定ステップは、第３の関数の個数が２つ以上の場合は（Ｓ２５のＮＯ）、２つ以上の第３の関数を呼び出している第４の関数が同一のときのみ解析対象となるプログラムを変換可能であることを決定するものとする。また決定ステップは、対象変数に代わる動的オブジェクトへの参照をレジスタを介して関数引数として第３の関数に渡すことが可能であるとき解析対象となるプログラムを変換可能であることを決定してもよい。
【００４７】
ステップＳ３３では、ステップＳ２７またはＳ３２またはこれらの両方によってソースプログラムが変換されていれば、変換後のソースプログラムを出力する。変換後のソースプログラムをコンパイルして得られる実行プログラムを出力してもよい。出力されたプログラムはハードディスク等の記憶部へ記憶されてもよい。
【００４８】
ここでステップＳ２７およびＳ３２ではソースプログラムの書き換えを行うとしたが、プログラムの書き換えを行わずに、ステップＳ３３において、局所変数に置換可能な大域変数を指定するメッセージ、該大域変数が存在するソースプログラム上の箇所を指定したメッセージ、親関数の局所変数に置換可能な大域変数を指定するメッセージ、または該大域変数が存在するソースプログラム上の箇所を指定したメッセージを、開発者が使用するディスプレイに表示するようにしてもよい。
【００４９】
また、ステップＳ３１では、対象変数が使用されている関数は、引数を一つ追加したとすると、その引数をレジスタで受け取ることができない場合はステップＳ３２に進まないこととしたが、ルート関数に、対象変数が使用されている関数の親関数とは別の関数が用いられている場合は、ステップＳ３２に進むようにしてもよい（以下の説明では、これを、「ステップＳ３１の例外処理」と称する）。これについての詳細は後述する。
【００５０】
以下３つの解析対象となるプログラム例２〜４を用いて、本実施形態によりプログラム変換を行う例を具体的に示す。
【００５１】
（プログラム例２）
図９は解析対象となるプログラム例２を示す。図１０は図９のプログラム例２からステップＳ２１によって得られる関数−変数対応情報である。図１１は、図９のプログラム例２に示される（A）時点、（B）時点、(C)時点でのメモリ内容を示す。
【００５２】
一方、図１２は図９のプログラム例２から図３０の処理を経て得られた変換後ソースプログラムを示す。図１３は図１２の変換後ソースプログラムから得られる関数−変数対応情報を示す。図１４は図１２の変換後ソースプログラムに示される（A）時点、（B）時点、(C)時点でのメモリ内容を示す。図１５は、前述したステップＳ３１の例外処理を行った場合の（A）時点、（B）時点、(C)時点でのメモリ内容を示す。
【００５３】
本実施形態を適用する前の図１１と、適用後の図１４とを比較すると、本実施形態によるプログラム変換の効果として、(A)時点でのメモリ使用量が削減でき、(B)時点、(C)時点では本実施形態の適用前と同じであることがわかる。また、本実施形態の適用前の図１１と、ステップＳ３１の例外処理を行った場合の図１５とを比較すると、(C)時点では本実施形態の適用した場合の方がメモリ使用量が多いものの、(A)時点では本実施形態を適用した場合の方がメモリ使用量が少なく、これによりルート関数から呼び出される他の関数（対象変数が使用される関数の親関数と異なる、ルート関数で使用される関数）では、十分に本実施形態の効果が得られることが理解される。
【００５４】
（プログラム例３）
図１６は解析対象となるプログラム例３を示す。図１７は図１６のプログラム例３からステップＳ２１によって得られる関数−変数対応情報である。図１８は、図１６のプログラム例３に示される（A）時点、（B）時点、(C)時点、（D）時点でのメモリ内容を示す。
【００５５】
一方、図１９は図１６のプログラム例２から図３０の処理を経て得られた変換後ソースプログラムを示す。図２０は図１９の変換後ソースプログラムから得られる関数−変数対応情報を示す。図２１は図１９の変換後ソースプログラムに示される（A）時点、（B）時点、(C)時点、（D）時点でのメモリ内容を示す。図２２は、前述したステップＳ３１の例外処理を行った場合の（A）時点、（B）時点、(C)時点、（D）時点でのメモリ内容を示す。
【００５６】
本実施形態を適用する前の図１８と、本実施形態を適用した後の図２１とを比較すると、本実施形態によるプログラム変換の効果として、(A)時点でのメモリ使用量が削減でき、(B)時点、(C)時点、（D）時点では本実施形態の適用前と同じになることがわかる。また、本実施形態の適用前の図１８と、ステップＳ３１の例外処理を行った場合の図２２とを比較すると、(C)時点、(D)時点では本実施形態を適用した場合の方がメモリ使用量が多いものの、(A)時点では本実施形態を適用した場合の方がメモリ使用量が少なく、これによりルート関数から呼び出される他の関数（対象変数が使用される関数の親関数と異なる、ルート関数で使用される関数）では、十分に本実施形態の効果が得られることが理解される。
【００５７】
（プログラム例４）
図２３は解析対象となるプログラム例４を示す。図２４は図２３のプログラム例４からステップＳ２１によって得られる関数−変数対応情報である。図２５は、図２３のプログラム例４に示される（A）時点、（B）時点、(C)時点、（D）時点、（E）時点でのメモリ内容を示す。
【００５８】
一方、図２６は図２３のプログラム例４から図３０の処理を経て得られた変換後ソースプログラムを示す。図２７は図２６の変換後ソースプログラムから得られる関数−変数対応情報を示す。図２８は図２６の変換後ソースプログラムに示される（A）時点、（B）時点、(C)時点、（D）時点、（E）時点でのメモリ内容を示す。
【００５９】
本実施形態を適用する前の図２５と、本実施形態を適用した後の図２８とを比較すると、（A）時点~（E）時点のすべての時点においてメモリ使用量が常に削減されていることが理解される。
【００６０】
（実施形態３）
対象変数については、変数名（あるいはシンボル名）ではなく、対象変数のアドレスで扱っても良い。どちらも一意に決まるためである。手順としては、実施形態１や実施形態２において、変数の選択を変数名ではなくアドレスを利用して実施する。アドレスを利用することで、名前がついていないもの（配列の要素など。たとえばint glb[10]によって配列を宣言した場合における配列の要素glb[2]）、アセンブリ言語プログラム（単に指定されたアドレスにデータを入れる場合など）を処理することができる。
【００６１】
（実施形態４）
実施形態３のように対象変数をアドレスで扱うことができると、ソースプログラムがなくても、実行プログラム（ROM（Read On Memory）データ）から逆アセンブルなどでメモリアクセス命令を検出することにより、複数の関数で使われる変数（大域変数）なのかスタック上の変数（局所変数）なのかを判断できる（大域変数と局所変数とでメモリアクセス命令が異なる）。また、逆アセンブルなどで関数呼び出し命令を検出することで、関数の呼び出し関係や呼び出し回数が得られる。ソースプログラムなしで関数の境界を見分ける方法は、デバッグ情報（ソースプログラムと実行プログラムとの対応関係を表した情報）を用いる方法や、関数呼び出し命令の飛び先は関数の開始アドレスであるとみなし開始アドレス間の範囲を１つの関数の領域とする方法がある。これらを利用することでROMデータから図５のような関数−変数対応情報を取得できるため、実施形態１、実施形態２と同様の処理を実施することができる。
【００６２】
本実施形態４の場合、コンパイル時の変換とは違い、単にROMデータを変換すると既に配置されているオブジェクトとのアドレス整合が解決できないため、ソースプログラムを変換するのではなく、前述した置換可能性等を表したメッセージを出力ステップで出力することとする。
【図面の簡単な説明】
【００６３】
【図１】静的オブジェクトと動的オブジェクトを持つプログラム例１を示す図。
【図２】図１のプログラム例１に示される（A）時点および（B）時点でのメモリ内容を示す図。
【図３】図１のソースプログラム（プログラム例１）から取得した、関数毎に使用されている大域変数および局所変数の情報を示す図。
【図４】図２のソースプログラム（プログラム例１）から取得した、関数の呼び出し関係と呼び出し順序との情報とを示す図。
【図５】図３と図４の情報を合わせた情報（関数−変数対応情報）を示す図。
【図６】図７のソースプログラムから得られる関数−変数対応情報を示す図。
【図７】図１のソースプログラムから上記の処理を経ることによって得られた変換後ソースプログラムを示す図。
【図８】図７のプログラムに示される（A）時点および（B）時点でのメモリ内容を示す図。
【図９】解析対象となるプログラム例２を示す図。
【図１０】図９のプログラム例２から得られる関数−変数対応情報を示す図。
【図１１】図９のプログラム例２に示される（A）時点、（B）時点、(C)時点でのメモリ内容を示す図。
【図１２】図９のプログラム例２から図３０の処理を経て得られた変換後ソースプログラムを示す図。
【図１３】図１２の変換後ソースプログラムから得られる関数−変数対応情報を示す図。
【図１４】図１２の変換後ソースプログラムに示される（A）時点、（B）時点、(C)時点でのメモリ内容を示す図。
【図１５】ステップＳ３１の例外処理を行った場合の（A）時点、（B）時点、(C)時点でのメモリ内容を示す図。
【図１６】解析対象となるプログラム例３を示す図。
【図１７】図１６のプログラム例３から得られる関数−変数対応情報を示す図。
【図１８】図１６のプログラム例３に示される（A）時点、（B）時点、(C)時点、（D）時点でのメモリ内容を示す図。
【図１９】図１６のプログラム例２から図３０の処理を経て得られた変換後ソースプログラムを示す図。
【図２０】図１９の変換後ソースプログラムから得られる関数−変数対応情報を示す図。
【図２１】図１９の変換後ソースプログラムに示される（A）時点、（B）時点、(C)時点、（D）時点でのメモリ内容を示す図。
【図２２】ステップＳ３１の例外処理を行った場合の（A）時点、（B）時点、(C)時点、（D）時点でのメモリ内容を示す図。
【図２３】解析対象となるプログラム例４を示す図。
【図２４】図２３のプログラム例４から得られる関数−変数対応情報を示す図。
【図２５】図２３のプログラム例４に示される（A）時点、（B）時点、(C)時点、（D）時点、（E）時点でのメモリ内容を示す図。
【図２６】図２３のプログラム例４から図３０の処理を経て得られた変換後ソースプログラムを示す図。
【図２７】図２６の変換後ソースプログラムから得られる関数−変数対応情報を示す図。
【図２８】図２６の変換後ソースプログラムに示される（A）時点、（B）時点、(C)時点、（D）時点、（E）時点でのメモリ内容を示す図。
【図２９】実施形態１としてのコンパイラにより行われる処理の流れの一例を示したフローチャート。
【図３０】実施形態２としてのコンパイラによる全体の処理の流れの一例を示したフローチャート。
【図１】
2009053802.tif 000003
【図２】
2009053802.tif 000004
【図３】
2009053802.tif 000005
【図４】
2009053802.tif 000006
【図５】
2009053802.tif 000007
【図６】
2009053802.tif 000008
【図７】
2009053802.tif 000009
【図８】
2009053802.tif 000010
【図９】
2009053802.tif 000011
【図１０】
2009053802.tif 000012
【図１１】
2009053802.tif 000013
【図１２】
2009053802.tif 000014
【図１３】
2009053802.tif 000015
【図１４】
2009053802.tif 000016
【図１５】
2009053802.tif 000017
【図１６】
2009053802.tif 000018
【図１７】
2009053802.tif 000019
【図１８】
2009053802.tif 000020
【図１９】
2009053802.tif 000021
【図２０】
2009053802.tif 000022
【図２１】
2009053802.tif 000023
【図２２】
2009053802.tif 000024
【図２３】
2009053802.tif 000025
【図２４】
2009053802.tif 000026
【図２５】
2009053802.tif 000027
【図２６】
2009053802.tif 000028
【図２７】
2009053802.tif 000029
【図２８】
2009053802.tif 000030
【図２９】
2009053802.tif 000031
【図３０】
2009053802.tif 000032