JP3437932B2 - 配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置 - Google Patents

配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置

Info

Publication number
JP3437932B2
JP3437932B2 JP00071299A JP71299A JP3437932B2 JP 3437932 B2 JP3437932 B2 JP 3437932B2 JP 00071299 A JP00071299 A JP 00071299A JP 71299 A JP71299 A JP 71299A JP 3437932 B2 JP3437932 B2 JP 3437932B2
Authority
JP
Japan
Prior art keywords
array
code
check
range check
array range
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
JP00071299A
Other languages
English (en)
Other versions
JP2000207221A (ja
Inventor
基弘 川人
秀昭 小松
俊明 安江
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
International Business Machines Corp
Original Assignee
International Business Machines Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by International Business Machines Corp filed Critical International Business Machines Corp
Priority to JP00071299A priority Critical patent/JP3437932B2/ja
Priority to US09/473,858 priority patent/US6665864B1/en
Publication of JP2000207221A publication Critical patent/JP2000207221A/ja
Application granted granted Critical
Publication of JP3437932B2 publication Critical patent/JP3437932B2/ja
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Devices For Executing Special Programs (AREA)

Description

【発明の詳細な説明】
【0001】
【発明の属する技術分野】本発明は、コンパイラに関
し、より詳しくは、コンパイラにおいて配列レンジ・チ
ェックの回数を減少させてプログラムの実行速度を上げ
る方法に関する。配列レンジ・チェックとは、プログラ
ムにおける配列アクセスがその配列の範囲を越えている
か否かに関する検査である。
【0002】
【従来の技術】データ・フロー解析(Data-flow analys
is)を用いて配列チェック除去を行う方法(R. Gupta.
Optimizing array bound checks using flow analysis.
ACM Letters on Programming Languages and Systems,
2(1-4): 135-150, March-December 1993.等を参照のこ
と)がある。この方法は、次のような2段階の処理で配
列レンジ・チェックを除去する。すなわち、(1)配列
レンジ・チェックを減らすために実行順の最初の方にチ
ェックを挿入する。(2)不要な配列レンジ・チェック
を除去する。この方法の長所はループ以外の場所につい
ても適用できる点にある。しかし、配列レンジ・チェッ
クを除去できる範囲が狭く、レンジを超えるのは誤りで
あるという仕様の言語にしか適用できないという欠点が
ある。
【0003】他の従来技術としては、ループ・スプリッ
ティングによるループ変換という方法がある。これはル
ープの下限値のチェック部分、チェック不要部分、上限
値のチェック部分の3つに分ける方法である。例えば、
表1のようなプログラムを表2のように変換するもので
ある。
【表1】
【表2】 このように3つに分けると2つ目のforループはレン
ジ・チェックを省略することができる。この方法はこの
例のようにループ内の配列アクセスがシンプルならばコ
ードサイズは3倍になるだけで済むが、配列ベース変数
が複数ある場合については場合分けが多くなり、それに
つれてコードサイズも大きくなるという欠点がある。
【0004】
【発明が解決しようとする課題】Java言語(Jav
aはSun Microsystems社の商標)は仕様として配列のレ
ンジを超えたアクセスを検出し、ユーザ定義の例外ハン
ドラが無いときは例外の起きたメソッドを抜けて呼び出
したメソッドへと制御を移し、ユーザが定義した例外ハ
ンドラがあるときにはその例外ハンドラに処理を移すこ
とができる。そのため例外が起きることが正しい動作と
してプログラムが書かれる場合もあるため、配列レンジ
・チェックは必要不可欠である。しかし、配列レンジ・
チェックはレンジ・チェックを必要としない言語と比較
して実行速度の低下を引き起こす。実際のプログラムで
は、レンジを超えたアクセスが無いことを保証できる配
列アクセスが存在し、これらの冗長な配列レンジ・チェ
ックを除去することは性能向上に大きく貢献する。また
例外の発生と配列への値の代入のような副作用を生じる
処理の間の実行順序の保証の観点から、最適化の範囲を
拡大できるればより好ましい。
【0005】本発明は、より配列レンジ・チェックの回
数を減らし、実行速度を上げることを目的とする。
【0006】また、複数の配列レンジ・チェックをまと
めた広い配列レンジ・チェックを行い、この広い配列レ
ンジ・チェックが失敗した場合に厳密な配列レンジ・チ
ェックを行うという2段階のチェックを行うことにより
実行時の配列レンジ・チェックの回数を減らし、高速な
実行を可能にする方法を提供することも目的である。
【0007】さらに、ループ内のどの実行経路を通って
も必ず行われる配列アクセスの情報を用いてバージョニ
ングを実施する方法を提供することも目的である。な
お、バージョニングとは、コンパイル時に、(1)プロ
グラムのある部分のコードが実行される状態をいくつか
に分類し、(2)実行時にその状態を分類するためのチ
ェック・コードと、それぞれの状態に対する、当該プロ
グラムのある部分の実行コードを生成する処理である。
【0008】
【課題を解決するための手段】配列レンジ・チェックの
回数を減らす本発明は、より広い概念では、複数の配列
レンジ・チェックを統合して、統合された配列レンジ・
チェックのためのコードを生成し、統合された配列レン
ジ・チェックの結果が失敗であった場合のために、複数
の配列レンジ・チェックに含まれる配列レンジ・チェッ
クのためのコードを生成するものである。これらのコー
ドは記憶装置に記憶され、後にプロセッサにより実行さ
れる。このような概念をより具体的にすると、以下の3
つの態様になる。
【0009】第1の態様においては、プログラム内の配
列アクセスに対する配列レンジ・チェックのためのコー
ドを生成する場合、複数の配列アクセスに対応する複数
の配列レンジ・チェックを統合した統合配列レンジ・チ
ェック(例えば実施例におけるVERSION_OR
[B])の結果を1又は複数の記憶領域(例えばプロセ
ッサのフラグ)に格納する第1コードを生成し且つ記憶
装置(例えばメインメモリ)に記憶する第1ステップ
と、記憶領域を検査し且つ当該記憶領域が統合配列レン
ジ・チェックの成功を示している場合には前記複数の配
列レンジ・チェックに包含される配列レンジ・チェック
のための第2コード(第3コードにより無効化されない
場合には実行しないと正しい実行がなされなくなるよう
な配列レンジ・チェック)を無効化する第3コード(例
えばPowerPC(InternationalBusiness Machines
Corp. の商標)におけるゼロサイクル・ブランチ命
令)を生成し且つ記憶装置に格納する第2ステップとを
実行する。例えば、フラグをレジスタとして使用できる
プロセッサを使用する場合、高速に第2コードの無効化
を行うことができ、またコードサイズもあまり増やさず
に、配列レンジ・チェックの回数を減らすことができ
る。なお、フラグをレジスタとして使用できるというの
は、フラグの内容を算術命令等によって勝手に壊される
こと無く、そのフラグに保持しておくことができる、と
いうことである。
【0010】先に示した第1ステップは、複数の配列ア
クセスに対する配列レンジ・チェックを所定の条件に従
って統合し、統合された配列レンジ・チェックの情報を
記憶装置に格納するステップと、統合された配列レンジ
・チェックを記憶領域に割り当てるステップとを含むよ
うにすることができる。
【0011】本発明の第1の態様においてバージョニン
グを実施する場合、当該バージョニングの条件である統
合配列レンジ・チェックの結果を格納した記憶領域を参
照し且つその記憶領域が統合配列レンジ・チェックの成
功を示している場合には統合配列レンジ・チェックに包
含される配列レンジ・チェックのためのコードを含まな
いバージョンに分岐し且つ記憶領域が統合配列レンジ・
チェックの不成功を示している場合には第2及び第3コ
ードを含むバージョンに分岐するコードを生成し且つ記
憶装置に格納するステップとを、さらに実行する。これ
により、バージョニングの条件である統合配列レンジ・
チェックの不成功の場合でも、従来に比して高速な実行
が可能になる。
【0012】本発明の第2の態様においては、プログラ
ム内の配列アクセスに対する配列レンジ・チェックのた
めのコードを生成する場合、処理の対象となる、プログ
ラムの第1部分(例えば実施例のAの部分)に対応し且
つ含まれる配列アクセスに対応して必要な範囲の配列レ
ンジ・チェックを行うための第2部分(例えば実施例の
Bの部分)を生成し且つ記憶装置に記憶するステップ
と、第1部分について、例外を発生させる配列レンジ・
チェックをそれより前に移動させることによって副作用
を生じるような命令の存在を無視して配列レンジ・チェ
ックの最適化及び不要な配列レンジ・チェックの除去を
実施し、第1部分のベーシック・ブロックごとに必要と
なる配列レンジ・チェックの情報(又は除去不可能な配
列レンジ・チェック)を記憶装置に記憶するステップ
と、必要となる配列レンジ・チェックを行い且つ当該配
列レンジ・チェックが不成功であった場合に当該不成功
であった配列レンジ・チェックを含むベーシック・ブロ
ックに対応する、第2部分内のベーシック・ブロックに
ジャンプする条件分岐コードを生成し且つ記憶装置に格
納するステップとを実施する。本発明の第2の態様は、
第1の態様が実施できないような場合においても実施す
ることができる。また、本来配列レンジ・チェックが失
敗する配列アクセスが生じるまで、最適化及び不要な配
列レンジ・チェックの除去を行った第1部分を実行する
ので、配列レンジ・チェックの実行回数を減少させるこ
とができる。
【0013】本発明の第3の態様においては、プログラ
ム内のループのバージョニングを実行する場合、ループ
内のいずれの実行経路を通過したとしても必ず行われる
配列アクセスに対する配列レンジ・チェックの第1集合
情報(実施例においてはVERSION_AND
[B])を収集し、収集結果を記憶装置に格納するステ
ップと、収集結果を用いて、バージョニングのための検
査コードを生成し且つ記憶装置に格納するステップと、
収集結果を用いて不要な配列レンジ・チェックを除去
し、除去不可能な配列レンジ・チェックのためのコード
を含む、検査コードによる配列レンジ・チェックが成功
した場合におけるバージョンを生成し且つ記憶装置に格
納するステップと、検査コードによる配列レンジ・チェ
ックが不成功の場合におけるバージョンを生成し且つ記
憶装置に格納するステップとを実行する。これにより、
ループ内において必ず配列レンジ・チェックに失敗する
場合のみ、検査コードによる配列レンジ・チェックが不
成功の場合におけるバージョンを実行することになるの
で、配列レンジ・チェックの実行回数が減ることが期待
できる。
【0014】上は2バージョンであったが3バージョン
に分けることもでき、この場合には以下のステップを実
行する。すなわち、ループ内のいずれの実行経路を通過
したとしても必ず行われる配列アクセスに対する配列レ
ンジ・チェックに限定せずに配列レンジ・チェックの第
2集合情報(実施例におけるVERSION_OR
[B])を収集し、第2の収集結果を記憶装置に格納す
るステップと、第2集合情報から第1集合情報に含まれ
る配列レンジ・チェックを除去した第3集合情報を用い
て、検査コードによる配列レンジ・チェックが成功した
場合におけるバージョンのさらなるバージョニングのた
めの第2検査コードを生成し且つ記憶装置に格納するス
テップと、第2の収集結果を用いて不要な配列レンジ・
チェックを除去し、除去不可能な配列レンジ・チェック
のためのコードを含む、第2検査コードによる配列レン
ジ・チェックが成功した場合におけるバージョンを生成
し且つ記憶装置に格納するステップとである。なお、検
査コードによる配列レンジ・チェックが成功した場合に
おけるバージョンは、第2検査コードによる配列レンジ
・チェックが不成功であった場合におけるバージョンと
なる。このようにすると、コード量が3倍になるが、元
のコードが少ない場合にはさらに実行時における配列レ
ンジ・チェック回数の削減が期待できる。
【0015】また本発明の第1の態様と第3の態様は組
み合わせることができ、例えば、2バージョンの場合に
除去不可能な配列レンジ・チェックとインデックス変数
の範囲による配列レンジ・チェックの結果を、生成され
たコードを実行するプロセッサのフラグに格納するため
のコードを生成し且つ記憶装置に格納するステップと、
フラグを検査し且つ当該フラグが除去不可能な配列レン
ジ・チェックの成功を示している場合には除去不可能な
配列レンジ・チェックのためのコードを無効化する他の
コードを生成し且つ記憶装置に格納するステップとをさ
らに実行することも考えられる。これにより、検査コー
ドによる配列レンジ・チェックが成功の場合にフラグの
チェックだけで実際の配列レンジ・チェックが省略でき
る場合もあるため、処理が高速化される。
【0016】上と同じような効果を得るためにプロセッ
サのフラグを用いる場合、ループ内のいずれの実行経路
を通過したとしても必ず行われる配列アクセスに対する
配列レンジ・チェックに限定せずに配列レンジ・チェッ
クの第2集合情報(実施例においてはVERSION_
OR[B])を収集し、第2の収集結果を記憶装置に格
納するステップと、第2集合情報から第1集合情報に含
まれる配列レンジ・チェックを除去した第3集合情報
(実施例においてはVERSION_OR[B]−VE
RSION_AND[B])の結果を、生成されたコー
ドを実行するプロセッサのフラグに格納するためのコー
ドを生成し且つ記憶装置に格納するステップと、フラグ
を検査し且つ当該フラグが第3集合情報に含まれる配列
レンジ・チェックが成功を示している場合に2バージョ
ンの場合に除去不可能な配列レンジ・チェックのための
コードを無効化する他のコードを生成し且つ記憶装置に
格納するステップとを実行することも考えられる。
【0017】また、本発明の第1の態様と第3の態様を
バージョニングを行わない場合に組み合わせる時には、
本発明の第1の態様における処理で説明した第1ステッ
プにおいて、プログラムのある部分のいずれの実行経路
を通過したとしても必ず行われる配列アクセスに対する
配列レンジ・チェックの第1集合情報(実施例において
はVERSION_AND[B])を収集し、収集結果
を記憶装置に格納するステップと、ある部分のいずれの
実行経路を通過したとしても必ず行われる配列アクセス
に対する配列レンジ・チェックに限定せずに配列レンジ
・チェックの第2集合情報(実施例においてはVERS
ION_OR[B])を収集し、第2の収集結果を記憶
装置に格納するステップと、第2集合情報に含まれる配
列レンジ・チェックを1つの記憶領域に割り当て、第2
集合情報から第1集合情報に含まれる配列レンジ・チェ
ックを除去した第3集合情報の配列レンジ・チェックを
1又は複数の記憶領域に割り当てるステップとを実行す
る。これにより効果的に配列レンジ・チェックの除去を
することができる。
【0018】以上本発明を処理のフローとして表現して
きたが、以上の処理を実行するコンピュータ及びコンピ
ュータ・プログラム又は専用の回路又は装置により実施
することも可能である。なお、コンピュータ・プログラ
ムにより実施する場合には、CD−ROMやフロッピー
・ディスク、ハードディスクのような記憶媒体にコンピ
ュータ・プログラムを格納する場合がある。
【0019】
【発明の実施の形態】Javaを用いた環境における、
本発明の装置構成を図1を用いて説明する。サーバ・コ
ンピュータ1及びクライアント・コンピュータ5はネッ
トワーク3を介して接続されている。クライアント・コ
ンピュータ5は、JavaVM(Virtual Machine)5
2及びOS(Operating System)53及びハードウエア
(CPU及びメモリを含む)55を含む。さらに、Ja
vaVM52は、Javaインタープリタ54又はJa
va JITコンパイラ56を含む。インタープリタ5
4及びJITコンパイラ56の両者を有している場合も
ある。なお、クライアント・コンピュータ5は、通常の
コンピュータの他、メモリの大きさが小さかったり、ハ
ードディスク等の補助記憶装置を含まないような、いわ
ゆるネットワーク・コンピュータや情報家電の場合もあ
る。
【0020】サーバ・コンピュータ1では、Javaソ
ースコード10は、Javaコンパイラ12によりコン
パイルされる。このコンパイルの結果が、バイトコード
14である。このバイトコード14は、ネットワーク3
を介してクライアント・コンピュータ5に送信される。
バイトコード14は、クライアント・コンピュータ5内
のWWWブラウザ(World Wide Web Browser)などに設
けられたJava仮想マシン(Java VM)52にとって
ネイティブ・コードであり、実際ハードウエア55のC
PUにて実行する場合には、Javaインタープリタ5
4や、JavaJITコンパイラ56を用いる。インタ
ープリタ54は、実行時にバイトコード14をデコード
し、命令ごとに用意される処理ルーチンを呼び出して実
行する。一方、JITコンパイラ56は、バイトコード
を事前にあるいは実行する直前にコンパイラを用いてマ
シン・コード58に変換してそれをCPUで実行する。
【0021】以下、JITコンパイラ56の本発明に関
連する処理について説明する。
【0022】A.フラグをレジスタとして使用できるプ
ロセッサにおいて、範囲の広いレンジ・チェックの結果
をプロセッサのフラグに割り当て、そのフラグを用いて
配列レンジ・チェックのためのコードを無効化する処理 先にも述べたがフラグをレジスタとして使用できると
は、フラグの内容を算術命令等によって勝手に壊される
ことなく、そのフラグに保持しておくことができるとい
う意味である。例えば、Merced(Intel社の
次世代プロセッサの開発コード名)の述語(Predicat
e)付き実行やPowerPCのゼロサイクル・ブラン
チ命令(Zero Cycle Branch)を利用することを意図し
たものである。但し、これは一例であって同様の機能を
有する他のプロセッサであっても本発明は有効である。
【0023】では、本処理の大まかな流れを図2を用い
て説明する。まず、複数の配列アクセスに対応する複数
の配列レンジ・チェックを所定の条件に従って統合し、
その結果VERSION_OR[B]を記憶装置(例え
ばメインメモリ)に格納する(ステップ110)。この
統合のための処理は後に詳しく説明する。図2には示さ
なかったが、このステップ110の後に配列レンジ・チ
ェックの最適化処理を実施してもよい。そして、VER
SION_OR[B]の配列レンジ・チェックを1又は
複数のフラグに割り当てる(ステップ120)。この割
り当てに必要な処理についても後に詳しく説明する。次
に、統合された配列レンジ・チェックの結果を、割り当
てられたフラグに格納するコードを生成し、記憶装置に
格納する(ステップ130)。もしバージョニングを実
施する場合(ステップ140)には、フラグを用いてバ
ージョニング・ヘッダを生成し、フラグ・チェック成功
のバージョンとフラグ・チェック失敗のバージョンを生
成し且つ記憶装置に格納する(ステップ150)。フラ
グ・チェック成功のバージョンとフラグ・チェック失敗
のバージョンはここまででは実質的に同じである。バー
ジョニングを行わない場合(ステップ140)又はステ
ップ150の後に、メソッド全体に対して、後に詳細に
述べる不要な配列レンジ・チェックの除去と、除去処理
によっても残った、残余の配列レンジ・チェックを包含
する配列レンジ・チェックに対応するフラグを検査し且
つ当該フラグがチェック成功を示している場合には残余
の配列レンジ・チェックのためのコードを無効化するコ
ードを生成し且つ記憶装置に格納する(ステップ16
0)。なお、最適化処理をステップ110の後に実施す
ると、ステップ160における不要な配列レンジ・チェ
ックの除去によって除去される配列レンジ・チェックが
少なくなる。
【0024】では各ステップごとに詳しく説明する。ま
ず、ステップ110におけるVERSION_OR
[B]の生成について説明する。このステップ110の
処理(1)では、原則として配列インデックス又は配列
ベースを変更する命令に関わる配列レンジ・チェックを
本ステップの対象外として取り扱いながら、ベーシック
・ブロックの先頭における、配列レンジ・チェックの集
合C_GEN[B]を、実行とは逆順に収集する。但
し、配列インデックス変数をv=v+c(cは正又は負
の定数)のように変更する場合には、本ステップの対象
外とはしないで、集合情報C_GEN[B]内の配列イ
ンデックスの式f(v)をf(v+c)として再計算
し、置き換える。以下にステップ110の処理(1)の
擬似コードを示す。
【表3】 for (各ベーシック・ブロックについて実行とは逆順に命令を取り出す){ switch(命令){ 配列アクセス命令: その配列レンジ・チェックCに対して C_GEN[B] += C; break; 配列のベース変数 a の変更命令: for (全てのC∈ C_GEN[B]){ if (Cの中に変更された配列ベース a によるlb(a)又はub(a)が含まれる){ C_GEN[B] -= C; } } break; インデックス変数 v の変更命令: for (全てのC∈ C_GEN[B]){ if (Cは変更されたインデックス変数v 又はvの式 f(v) で構成される){ if (インデックス変数vが v = v + c (cは正又は負の定数:定数の加算又は減算)で変更される){ Cのvを v + c、又はf(v)をf(v + c)として置き換える。 } else { C_GEN[B] -= C; } } } break; } }
【0025】表3全体は各ベーシック・ブロックについ
て行われる。そして、各ベーシック・ブロックの各命令
ごとにforループ内の処理が実施される。命令の取り
出し順番は実行順とは逆順となる。switch文は、取り出
した命令が、それ以下の条件(ここでは3つの条件)の
いずれかに該当する場合には、該当する条件の下に規定
された処理を実行するものである。この条件は、配列ア
クセス命令、配列ベース変数aの変更命令、及びインデ
ックス変数vの変更命令である。配列アクセス命令の場
合には、その配列アクセス命令に対する配列レンジ・チ
ェックCをC_GEN[B]に入れる。配列ベース変数
aの変更命令の場合には、このベース変数aに関連する
配列レンジ・チェックCを本発明では取り扱うことがで
きないので、C_GEN[B]からCを除去する処理を
実施する。インデックス変数vの変更の場合には、まず
C_GEN[B]内の各配列レンジ・チェックCがその
変更された配列インデックス変数vに関連するか検査す
る。もし定数と配列インデックスの上限又は下限とによ
る検査であれば、インデックス変数vの変更操作はその
検査には影響が無い。そして、インデックス変数vの変
更命令が、定数の加算又は減算命令であるか判断する。
インデックス変数vの変更命令が、定数の加算又は減算
命令である場合には、C_GEN[B]内の配列レンジ
・チェックCも、その定数の加算又は減算に従って、定
数の加算又は減算を実施する。本発明で取り扱い不可能
なインデックス変数vの変更を実施している場合には、
そのインデックス変数vに関連する配列レンジ・チェッ
クCはC_GEN[B]から取り除かれる。
【0026】次にステップ110の処理(2)について
説明する。ここでは、上で収集したC_GEN[B]を
用いて深さ優先探索(DFS:Depth-First Search)の
ポスト・トラバーサルの順番、すなわち後続のベーシッ
ク・ブロックが先に来るような順番で全てのベーシック
・ブロックについて、次の式を一回実行する。S∈ Suc
c(B) であってBとSは同じループ内又はB及びS共に
ループ外という条件を満たす全てのSについて、 C_OUT_OR[B] = ∪ C_IN_OR[S] C_IN_OR[B] = C_GEN[B] ∪ backward(C_OUT_OR[B], B) Succ(B)は、Bの直後に来る全てのベーシック・ブロッ
クの意味である。上の式は以下のことを示している。あ
るベーシック・ブロックBの後端における、配列レンジ
・チェックの集合C_OUT_OR[B]は、S∈ Suc
c(B)であってベーシック・ブロックBとベーシック・ブ
ロックSが同じループ内又はB及びS共にループ外とい
う条件を満たす全てのベーシック・ブロックSの先頭に
おける、配列レンジ・チェックの集合C_IN_OR
[S]の和集合である。また、C_OUT_OR[B]
は、後に述べる処理により、ベーシック・ブロックBに
おいて行われる配列インデックスに対する変更に応じて
所定の修正が行われ、新たに集合backward(C_OUT_OR
[B], B)となる。この集合backward(C_OUT_OR[B],B)及び
先に求めたC_GEN[B]の和集合がC_IN_OR
[B]となる。最終的に必要なのはこのC_IN_OR
[B]である。
【0027】backward(C_OUT_OR[B], B)の処理はApp
endix Aで説明する。
【0028】ステップ110の処理(3)は処理(2)
で作成したC_IN_OR[B]を用いて次の式による
データ・フロー解析を行い、FLAG_IN[B]及び
FLAG_OUT[B]を作成する。P∈Pred
(B)である全てのPについて FLAG_IN[B] = ∩ FLAG_OUT[P] FLAG_OUT[B] = C_IN_OR[B] ∪ forward(FLAG_IN[B], B) Pred(B)は、Bの直前に来る全てのベーシック・ブロッ
クの意味である。上記の式は以下のことを意味してい
る。ベーシック・ブロックBの直前の全てのベーシック
・ブロックPの後端における集合FLAG_OUT
[P]の積集合が集合FLAG_IN[B]となる。そ
して、この集合FLAG_IN[B]をforward(FLAG_I
N[B], B)で処理し、その結果と処理(2)で求めた集合
C_IN_OR[B]との和集合が和集合FLAG_O
UT[B]となる。
【0029】forward(FLAG_IN[B], B)の処理はAppe
ndix Bで説明する。
【0030】ステップ110の処理(4)では、次の式
を全てのベーシック・ブロックについて行い、C_IN
_OR[B]内の不要な配列集合情報を削除する。 C_IN_OR[B]=C_IN_OR[B]−FLA
G_IN[B]
【0031】ステップ110の処理(5)では、処理
(4)で作成したC_IN_OR[B]を用いて、A.
の処理の対象たるプログラムの部分(例えばループ)内
で不変の配列アクセス、及びループの場合ループ変数の
とりうる範囲が特定できる配列アクセスに関してはルー
プ変数の取り得る範囲を基に、処理の対象たるプログラ
ムの部分(例えばループ)のエントリ・ポイントにおけ
る配列レンジ・チェック集合情報VERSION_OR
[B]を計算する。このVERSION_OR[B]
は、バージョニング・ヘッダ内の配列レンジ・チェック
の集合情報である。例えば、ループ変数がiであって、
取り得る範囲が1以上n未満であることが分かれば、u
b(a)についてはi=n−1である場合についてチェ
ックし、lb(a)についてはi=1であるとしてVE
RSION_OR[B]を作成する。このVERSIO
N_OR[B]がA.における統合された配列レンジ・
チェックの情報である。
【0032】次に、図2には示されていない配列レンジ
・チェックの最適化をAppendix Cで説明して
おく。この処理を実施しなくともA.の効果はあるが、
より配列レンジ・チェックの数を削減するためにはこの
処理を実施する。なお、この配列レンジ・チェックの最
適化は、バージョニングを実行する前に行う。また、ス
テップ110の前に実行してもよい。
【0033】次にステップ120の処理の説明をする。
ステップ110において得られたVERSION_OR
[B]をフラグに割り振る処理を実施する。すなわち、
以下の擬似コードの処理を実施する。A.の処理の対象
となる、プログラムの部分(例えばループ)に対しては
以下のとおりである。なお、初期的には、 VERSION_OR[B]内の配列レンジ・チェック
の数:n 割り当て可能なプロセッサのフラグの最大数:fn とする。
【表4】 if (n <= 1 || fn <= 1) { <フラグへの割り当て及び配列レンジ・チェックのためのコードの無効化 は行わない。> } else { if (n > fn){ <VERSION_OR[B]内の配列レンジ・チェックを、処理対象部分における、 対応する配列レンジ・チェックの数でソートする。> do { <配列レンジ・チェック数の小さいほうから2つの項目を消去し、 その2つの項目及び配列レンジ・チェック数をマージして1つの項目 とし、ソートした配列レンジ・チェック集合情報に挿入する。> n--; } while (n > fn); } <各フラグに配列レンジ・チェックとループ変数等の範囲チェックの ANDを割り当てる。複数の配列レンジ・チェックがマージされている場合に はそれらのANDを割り当てる。> C_IN_OR[B] -= バージョニング・ヘッダとして使用される配列レンジ・チェッ ク; fn -= n; }
【0034】表4について少し説明しておく。最初のi
f文はVERSION_OR[B]に含まれる配列レン
ジ・チェックの数が0又は使用可能なフラグの数が0で
ある場合には、表4の処理は意味をなさないので、ここ
で処理を終了する。この条件を満たした場合には、n>
fnであるか否か検査する。言い換えれば、フラグの数
より配列レンジ・チェックの数が多いか検査する。フラ
グの数がVERSION_OR[B]内の配列レンジ・
チェックの数より多い場合には、各フラグに、各配列レ
ンジ・チェックとループの場合にはループ変数の範囲チ
ェックとの積(AND)を割り当てる。一方、フラグの
数がVERSION_OR[B]内の配列レンジ・チェ
ックの数より少ない場合には、1つのフラグに対して、
VERSION_OR[B]内の配列レンジ・チェック
を幾つかまとめて割り当てなければならない。そこで、
VERSION_OR[B]内の配列レンジ・チェック
を、処理対象部分(例えばループ)における、対応する
配列レンジ・チェックの数でソートする。そして、以下
の処理を、マージしてできた配列レンジ・チェック集合
情報内の項目数がフラグの数より小さくなるまで、繰り
返す。この処理とは、配列レンジ・チェック数の小さい
ほうから2つの項目を消去し、その2つの項目及び配列
レンジ・チェック数をマージして1つの項目とし、ソー
トした配列レンジ・チェック集合情報に挿入する処理で
ある。よって、この処理が終了すると、複数の配列レン
ジ・チェックがマージされている場合には、それらの配
列レンジ・チェックの積(AND)(ループの場合には
ループ変数の範囲チェックとの積)をフラグに割り当て
る。後続の処理のために、C_IN_OR[B]からバ
ージョニング・ヘッダとして使用される配列レンジ・チ
ェック(殆どの場合VERSION_OR[B]そのも
の)を取り除く処理を実施する。殆どの場合C_IN_
OR[B]は空になる。
【0035】また、この後に全てのベーシック・ブロッ
クに対して次の処理を行う。なお、全てのC_IN_O
R[B]の和(OR)としてALL_FLAGという集
合を作成する。この集合情報は、各項目について配列レ
ンジ・チェック情報に加えてそのベーシック・ブロック
番号を有している。 ALL_FLAG = ∪ C_IN_OR[B] また、初期的には、 ALL_FLAGの配列レンジチェック集合情報の項目数 : n 割り当て可能なプロセッサの最大フラグ数 : fn とする。
【表5】 if (fn <= 0) { <フラグへの割り当て及び配列レンジ・チェックの無効化は行わない。> } else { <ALL_FLAGの配列レンジ・チェック集合情報を、対応する配列レンジ・ チェックの数でソートし、配列レンジ・チェック数が1以下の要素を 削除する。> while (n > fn){ <配列レンジ・チェック数の小さいほうからベーシック・ブロックが 同一の2つの項目を消去し、その2つの項目及びレンジ・チェック数 をマージして1つの項目とし、ソートした配列レンジ・チェック集合 情報に挿入する。> if (マージできる項目が無かった) { n = fn; break; } n--; } <各フラグに配列レンジ・チェック数が多い項目から配列レンジ・チェック 集合情報内の配列レンジ・チェックを割り当てる。 複数の配列レンジ・チェックがマージされている場合にはそれらのANDを を割り当てる。> ALL_FLAG -= フラグを割り当てられなかった配列レンジ・チェック fn -= n; }
【0036】表5の処理を大まかに説明しておく。表5
は余ったフラグを用いて、配列レンジ・チェックの数を
さらに減少させるための処理である。表4等の処理で割
り当て可能なフラグが0になってしまえば、表5の処理
は行われない。もし割り当て可能なフラグが存在してい
るならば、ALL_FLAGの中でマージを試みる。そ
のため、表4でも行われているように、ALL_FLA
Gの配列レンジ・チェックを、対応する配列レンジ・チ
ェックの数でソートする。この時、配列レンジ・チェッ
クの数が1以下であるものにフラグを割り当てても効果
がないので、1以下のものは破棄される。そして、配列
レンジ・チェックの数が小さい方から、ベーシック・ブ
ロックが同一の項目を消去し、その2つの項目及びレン
ジ・チェック数をマージして1つの項目とし、ソートし
た配列レンジ・チェック集合情報に挿入する。これを集
合情報に含まれる項目がフラグの数以下になるまで繰り
返す。但し、同じベーシック・ブロックの項目がないと
マージできないので、マージできない場合には、そこで
繰り返し処理を中止する。そして、各フラグに配列レン
ジ・チェック数が多い項目から配列レンジ・チェックを
割り当てる。複数の配列レンジ・チェックがマージされ
ている場合にはそれらの積(AND)を割り当てる。最
後に、ALL_FLAGからフラグに割り当てられなか
った配列レンジ・チェックを取り除いておく。これは後
の処理で用いられる。
【0037】以上のような処理にてVERSION_O
R[B]の配列レンジ・チェックを各フラグに割り当て
る。なお、以上の割り当て方法は一例であって他の方法
にて割り当てることも可能である。さらに表5の処理は
実施しなくともよい。
【0038】次にステップ130の説明をする。ここで
は、ステップ120の結果により、A.の処理に必要な
最初のコードを生成する。すなわち、各フラグに、ステ
ップ120によりそのフラグに割り当てられた配列レン
ジ・チェック集合情報の項目の配列レンジ・チェックの
結果を格納するためのコードを生成する。1つのフラグ
に多数の配列レンジ・チェックが割り当てられた場合に
は、それらの配列レンジ・チェックの結果がANDされ
てそのフラグに格納されるようなコードが生成される。
【0039】ステップ140は単純な場合分けであるか
らこれ以上述べない。A.の処理は、ループなどのバー
ジョニングを行わない場合にも適用可能である。
【0040】バージョニングを行う場合には、ステップ
150に遷移する。ここでは、まずバージョニング・ヘ
ッダを生成する。このバージョニング・ヘッダとは、ど
のバージョンへジャンプするかの判断を行う場所であ
る。ここでは、ステップ130でバージョニング・ヘッ
ダとなるVERSION_OR[B]の配列レンジ・チ
ェックの結果は割り当てのあったフラグに格納されてい
ることになるので、それらのフラグをチェックするコー
ドを生成する。割り当てのあった全てのフラグが配列レ
ンジ・チェック成功を示している場合には、成功の場合
のバージョンへジャンプし、不成功を示している場合に
は、1つでも不成功の場合のバージョンへジャンプする
ためのコードも生成する。
【0041】次に実際に配列レンジ・チェック成功の場
合のバージョンのためのコードと、不成功の場合のバー
ジョンのためのコードを生成する。但し、これらのバー
ジョンはこの段階では実質的に同じものである。すなわ
ち、両バージョンとも、最適化の処理を実施していない
場合には、個々の配列アクセスに対して1つの必要十分
な配列レンジ・チェックを含んでいる。最適化の処理を
実施した場合には、各ベーシック・ブロックごとにその
ベーシック・ブロックに含まれる全ての配列アクセスに
対し、必要な配列レンジ・チェックが生成されている。
【0042】ステップ160では、主に不要な配列レン
ジ・チェックの除去を実施する。それと同時に、除去さ
れなかった、残余の配列レンジ・チェックを包含する配
列レンジ・チェックのフラグを検査し且つ当該フラグが
配列レンジ・チェック成功を示している場合残余の配列
レンジ・チェックのためのコードを無効化するコードを
生成する。この不要な配列レンジ・チェックの除去処理
の詳細はAppendix Dに記載してある。但し、
ステップ320の処理を以下のように変更する。すなわ
ち、ALL_FLAGからベーシック・ブロックBの要
素を抜き出した部分集合ALL_FLAG[B]を新た
に定義し、C_GEN[B],C_IN[B],C_O
UT[B],VERSION_OR[B]及びALL_
FLAG[B]内の各配列レンジ・チェックにつき、ベ
ース変数、インデックスのインデックス変数の項、最小
定数オフセット、最大定数オフセット、及び対応するフ
ラグ名を記憶する。なお、C_GEN[B]の各配列レ
ンジ・チェックについては[対応するフラグ名]には
[なし]を記憶し、VERSION_OR[B]及びA
LL_FLAG[B]の各配列レンジ・チェックには上
で述べたステップ130で割り当てられたフラグ名を記
憶する。そして、次の式によるデータ・フロー解析を実
施する。ベーシック・ブロックBが初期ブロックでない
場合、Bに先行する全てのPについて、 C_IN[B] = (∩ C_OUT[P]) ∪ VERSION_OR[B] ∪ ALL_FL
AG[B] ベーシック・ブロックBが初期ブロックである場合、 C_IN[B] = VERSION_OR[B] ∪ ALL_FLAG[B] C_OUT[B] = C_GEN[B] ∪ forward(C_IN[B],B) 少し説明しておくと、ベーシック・ブロックBが初期ブ
ロックでない場合には、Bに先行する全てのPについて
C_OUT[P]の積集合を求め、その結果とVERS
ION_OR[B]とALL_FLAG[B]との和集
合がC_IN[B]となる。一方、ベーシック・ブロッ
クBが初期ブロックである場合には、C_OUT[P]
がないので、VERSION_OR[B]とALL_F
LAG[B]との和集合がC_IN[B]となる。この
C_IN[B]にAppendix Bで説明している
forward処理を実施し、その結果とC_GEN
[B]の和集合がC_OUT[B]となる。
【0043】また、Appendix Dのステップ3
30も以下のように変更する。
【表6】 for (各ベーシック・ブロックについて実行順に命令を取り出す){ switch(命令){ 配列アクセス命令: その配列レンジ・チェックCに対して if (CがC_IN[B]からチェック済と判断できる){ if (C_IN[B]内のCを含む部分集合内に[対応するフラグ名]が [無し]の配列レンジ・チェックがある){ /* C_GENから流れてきた配列レンジ・チェックがある */ 配列レンジ・チェックCを除去; } else { [対応するフラグ名]の結果により配列レンジ・チェック Cを無効化するコードを生成する。 } } else { C_IN[B] += C; } break; 配列のベース変数 a の変更: for (全てのC∈ C_IN[B]){ if (Cの中に変更された配列ベース a による lb(a)またはub(a)が含まれる){ C_IN[B] -= C; } } break; インデックス v の変更: for (全てのC∈ C_IN[B]){ if (Cは変更されたインデックス v 又は v の式 f(v) で構成される){ if (インデックス v が i = i + c (cは正又は負の定数)で変更される){ v を v - c、又はf(v)をf(v - c)として置き換える。 } else { C_IN[B] -= C; } } } break; } }
【0044】Appendix Dの表30と異なるの
は、ベーシック・ブロックB内の配列アクセス命令を取
り出した時の処理である。ここではC_IN[B]で配
列レンジ・チェックCがチェック済みであると判断でき
る場合でも、もう一つの検査に従って場合分けを行う。
すなわち、C_IN[B]内の、Cが含まれる部分集合
がC_GEN[B]から加わった配列レンジ・チェック
である場合、すなわち、その部分集合の[対応するフラ
グ名]が[無し]である場合には、配列レンジ・チェッ
クCを除去し、そうでない場合には、その配列レンジ・
チェックCを[対応するフラグ名]のフラグが配列レン
ジ・チェックが成功したことを示している場合には無効
化するコードを生成する。
【0045】より具体的に、Mercedの述語(Pred
icate)付き命令を利用する場合を図3及び図4を用い
て説明する。ここでは、図3のように、命令1乃至3は
無条件に実行されるが、FLAG1が真(TRUE)で
あれば配列レンジ・チェックのためのコード1.1乃至
1.3を実行する。FLAG1が真でない場合又はコー
ド1.3を実行した後に、命令4以降を実行する。この
時、Mercedでは、図4のように命令を実行する。
すなわち、図4の太枠が1つの命令であって、命令内の
左のフィールドがFLAG1と書いてある命令はFLA
G1がTRUEの時に命令を実行し、FLASEの場合
には命令を実行しないことを意味している。左のフィー
ルドが空欄である場合には、その命令は無条件に実行さ
れる。なお、図4の各命令は、通常1行(3命令)を1
サイクルで実行されるが、ここでは図3の順番で1つず
つ実行される。
【0046】また、PowerPCのゼロサイクル・ブ
ランチ命令を利用する場合には、割り当てられたフラグ
がTRUEの時フラグに対応する配列レンジ・チェック
をスキップするコードを生成する。例えば割り当てられ
たフラグがBit5だとしたら次のようなコードを生成
してスキップする。 bbt 5, SKIP 配列レンジ・チェックのためのコード SKIP:bbtはBit「5」がTRUEだったらSKI
Pへジャンプし、そうでなければ、下の配列レンジ・チ
ェックのためのコードを実行するものである。
【0047】このようにして、ステップ160の処理が
不要な配列レンジ・チェックの除去の処理と共に実施さ
れる。
【0048】では、具体例をもってA.の処理を説明す
る。
【表7】 i = 0; while(i < n-2){ t = sub1[i] / diag[i]; diag[i + 1] -= t * sup1[i]; sup1[i + 1] -= t * sup2[i]; b [i + 1] -= t * b [i]; t = sub2[i] / diag[i]; sub1[i + 1] -= t * sup1[i]; diag[i + 2] -= t * sup2[i]; b [i + 2] -= t * b [i]; i++; } これは5重対角な連立方程式を解くアルゴリズムの一部
分を抜き出したものである。なお、lb(a)とは配列
aの下限値、ub(a)とは配列aの上限値を指してい
る。また、check( )とは括弧内の配列レンジ・チ
ェックが行われることを意味する。さらに、Java言
語では配列の下限は0と決まっているので、以下このこ
とを使用する。
【0049】ステップ110の処理を実施すると、VE
RSION_OR[B]は check(n-1 <= ub(diag)) check(n-1 <= ub(b)) check(n-2 <= ub(sub1)) check(n-2 <= ub(sup1)) check(n-3 <= ub(sub2)) check(n-3 <= ub(sup2)) となる。なお、ループ変数の範囲のチェックは、0 <= n
-3である。
【0050】なお、最適化を実施すると、
【表8】 i = 0; while(i < n-2){ check(i <= ub(sub1)); check(i <= ub(diag)); t = sub1[i] / diag[i]; check(i+1 <= ub(diag)); check(i <= ub(sup1)); diag[i + 1] -= t * sup1[i]; check(i+1 <= ub(sup1)); check(i <= ub(sup2)); sup1[i + 1] -= t * sup2[i]; check(i+1 <= ub(b)); b[i + 1] -= t * b[i]; check(i <= ub(sub2)); t = sub2[i] / diag[i]; check(i+1 <= ub(sub1)); sub1[i + 1] -= t * sup1[i]; check(i+2 <= ub(diag)); diag[i + 2] -= t * sup2[i]; check(i+2 <= ub(b)); b[i + 2] -= t * b[i]; i++; }
【0051】ステップ120の処理で、まず表8の結果
からVERSION_OR[B]のソートを行うと、以
下のようになる。 チェック命令 レンジチェック数 n-1 <= ub(diag) 3回 n-1 <= ub(b) 2回 n-2 <= ub(sub1) 2回 n-2 <= ub(sup1) 2回 n-3 <= ub(sub2) 1回 n-3 <= ub(sup2) 1回 これをステップ120の処理でプロセッサのフラグ4つ
(flag1からflag4とする)に割り振るとすると次のよう
になる。
【表9】 フラグ フラグに対応する配列レンジ・チェック レンジチェック数 flag1 0 <= n-3 && n-2 <= ub(sub1) && n-2 <= ub(sup1) 4回 flag2 0 <= n-3 && n-1 <= ub(diag) 3回 flag3 0 <= n-3 && n-1 <= ub(b) 2回 flag4 0 <= n-3 && n-3 <= ub(sub2) && n-3 <= ub(sup2) 2回
【0052】表9を用いてステップ130では、以下の
ようなコードが生成される。
【表10】 なお、
【表11】 flag1 = (n-2 <= ub(sub1) && n-2 <= ub(sup1) && 0 <= n-3); flag2 = (n-1 <= ub(diag) && 0 <= n-3); flag3 = (n-1 <= ub(b) && 0 <= n-3); flag4 = (n-3 <= ub(sub2) && n-3 <= ub(sup2) && 0 <= n-3); としてもよい。
【0053】ステップ150の処理を実施すると、
【表12】
【0054】最後にステップ160を実施すると、以下
のようになる。
【表13】 例えば「if (!flag3) check(i+2 <= ub(b));」がフラグ
を検査し且つフラグに割り当てられた配列レンジ・チェ
ックがチェック成功を示している場合にはcheck(i+2 <=
ub(b))を無視するコードである。
【0055】本発明はステップ140から明らかなよう
にバージョニングを用いない場合であっても適用可能で
ある。すなわち、表7は、以下のようになる。
【表14】
【0056】さらに、A.の処理はループでなくとも適
用可能であり、例えば表7のwhile文が無くとも、同じ
ようにフラグのチェックだけで実際の配列レンジ・チェ
ックを行わずに済み、高速化される場合もある。
【0057】B.副作用を起こす命令の存在を考慮せず
に配列レンジ・チェックをできるかぎりまとめる処理 A.の処理はプロセッサのフラグを上記のように使用で
きる場合に主に適用できる。また、バージョニングでき
ないような場合も存在する。本処理Bは処理Aが使用で
きないような場面で有効である。図5に本処理B.のフ
ローを示す。まず、本処理が適用される部分Aを複製
し、対応するプログラム部分Bを作成し且つ記憶装置に
格納する(ステップ410)。次に、配列レンジ・チェ
ックの最適化処理(Appendix C)を施す。但
し、Appendix Cに述べられた処理は、副作用
を起こす可能性のある命令が存在するか否かを考慮して
行われるが、ここでは、このような副作用を起こす可能
性のある命令の存在は考慮しない。Appendix
Cと異なる点は、表25及び表26においてC_GEN
[B]又はC_OUT[B]をφにする処理を行わない
という点である。その後に、プログラム部分Aについて
配列レンジ・チェックの除去処理を実施する(ステップ
430)。この除去処理は、Appendix Dで説
明された処理である。そして、プログラム部分A内に残
った配列レンジ・チェックに失敗した場合にその失敗し
た配列レンジ・チェックを含むベーシック・ブロックに
対応する、プログラム部分B内のベーシック・ブロック
にジャンプする条件分岐命令を生成し且つ記憶装置に格
納する(ステップ440)。その後全体のコントロール
フロー・グラフを再構成し、その際本処理適用部分のエ
ントリ・ポイントをAに設定する(ステップ450)。
本願に関係する部分はこれで終わるが、この後に再構成
したコントロールフロー・グラフを基にA及びBについ
て従来から行われているレジスタ割り当て及びコード生
成を行う。
【0058】以上のような処理を実施すると、副作用を
起こす命令を考慮せずに配列レンジ・チェックを集める
ことができるため、配列レンジ・チェック数を減らすこ
とができる。そのため、配列レンジ・チェックを失敗す
ることによって生じる例外が実行時には発生しない場
合、Aのみ実行されるために実行が高速化される。ま
た、例外が実際に起こる場合にも配列レンジ・チェック
の最適化を行わないBのコードが実行され、正しい場所
で例外が起こるために副作用を起こす命令に関する問題
が生じない。また、ループ内で例外が起こる場合(例え
ば、配列に初期値を順番に入力する場合に、配列のレン
ジを超えるような回数のループを設け、配列のレンジを
超えるような配列アクセスを生じさせて、初期値入力を
終了させるようなプログラムの場合)でも実際に例外が
起こるループの最後の実行時のみBに制御が移る。よっ
て、それまでのループの実行はA内で動作するため、ル
ープ全体の実行速度を上げることができる。
【0059】では、上記処理の適用例を示す。以下のよ
うなプログラムに本処理を適用する。
【表15】
【0060】表15はiの範囲が定まらないので、ルー
プのバージョニングを行うことができない。このプログ
ラムに対して、Appendix Cの最適化処理を行
うとcase 1乃至3はその配列アクセスが副作用を
生じる可能性があるので、これを越えて配列レンジ・チ
ェックをまとめることができない。ステップ410乃至
ステップ430を実行すると、以下のようになる。
【表16】 なお、例えばcase 3の場合、Appendix
Cの最適化処理を実施した場合と、処理B.で修正した
最適化処理を実施する場合とでは以下の差が出る。 なお、括弧内の意味は、左から順番に配列ベース変数、
インデックスの変数の項、最小定数インデックス、最大
定数インデックス変数である。最適化処理で最終的に使
用されるのはC_IN[B]である。処理B.の方が、
最大定数インデックス変数が大きくなっているので、多
くの配列インデックスがまとめられる。この後、不要な
配列インデックスの除去の処理でも、C_IN[B]が
計算される。case 3のC_IN[B]の場合に
は、上の結果と同じになり、プログラム部分Aのi+1
からi+4の間の配列レンジ・チェックは除去される。
【0061】最後に、ステップ440以降の処理を実施
すると、以下のようになる。
【表17】 /* Entry Point */ i = 0; while(TRUE){ check(i <= ub(a)); switch(a[i]){ case 1: if (i+2 > ub(a)) goto EXACT_CHECK1; --- (1) a[i+1] = 5; i += 2; break; case 2: if (i+3 > ub(a)) goto EXACT_CHECK2; --- (2) a[i+1] = 10; a[i+2] = 20; i += 3; break; case 3: if (i+4 > ub(a)) goto EXACT_CHECK3; --- (3) a[i+1] = 100; a[i+2] = 200; a[i+3] = 300; i += 4; break; default: System.err.println("error!"); case 0: return; } } return; /* (1),(2),(3)について実際に例外を発生させる部分 */ i = 0; while(TRUE){ check(i <= ub(a)); switch(a[i]){ case 1: EXACT_CHECK1: --- (4) check(i+1 <= ub(a)); a[i+1] = 5; i += 2; break; case 2: EXACT_CHECK2: --- (5) check(i+1 <= ub(a)); a[i+1] = 10; check(i+2 <= ub(a)); a[i+2] = 20; i += 3; break; case 3: EXACT_CHECK3: --- (6) check(i+1 <= ub(a)); a[i+1] = 100; check(i+2 <= ub(a)); a[i+2] = 200; check(i+3 <= ub(a)); a[i+3] = 300; i += 4; break; default: System.err.println("error!"); case 0: return; } } return; (1)乃至(3)がステップ440で生成されるコード
である。表16とは、配列レンジ・チェックが失敗した
ら、プログラム部分Bにジャンプするということで、条
件が不等式が異なっている。
【0062】C.ループ内のどの実行経路を通っても必
ず行われる配列アクセスに対する配列レンジ・チェック
情報を使用してバージョニングする処理 ループ内のどの実行経路を通っても必ず行われる配列ア
クセスに対する配列レンジ・チェック情報を使ってバー
ジョニングをすると、実際に配列レンジ・チェックで例
外が発生する場合以外は厳密な配列レンジ・チェックを
行うバージョンに遷移するのを防ぐことができる。以
下、本方法の処理フローを図6を用いて説明する。
【0063】まず、バージョニングを行うループ内のど
の実行経路を通過しても必ず行われる配列アクセスに対
する配列レンジ・チェック集合情報VERSION_A
ND[B]を、バージョニングを行うループのエントリ
・ポイントで生成する(ステップ510)。なお、この
VERSION_AND[B]は、記憶装置に記憶され
る。そして、このVERSION_AND[B]を用い
てバージョニング・ヘッダを生成し且つ記憶装置に格納
する(ステップ520)。この後、バージョンニング・
ヘッダにおける配列レンジ・チェックが成功した場合の
バージョンと、失敗した場合のバージョンとを生成し、
記憶装置に格納する(ステップ530)。これらは、こ
の時点では実質的に同一である。但し、先ほど述べたV
ERSION_AND[B]は成功した場合のバージョ
ンのループのエントリ・ポイントで有効であり、失敗し
た場合のバージョンの場合にはφである。このような状
態で、不要な配列レンジ・チェックの除去処理を実施す
る(ステップ540)。このようにすると、バージョニ
ング・ヘッダの配列レンジ・チェックが成功した場合の
バージョンではどの実行経路を通過しても必ず行われる
配列アクセスに対する配列レンジ・チェックは除去され
るが、失敗した場合のバージョンでは重複する配列レン
ジ・チェックのみが除去されるのみであり、成功した場
合のバージョンの実行速度が速くなる。
【0064】図6の処理では、バージョニング・ヘッダ
の配列レンジ・チェックが成功した場合のバージョンだ
けでなく失敗した場合のバージョンでも配列レンジ・チ
ェックの除去処理を行っているが、成功した場合のバー
ジョンのみ除去処理を行ってもよい。成功した場合のバ
ージョンは配列レンジ・チェックが大幅に減少するの
で、実行速度が速くなる。
【0065】では、図6の各ステップを詳しく説明す
る。まず、ステップ510では、VERSION_AN
D[B]を求める。A.の処理ではVERSION_O
R[B]を求めていたが、ここでは、A.の処理の和集
合を取っていたある部分で積集合を取る。
【0066】ステップ510の処理(1)では、原則と
して配列インデックス又は配列ベースを変更する命令に
関わる配列レンジ・チェックを本ステップの対象外とし
て取り扱いながら、ベーシック・ブロックの先頭におけ
る、配列レンジ・チェックの集合C_GEN[B]を、
実行とは逆順に収集する。但し、配列インデックス変数
をv=v+c(cは正又は負の定数)のように変更する
場合には、本ステップの対象外とはしないで、集合情報
C_GEN[B]内の配列インデックスの式f(v)を
f(v+c)として再計算し、置き換える。表3の擬似
コードは本処理(1)に用いることができる。
【0067】次にステップ510の処理(2)について
説明する。このステップ510の処理(2)では、上で
収集したC_GEN[B]を用いて、次の式によるデー
タ・フロー解析を実行し、C_IN_AND[B]を求
める。 S∈ Succ(B) である全てのSについて、 C_OUT_AND[B] = ∩ C_IN_AND[S] C_IN_AND[B] = C_GEN[B] ∪ backward(C_OUT_AND[B], B) Succ(B)は、Bの直後に来る全てのベーシック・ブロッ
クの意味である。上の式は以下のことを示している。あ
るベーシック・ブロックBの後端における、配列レンジ
・チェックの集合C_OUT_AND[B]には、S∈
Succ(B)である全てのベーシック・ブロックSの先頭に
おける、配列レンジ・チェックの集合C_IN_AND
[S]の積集合を計算した結果を代入する。また、C_
OUT_AND[B]は後に述べる処理により、ベーシ
ック・ブロックBにおいて行われる配列インデックスに
対する変更に応じて所定の修正が行われ、新たに集合ba
ckward(C_OUT_AND[B], B)となる。この集合backward(C_
OUT_AND[B], B)及び先に求めたC_GEN[B]の和集
合がC_IN_AND[B]となる。最終的に必要なの
はこのC_IN_AND[B]である。
【0068】backward(C_OUT_AND[B], B)の処理はAp
pendix Aと同じである。但し、Appendi
x AではC_IN_OR[B]であったが、これをC
_IN_AND[B]に置き換える。
【0069】ステップ510の処理(3)は処理(2)
で作成したC_IN_AND[B]を用いて次の式によ
るデータ・フロー解析を行い、FLAG_IN[B]を
作成する。P∈Pred(B)である全てのPについて FLAG_IN[B] = ∩ FLAG_OUT[P] FLAG_OUT[B] = C_IN_AND[B] ∪ forward(FLAG_IN[B],
B) Pred(B)は、Bの直前に来る全てのベーシック・ブロッ
クの意味である。上記の式は以下のことを意味してい
る。ベーシック・ブロックBの直前の全てのベーシック
・ブロックPの後端の集合FLAG_OUT[P]の積
集合が集合FLAG_IN[B]となる。そして、この
集合FLAG_IN[B]をforward(FLAG_IN[B], B)で
処理し、その結果と処理(2)で求めた集合C_IN_
AND[B]との和集合が和集合FLAG_OUT
[B]となる。
【0070】forward(FLAG_IN[B], B)の処理はAppe
ndix Bと同じである。
【0071】ステップ510の処理(4)では、次の式
を全てのベーシック・ブロックについて行い、C_IN
_AND[B]内の不要な配列集合情報を削除する。C
_IN_AND[B]=C_IN_AND[B]−FL
AG_IN[B]
【0072】ステップ510の処理(5)では、処理
(4)で作成したC_IN_AND[B]を用いて、ル
ープ内で不変の配列アクセス、及びループ変数の取り得
る範囲が特定できる配列アクセスに関してはループ変数
の取り得る範囲を基に、ループのエントリ・ポイントに
おける配列レンジ・チェック集合情報VERSION_
AND[B]を計算する。このVERSION_OR
[B]がバージョニング・ヘッダー内の配列レンジ・チ
ェックとなる。例えば、ループ変数がiであって、取り
得る範囲が1以上n未満であることが分かれば、ub
(a)についてはi=n−1である場合についてチェッ
クし、lb(a)についてはi=1であるとしてVER
SION_AND[B]を作成する。このVERSIO
N_AND[B]、ステップがステップ510における
出力となる。
【0073】次に、ステップ520であるが、A.の処
理でVERSION_OR[B]を用いてバージョニン
グ・ヘッダを作成したが、それと同じで、ここではVE
RSION_AND[B]を用いてバージョニング・ヘ
ッダを作成する。
【0074】ステップ530の処理は、実質的にバージ
ョニング対象となるループのコピーを行うものである。
但し、バージョニング・ヘッダの配列レンジ・チェック
が失敗した場合のバージョンについては、VERSIO
N_AND[B]は空である。
【0075】ステップ540では、不要な配列レンジ・
チェックの除去を実施する。これは基本的には、App
endix Dに記載されている配列レンジ・チェック
の処理を実施する。但し、図14のステップ320の処
理は以下のように変更する。すなわち、ステップ320
で次の式によるデータ・ブロー解析を行う。全てのP∈
Pred(B)について、Bが初期ブロックでない場合、 C_IN[B] = (∩ C_OUT[P])∪VERSION_AND[B] Bが初期ブロックである場合、 C_IN[B] = VERSION_AND[B] C_OUT[B] = C_GEN[B] ∪ forward(C_IN[B], B) これらの説明を少ししておくと、ベーシック・ブロック
Bに先行する全てのベーシック・ブロックPについて、
もしベーシック・ブロックBが初期ブロックでなけれ
ば、C_OUT[P]の積集合を求め、その結果とVE
RSION_AND[B]との和集合をC_IN[B]
として計算する。一方、ベーシック・ブロックが初期ブ
ロックである場合には、C_IN[B]はVERSIO
N_AND[B]と同じである。そして、C_OUT
[B]はC_GEN[B]とforward(C_IN[B], B)で計
算される。forward(C_IN[B], B)は、Appendix
Bの処理で計算できる。但し、FLAG_IN[B]をC_IN[B]に
置き換える。
【0076】これ以外の処理はAppendix Dと
同じである。よって、この処理が終了したところで、バ
ージョニング・ヘッダにおける配列レンジ・チェックが
成功した場合のバージョンは、バージョニングを行うル
ープ内のある実行経路でしか実行されない配列レンジ・
チェックについては残るが、他の配列レンジ・チェック
はほとんど除去されるので、配列レンジ・チェックの回
数が減少する。一方、失敗した場合のバージョンでは、
重複する配列レンジ・チェックのみ除去される。
【0077】以上の処理の具体的例を以下に説明する。
例えば、以下のようなプログラムに処理を実施する。
【表18】
【0078】ステップ510を実施すると、VERSI
ON_AND[B]は以下のようになる。 よって、ステップ520のバージョニング・ヘッダは以
下のようになる。
【0079】ステップ530及びステップ540を実施
すると以下のようになる。
【表19】
【0080】表19を見ればよく分かるように、バージ
ョニング・ヘッダにおける配列レンジ・チェックが成功
した場合には、ループ内の配列レンジ・チェックは1つ
になる。一方、失敗した場合には、多数の配列レンジ・
チェックが必要となっている。
【0081】本処理C.は処理A.と組み合わせて実施
することも可能である。その例が表19の(1)であ
る。このためには、2つの方法が考えられる。1つの方
法は、ステップ540の不要な配列レンジ・チェックの
除去処理後に、バージョニング・ヘッダにおける配列レ
ンジ・チェックが成功した場合のバージョン内に残った
配列レンジ・チェックの結果をフラグに格納するコード
を生成し(ステップ610:図7)、当該残った配列レ
ンジ・チェックに割り当てられたフラグを検査し且つ当
該フラグが配列レンジ・チェック成功を示している場合
には当該残った配列レンジ・チェックを無効化するコー
ドを生成する(ステップ620)。生成されたコードは
記憶装置に格納される。これにより、表19の(1)の
ようなコードが生成されるようになる。
【0082】もうひとつの方法は結果は同じであるが、
バージョニングを行うループ内のいずれの実行経路を通
過したとしても必ず行われる配列アクセスに対する配列
レンジ・チェックに限定せずに配列レンジ・チェックを
収集してVERSION_OR[B]を計算し(ステッ
プ660:図8)、VERSION_OR[B]−VE
RSION_AND[B]をフラグに割り当てる(ステ
ップ670)。そして、割り当てに従って配列レンジ・
チェックの結果をフラグに格納するコードを生成する
(ステップ680)。フラグを検査し且つ当該フラグが
配列レンジ・チェック成功を示している場合にはフラグ
に割り当てられた配列レンジ・チェックを無効化するコ
ードを生成する(ステップ690)。VERSION_
OR[B]及び生成されたコードは記憶装置に格納され
る。
【0083】また、VERSION_OR[B]を用い
て3バージョンに分けることも可能である。この場合に
は、以下のような処理を行う(図9)。まず、VERS
ION_OR[B]を求め且つ記憶装置に格納する(ス
テップ710)。そして、VESION_OR[B]−
VERSION_AND[B]を求め、これにより第2
のバージョニング・ヘッダを生成し且つ記憶装置に格納
する(ステップ720)。この第2のバージョニング・
ヘッダによる配列レンジ・チェックが成功した場合に実
行するバージョンを生成し且つ記憶装置に格納する(ス
テップ730)。但し、VERSION_OR[B]を
用いて配列レンジ・チェックの除去を行う。これはステ
ップ540(図6)におけるVERSION_AND
[B]をVERSION_OR[B]にして実施する。
このようなコードを生成し、以下のようにまとめる。な
お、本処理はVERSION_AND[B]がφでな
く、且つVERSION_AND[B]とVERSIO
N_OR[B]が同じでない場合に機能する。
【表20】 < VERSION_AND[B] を使ったバージョニング・ヘッダ > ---(1) < (1)が成功したとき > < (VERSION_OR[B] - VERSION_AND[B]) を使った バージョニング・ヘッダ > --- (2) < (2) が成功した場合のバージョン。 但し、VERSION_OR[B] を基にして配列レンジ・チェック除去。 >---(3) < (2) が失敗した場合のバージョン。 但し、VERSION_AND[B] を基にして配列レンジ・チェック除去。 >---(4) < (1)が失敗した場合のバージョン。 但し、VERSION_AND[B]がφとして配列レンジ・チェック除去。 >---(5)
【0084】このように、図9では表20の(2)及び
(3)を求める。残りの部分は、図6で求められている
ので、表20のようになるように全体をまとめる必要は
ある。
【0085】表18を図6及び図9で処理すると、以下
のようになる。
【表21】 total = 0; if (s <= n-1 && s >= lb(a) && n-1 <= ub(a) && k >= lb(c) && k <= ub(c) && s >= lb(b) && n-1 <= ub(b)) { /* VERSION_OR[B]-VERSION_AND[B]によるヘッダ */ if (s-2 >= lb(a)){ /* VERSION_OR[B]に基づく除去によるバージョン */ for (i = s; i < n; i++){ if (a[i] == 0) { a[i] = a[i-1] + a[i-2]; } total += a[i] + c[k]; b[i] = total; } } else { /* VERSION_AND[B]に基づく除去によるバージョン */ for (i = s; i < n; i++){ if (a[i] == 0) { check(i-2 >= lb(a)); a[i] = a[i-1] + a[i-2]; } total += a[i] + c[k]; b[i] = total; } } } else { for (i = s; i < n; i++){ check(i >= lb(a)); check(i <= ub(a)); if (a[i] == 0) { check(i-2 >= lb(a)); a[i] = a[i-1] + a[i-2]; } check(k >= lb(c)); check(k <= ub(c)); total += a[i] + c[k]; check(i >= lb(b)); check(i <= ub(b)); b[i] = total; } }
【0086】表21を見ればすぐに分かるが、コード・
サイズがほぼ3倍になってしまう。よって、このように
3バージョンにするためには、ループ内の処理の内容が
簡単なものでなければならない。
【0087】本処理C.はさらにバージョニングを実施
しないような場合に、処理A.と組み合わせて実施する
ことができる。その処理を図10を用いて説明する。先
に説明したVERSION_OR[B]及びVERSI
ON_AND[B]を求め且つ記憶装置に格納する(ス
テップ810)。そして、VERSION_AND
[B]に1つのフラグを割り当て、VERSION_O
R[B]−VERSION_AND[B]に図2のステ
ップ120の処理で1又は複数のフラグを割り当てる
(ステップ820)。以上の割り当てに従って、各フラ
グに割り当ての配列レンジ・チェックの結果を格納する
コードを生成し且つ記憶装置に格納する(ステップ83
0)。そして、不要な配列レンジ・チェックを除去する
処理を図2のステップ160に従って行う(ステップ8
40)。これによって、バージョニングを行わない場合
でも処理を高速化することができる。
【0088】表18に図10の処理を実施すると、以下
のようになる。
【表22】
【0089】なお、上ではループのバージョニングを説
明したが、ループでない部分についても処理C.を適用
することもできる。
【0090】
【効果】より配列レンジ・チェックの回数を減らし、実
行速度を上げることができた。
【0091】また、複数の配列レンジ・チェックをまと
めた広い配列レンジ・チェックを行い、この広い配列レ
ンジ・チェックが失敗した場合に厳密な配列レンジ・チ
ェックを行うという2段階のチェックを行うことにより
実行時の配列レンジ・チェックの回数を減らし、高速な
実行を可能にする方法を提供することもできた。
【0092】さらに、ループ内のどの実行経路を通って
も必ずアクセスされる配列アクセス情報を用いてバージ
ョニングを実施する方法を提供することもできた。
【0093】Appendix A backward(C_OUT_OR[B], B)は以下のような擬似コードに
て求められる。
【表23】 backward(C_OUT_OR[B], B){ T = 0; for (各配列レンジ・チェック C ∈ C_OUT_OR[B]) { case C of lb <= v: case AFFECT(B, v) of unchanged: T = T ∪ { lb <= v } increment: if 加算する値 c が定数 then T = T ∪ { lb <= v + c } /* そうでなければTには入れない */ decrement: if 減算する値 c が定数 then T = T ∪ { lb <= v - c } else T = T ∪ { lb <= v } multiply: /* Tには入れない */ div > 1: T = T ∪ { lb <= v } div < 1: /* Tには入れない */ changed: /* Tには入れない */ end case v <= ub: case AFFECT(B, v) of unchanged: T = T ∪ { v <= ub } increment: if 加算する値 c が定数 then T = T ∪ { v + c <= ub } else T = T ∪ { v <= ub } decrement: if 減算する値 c が定数 then T = T ∪ { v - c <= ub } /* そうでなければTに入れない */ multiply: T = T ∪ { v <= ub } div > 1: /* Tには入れない */ div < 1: T = T ∪ { v <= ub } changed: /* Tには入れない */ end case lb <= f(v): case AFFECT(B, v) of unchanged: T = T ∪ { lb <= f(v) } increment: if f(v)が単調な関数であり且つ 加算する値 c が定数 then T = T ∪ { lb <= f( v + c ) } else if vが増加するとf(v) は減少する then T = T ∪ { lb <= f(v) } decrement: if f(v)が単調な関数であり且つ 減算する値 c が定数 then T = T ∪ { lb <= f( v - c ) } else if vが減少するとf(v)も減少する then T = T ∪ { lb <= f(v) } multiply, div < 1: if vが増加するとf(v)は減少する then T = T ∪ { lb <= f(v) } div > 1: if vが減少するとf(v)も減少する then T = T ∪ { lb <= f(v) } changed: /* Tには入れない */ end case f(v) <= ub: case AFFECT(B, v) of unchanged: T = T ∪ { f(v) <= ub } increment: if f(v)は単調な関数であり且つ 加算する値 c が定数 then T = T ∪ { f( v + c ) <= ub } else if vが増加するとf(v)も増加 then T = T ∪ { f(v) <= ub } decrement: if f(v)が単調な関数であり且つ 減算する値 c が定数 then T = T ∪ { f( v - c ) <= ub } else if vが減少するとf(v)は増加 then T = T ∪ { f(v) <= ub } multiply, div < 1: if vが増加するとf(v)も増加する then T = T ∪ { f(v) <= ub } div > 1: if vが減少するとf(v)は増加する then T = T ∪ { f(v) <= ub } changed: /* Tには入れない */ end case end case } return(T) }
【0094】backward(C_OUT_OR[B], B)の最終的な出力
はTである。backward(C_OUT_OR[B], B)はC_OUT_
OR[B]に含まれる配列レンジ・チェックの内容によ
り大きく4つの部分に分けられる。すなわち、配列イン
デックス変数vについて、lb≦vの場合及びv≦ub
の場合、配列インデックスf(v)について、lb≦f
(v)の場合及びf(v)≦ubの場合である。そし
て、それぞれの場合において、配列インデックス変数v
に対する操作(表23におけるAFFECT(B,v)。Bは処理
を行っているベーシック・ブロックを示している。)に
よってさらに場合分けされる。以下、それぞれについて
説明する。
【0095】(1)lb≦vの場合 配列インデックス変数vに対する操作が何も無い場合
(unchanged)には、lb≦vをそのまま配列レンジ・
チェックの集合であるTに入れる。なお、配列インデッ
クスが定数の場合にはこのunchangedに含まれる。配列
インデックス変数vを増加させる操作の場合(incremen
t)、加算する値cが定数であるかどうか判断する。も
し加算する値cが定数であれば、Tにはlb≦v+cを
入れる。これ以外のvを増加させる操作の場合には、本
発明では取り扱わないので、その配列レンジ・チェック
をTには入れない。配列インデックス変数vを減少させ
る操作の場合(decrement)、減算する値cが定数であ
るかどうか判断する。もし減算する値cが定数であれ
ば、Tにlb≦v−cを入れる。これ以外のvを減少さ
せる操作の場合には、lb≦vをTに入れる。配列イン
デックス変数vが掛け算される場合(multiply)、本発
明では取り扱うことができないので、その配列レンジ・
チェックをTには入れない。配列インデックス変数vが
1より大きな値で割り算される場合(div>1)には、l
b≦vをそのままTに入れる。配列インデックス変数v
が1より小さな値で割り算される場合(div<1)には、
本発明では取り扱うことができないので、その配列レン
ジ・チェックをTには入れない。以上述べた操作以外の
操作の場合(changed)、本発明では取り扱うことがで
きないので、その配列レンジ・チェックをTには入れな
い。
【0096】(2)v≦ubの場合 配列インデックス変数vに対する操作が何も無い場合
(unchanged)には、Tにv≦ubを入れる。配列イン
デックス変数vを増加させる操作の場合(incremen
t)、加算する値cが定数であるならばv+c≦ubを
Tに入れる。一方、それ以外のvを増加させる操作の場
合にはv≦ubをTに入れる。配列インデックス変数v
を減少させる操作の場合(decrement)、減算する値c
が定数であるならばv−c≦ubをTに入れる。それ以
外のvを減少させる操作の場合にはその配列レンジ・チ
ェックをTには入れない。配列インデックス変数vが掛
け算される場合(multiply)、その配列レンジ・チェッ
クをTには入れない。配列インデックス変数vを1より
大きい値で割り算する場合(div>1)、その配列レンジ
・チェックをTには入れない。配列インデックス変数v
が1より小さい値で割り算する場合(div<1)、v≦u
bをTに入れる。以上述べた以外の操作の場合(change
d)、その配列レンジ・チェックをTには入れない。
【0097】(3)lb≦f(v)の場合 配列インデックス変数vに対する操作が何も無い場合
(unchanged)には、Tにlb≦f(v)を入れる。配
列インデックス変数vを増加させる操作の場合(increm
ent)、f(v)が単調な関数(monotone)であって且つ
加算する値cが定数であるならば、lb≦f(v+c)
を入れる。また、そうでない場合であっても、vが増加
するとf(v)が減少するような場合には、lb≦f
(v)をTに入れる。配列インデックス変数vを減少さ
せる操作の場合(decrement)、f(v)が単調な関数
であって且つ減算する値cが定数であるならば、lb≦
f(v−c)をTに入れる。そうでない場合であって
も、vが減少するとf(v)が減少する場合には、lb
≦f(v)をTに入れる。配列インデックス変数vが掛
け算される場合及び1より小さい値で割り算される場合
(mutiply,div<1)、vが増加するとf(v)が減少す
るならばlb≦f(v)をTに入れる。配列インデック
スvを1より大きな値で割り算する場合(div>1)、l
b≦f(v)をTに入れる。以上述べた以外の操作の場
合(changed)、その配列レンジ・チェックをTには入
れない。
【0098】(4)f(v)≦ubの場合 配列インデックス変数vに対する操作が何もない場合
(unchanged)には、f(v)≦ubをTに入れる。配
列インデックス変数vを増加させる操作の場合(increm
ent)、f(v)が単調な関数であって且つ加算する値
cが定数ならば、f(v+c)≦ubをTに入れる。ま
た、そうでない場合であっても、vが増加するとf
(v)が増加する場合には、f(v)≦ubをTに入れ
る。配列インデックス変数vを減少させる操作の場合、
f(v)が単調な関数であって且つ減算する値cが定数
ならば、f(v−c)≦ubをTに入れる。そうでない
場合であっても、vが減少するとf(v)は増加するな
らば、f(v)≦ubをTに入れる。配列インデックス
変数vを掛け算する場合及び1より小さな値で割り算す
る場合(multiply,div <1)、vが増加するとf(v)
も増加するならば、f(v)≦ubをTに入れる。配列
インデックスvを1より大きな値で割り算する場合(di
v>1)、f(v)≦ubをTに入れる。以上述べた以外
の操作の場合(unchanged)、その配列レンジ・チェッ
クをTに入れない。
【0099】Appendix B forward(FLAG_IN[B], B)は以下のような擬似コードにて
求められる。
【表24】 forward(FLAG_IN[B], B){ T = 0; for each check C ∈ C_IN[B] do case C of lb <= v: case AFFECT(B, v) of unchanged: T = T ∪ { lb <= v } increment: if 加算する値 c が定数 then T = T ∪ { lb <= v - c } else T = T ∪ { lb <= v } decrement: if 減算する値 c が定数 then T = T ∪ { lb <= v + c } /* そうでなければTに入れない */ multiply: T = T ∪ { lb <= v } div > 1: /* Tに入れない */ div < 1: T = T ∪ { lb <= v } changed: /* Tに入れない */ end case v <= ub: case AFFECT(B, v) of unchanged: T = T ∪ { v <= ub } increment: if 加算する値 c が定数 then T = T ∪ { v - c <= ub } /* そうでなければTに入れない */ decrement: if 減算する値 c が定数 then T = T ∪ { v + c <= ub } else T = T ∪ { v <= ub } multiply: /* Tには入れない */ div > 1: T = T ∪ { v <= ub } div < 1: /* Tには入れない */ changed: /* Tには入れない */ end case lb <= f(v): case AFFECT(B, v) of unchanged: T = T ∪ { lb <= f(v) } increment: if f(v)が単調な関数 and 加算する値 c が定数 then T = T ∪ { lb <= f( v - c ) } else if vが増加するとf(v)も増加 then T = T ∪ { lb <= f(v) } decrement: if f(v)が単調な関数 and 減算する値 c が定数 then T = T ∪ { lb <= f( v + c ) } else if vが減少するとf(v)が増加 then T = T ∪ { lb <= f(v) } /* そうでなければTに入れない */ multiply, div < 1: if vが増加するとf(v)も増加 then T = T ∪ { lb <= f(v) } div > 1: if vが減少するとf(v)は増加 then T = T ∪ { lb <= f(v) } changed: /* Tに入れない */ end case f(v) <= ub: case AFFECT(B, v) of unchanged: T = T ∪ { f(v) <= ub } increment: if f(v)が単調な関数 and 加算する値 c が定数 then T = T ∪ { f( v - c ) <= ub } else if vが増加するとf(v)は減少 then T = T ∪ { f(v) <= ub } decrement: if f(v)が単調な関数 and 減算する値 c が定数 then T = T ∪ { f( v + c ) <= ub } else if vが減少するとf(v)も減少 then T = T ∪ { f(v) <= ub } /* そうでなければTに入れない */ multiply, div < 1: if vが増加するとf(v)は減少 then T = T ∪ { f(v) <= ub } div > 1: if vが減少するとf(v)も減少 then T = T ∪ { f(v) <= ub } changed: /* Tに入れない */ end case end case } return(T) }
【0100】forward(FLAG_IN[B], B)の最終的な出力は
Tである。forward(FLAG_IN[B], B)はFLAG_IN
[B]に含まれる配列レンジ・チェックの形式により大
きく4つの部分に分けられる。すなわち、配列インデッ
クス変数vについて、lb≦v(配列の下限)の形式の
場合、v≦ub(配列の上限)の場合、lb≦f(v)
の場合、f(v)≦ubの場合である。そして、それぞ
れの場合の中で、配列インデックス変数vに対する操作
(AFFECT(B, v))によってさらに場合分けされる。以下
それぞれの場合について説明する。
【0101】(1)lb≦vの場合 配列インデックス変数vに何等の操作も実施しない場合
(unchanged)には、lb≦vをそのままTに入れる。
配列インデックス変数vを増加させる操作を実施する場
合(increment)、加算する値cが定数であるならばl
b≦v−cをTに入れる。もしcが定数でない場合には
lb≦vをTに入れる。配列インデックス変数vを減少
させる操作を実施する場合(decrement)、減算する値
cが定数であるならばlb≦v+cをTに入れる。cが
定数でなければ、その配列レンジ・チェックをTには入
れない。配列インデックス変数vを掛け算する場合(mu
ltiply)には、lb≦vをTに入れる。配列インデック
ス変数vを1より大きい値で割り算する場合(div>1)
には、その配列レンジ・チェックをTに入れない。配列
インデックス変数vを1より小さな値で割り算する場合
(div<1)には、lb≦vをTに入れる。以上述べた操
作以外の操作を配列インデックス変数vに行う場合(ch
anged)には、その配列レンジ・チェックをTには入れ
ない。
【0102】(2)v≦ubの場合 配列インデックス変数vに何等の操作も実施しない場合
(unchanged)には、v≦ubをTに入れる。配列イン
デックス変数vを増加させる操作を実施する場合(incr
ement)には、加算する値cが定数であるならばv−c
≦ubをTに入れる。cが定数でない場合にはその配列
レンジ・チェックをTには入れない。配列インデックス
変数vを減少させる操作を実施する場合(decrement)
には、減算する値cが定数であるならばv+c≦ubを
Tに入れる。cが定数でない場合にはv≦ubをTに入
れる。配列インデックス変数vを掛け算する場合(mult
iply)には、その配列レンジ・チェックをTには入れな
い。配列インデックス変数vを1より大きな値で割り算
する場合(div>1)には、v≦ubをTに入れる。配列
インデックス変数vを1より小さな値で割り算する場合
(div<1)には、その配列レンジ・チェックをTには入
れない。以上述べた操作以外の操作を配列インデックス
変数vに行う場合(changed)には、その配列レンジ・
チェックをTには入れない。
【0103】(3)lb≦f(v)の場合 配列インデックス変数vに何等の操作も実施しない場合
(unchanged)には、lb≦f(v)をそのままTに入
れる。配列インデックス変数vを増加させる操作を実施
する場合(increment)には、f(v)が単調な関数で
あり且つ加算する値cが定数であれば、lb≦f(v−
c)をTに入れる。この条件が当てはまらない場合であ
ってvが増加するとf(v)も増加するならば、lb≦
f(v)をTに入れる。配列インデックス変数vを減少
させる操作を実施する場合(decrement)には、f
(v)が単調な関数であって減算する値cが定数なら
ば、lb≦f(v+c)をTに入れる。上の条件が満た
されない場合であってvが減少するとf(v)が増加す
る場合には、lb≦f(v)をTに入れる。そうでない
場合には、その配列レンジ・チェックをTには入れな
い。配列インデックス変数vを掛け算する場合(multip
ly)及び1より小さな値で割り算する場合(div<1)、
vが増加するとf(v)も増加するならば、lb≦f
(v)をTに入れる。配列インデックス変数vを1より
大きな値で割り算する場合(div>1)には、vが減少す
るとf(v)が増加するならば、lb≦f(v)をTに
入れる。以上の操作以外の操作を配列インデックス変数
vに施す場合(changed)には、その配列レンジ・チェ
ックをTには入れない。
【0104】(4)f(v)≦ubの場合 配列インデックス変数vに何等の操作も施さない場合
(unchanged)には、f(v)≦ubをそのままTに入
れる。配列インデックス変数vを増加させる操作を実施
する場合(increment)には、f(v)が単調な関数で
あって加算する値cが定数ならば、f(v−c)≦ub
をTに入れる。上の条件が満たされない場合には、vが
増加するとf(v)が減少するならば、f(v)≦ub
をTに入れる。配列インデックス変数vを減少させる操
作を実施する場合(decrement)には、f(v)が単調
な関数であって減算する値cが定数ならば、f(v+
c)≦ubをTに入れる。上の条件が満たされない場合
には、vが減少するとf(v)も減少するならば、f
(v)≦ubをTに入れる。そうでなければ、その配列
レンジ・チェックをTには入れない。配列インデックス
vに掛け算を実施する場合(multiply)及び1より小さ
な値で割り算する場合(div<1)、vが増加するとf
(v)が減少するならば、f(v)≦ubをTに入れ
る。配列インデックス変数vを1より大きな値で割り算
する場合には、vが減少するとf(v)も減少するなら
ば、f(v)≦ubをTに入れる。以上の操作以外の操
作を実施する場合(changed)には、その配列レンジ・
チェックをTには入れない。
【0105】Appendix C 配列レンジ・チェックの最適化処理を以下に説明する。
概要を図11に示す。まず、各ベーシック・ブロック内
において、実行とは逆順に、所定の条件に従ってC_G
EN[B]を収集する(ステップ210)。収集結果
は、記憶装置に記憶される。そして、プログラムにおけ
るデータ・フロー解析の順番で、処理中のベーシック・
ブロック中に副作用を生じるような命令が含まれている
か否かの情報を用い且つ第2の条件に従ってC_GEN
[B]を伝搬させ、各ベーシック・ブロックにおけるC
_OUT[B]を生成する(ステップ220)。C_O
UT[B]は記憶装置に記憶される。第2の条件に関連
して上で用いたBackward処理を実施する。最後に、各ベ
ーシック・ブロックにおいて、C_OUT[B]を第3
の条件に従って修正しつつ実行とは逆順に各命令を辿
り、C_OUT[B]を用いて配列レンジ・チェックの
ためのコードを生成する(ステップ230)。生成され
たコードは記憶装置に記憶される。以下、各ステップに
ついて詳しく説明する。
【0106】ステップ210では、例外を発生させる配
列レンジ・チェックがそれより前に移動させることによ
って副作用を生じるような命令が存在する場合にはC_
GEN[B]を空にし、且つ配列インデックス変数を正
又は負の定数の加算以外で変更する場合には変更された
配列インデックス変数に関連する配列レンジ・チェック
を取り扱わないものとして、ベーシック・ブロック中で
必要とされる配列レンジ・チェックの集合情報C_GE
N[B]を実行とは逆順で求める。なお、副作用とは、
移動前と後では実行結果が異なる、すなわちその命令が
実行されなくなるという結果をもたらすことを言う。こ
の副作用を生じるような命令の例としては、例外(Exce
ption)を発生する命令、ヒープ領域への書き込み命
令、関数呼び出し、Javaではトライ領域(Try Regi
on)内でローカル変数の書き込み命令のようなチェック
を移動することにより副作用を生じる命令等、である。
以下にステップ210の擬似コードを示す。
【表25】 for (各ベーシック・ブロックについて実行とは逆順に命令を取り出す){ switch(命令){ 配列アクセス: 配列レンジ・チェックCに対して C_GEN[B] += C; break; 配列のベース変数 a の変更: for (全てのC∈ C_GEN[B]){ if (Cの中に変更された配列ベース a による lb(a)またはub(a)が含まれる){ C_GEN[B] -= C; } } break; インデックス v の変更: for (全てのC∈ C_GEN[B]){ if (Cは変更されたインデックス v 又は v の式 f(v) で構成される){ if (インデックス v が v = v + c (cは定数)で変更される){ Cの v を v + c、又はf(v)をf(v + c)として置き換える。 } else { C_GEN[B] -= C; } } } break; 例外を発生させる配列レンジ・チェックをそれより前に移動 することにより副作用を生じるような命令: C_GEN[B] = φ; break; } }
【0107】例外を発生させる配列レンジ・チェックが
それより前に移動することにより副作用を生じるような
命令(以下副作用命令と呼ぶ)の場合に、C_GEN
[B]を空φにする。これは、配列レンジ・チェックを
移動させることができないからである。
【0108】ステップ220では、このC_GEN
[B]を用いて次の式によるデータフロー解析(Data-f
low Analysis)を実施し、C_OUT[B]を生成す
る。Bが終端のベーシック・ブロックでない場合には、
S∈Succ(B)に対して、 C_OUT[B] = ∩ C_IN[S] 一方、Bが終端のベーシック・ブロックである場合に
は、 なお、backward(C_OUT[B],B)はAppendix Aに
示したものと同じである。表25は、C_OUT[B]
を求める際には、Bが終端でない場合にはC_IN
[S]の積集合を計算し、Bが終端の場合にはC_OU
T[B]を空にする必要があることを示している。Sは
上でも述べたがBの直後の全てのベーシック・ブロック
である。C_IN[B]は、Bの中に副作用を生ずる命
令が存在する場合にはC_IN[B]=C_GEN
[B]により、また副作用を生ずる命令が存在しない場
合にはC_IN[B]=C_GEN[B]∪ backward
(C_OUT[B],B)により求められる。以上を図12にまとめ
ておく。
【0109】ステップ230はC_OUT[B]を基に
配列レンジ・チェックのためのコードを生成する処理で
ある。以下に擬似コードを示す。
【表26】 for (各ベーシック・ブロックについて実行とは逆順に命令を取り出す){ switch(命令){ 配列アクセス: その配列レンジ・チェックCに対して exist = FALSE; for (全てのC'∈ C_OUT[B]){ if (C ⊆ C'){ exist = TRUE; if (C ⊂ C') { CをC'として配列レンジ・チェックのコードを生成。 break; } } } if (!exist){ C_OUT[B] += C; Cの配列レンジ・チェックのコードを生成。 break; } 配列のベース変数 a の変更: for (全てのC∈ C_OUT[B]){ if (Cの中に変更された配列ベース a による lb(a)またはub(a)が含まれる){ C_OUT[B] -= C; } } break; インデックス v の変更: for (全てのC∈ C_OUT[B]){ if (Cは変更されたインデックス v 又は v の式 f(v) で構成される){ if (インデックス v が i = i + c(cは正又は負の定数) で変更される){ Cの v を v + c、又はf(v)をf(v + c)として置換。 } else { C_OUT[B] -= C; } } } break; 副作用命令: C_OUT[B] = φ; break; } }
【0110】表26は表25に似ているが、最初のswit
chの条件である、取り出した命令が配列アクセスである
場合の処理内容が異なる。まず、existをFALSEに初期化
した後、C_OUT[B]内の全てのC'について処理
中の配列アクセスに対する配列レンジ・チェックCを検
査する。そして、C⊆C'であるならば、existをTRUEに
して、CがC_OUT[B]と重複関係があることを記
録する。そして、さらにC⊂C'であるならば(配列レ
ンジ・チェックCの範囲が、C_OUT[B]内のC'
の範囲より狭い場合)、ここでCの配列チェックをする
よりもC'の方が好ましいのでCをC'として配列レンジ
・チェックのためのコードを生成する。一方、いずれの
C'についてもC⊆C'でなければ、existはTRUEになら
ないので、このCにて配列レンジ・チェックのためのコ
ードを生成する。但し、ここでCについて配列レンジ・
チェックのためのコードを生成するので、以降同じ範囲
の配列レンジ・チェックを行わないようにするため、C
をC_OUT[B]に加える。
【0111】以上のようにして配列レンジ・チェックが
最適化される。表24の例に本発明の最適化処理を施し
た例を以下に示しておく。図13に表27のフローグラ
フを示しておく。
【表27】 なお、BBはベーシック・ブロックを表し、その後の番号
はベーシック・ブロックの番号である。
【0112】BB1は配列アクセスが存在しないのでC_
GEN[BB1]は空である。ステップ210は実行とは
逆順に行われるため、最初にC_GEN[BB2]に含ま
れるのは、lb(a)≦i−2及びi≦ub(a)であ
る。次の命令はi++でi=i+1が実行されるので、
配列インデックスの定数の加算である。よって、lb
(a)≦i−2及びi≦ub(a)のiを+1する。す
なわち、lb(a)≦(i+1)−2=i−1及びi+
1≦ub(a)がC_GEN[BB2]に入力される。
【0113】C_GEN[BB3]に最初に含まれるの
は、lb(a)≦i−2、i≦ub(a)、lb(a)
≦5及び5≦ub(a)である。実行とは逆順で次の命
令i++によりC_GEN[BB3]を変更すると、lb
(a)≦i−1、i+1≦ub(a)、lb(a)≦5
及び5≦ub(a)となる。同様にすると、C_GEN
[BB4]はlb(a)≦i−2、i+1≦ub(a)と
なる。以下にまとめておく。
【0114】BB5は、終端ベーシック・ブロックである
からC_OUT[BB5]は空である。そして、C_GE
N[BB5]も空であるからC_IN[BB5]も空である。
BB4のC_OUT[BB4]も、C_OUT[B] = ∩ C_IN[S]の
要件から空になる。しかし、C_GEN[BB4]がlb(a)
<= i-2, i+1 <= ub(a)であるから、C_IN[BB4]も
lb(a) <= i-2, i+1 <= ub(a)となる。(1)配列ベース
(2)配列インデックスのうちインデックス変数を含む
項(3)配列インデックスの最大定数オフセット及び
(4)配列インデックスの最小定数オフセットのように
記憶装置に記憶する場合には、(1)a(2)i(3)
+1(4)−2となる。
【0115】C_OUT[BB3]はC_IN[BB4]のみ
から得られるので、C_OUT[BB3]もlb(a) <= i-2,
i+1 <= ub(a)となる。一方、C_IN[BB3]はC_G
EN[BB3]とbackward(C_OUT[BB3], BB3)から得られ
る。BB3には1(定数)の加算が含まれているので、lb
(a) <= i-2, i+1 <= ub(a)は、T={lb(a) <= i-1, i+
2 <= ub(a)}に修正される(先に示した記憶方法では、
(1)a(2)i(3)+2(4)−1)。C_GEN
[BB3]がlb(a) <= i-1, i+1 <= ub(a),lb(a) <= 5, 5
<= ub(a)であるから、最終的にC_IN[BB3]は、lb
(a) <= i-1, i+2<= ub(a),lb(a) <= 5, 5 <= ub(a)と
なる(先に示した記憶方法では(1)a(2)i(3)
+2(4)−1,(1)a(2)null(3)5(4)
5)。
【0116】C_OUT[BB2]はC_IN[BB4]及び
C_IN[BB3]の積集合から得られる。C_IN[BB
4]はlb(a) <= i-2, i+1 <= ub(a)、C_IN[BB3]は
lb(a) <= i-1, i+2 <= ub(a),lb(a) <= 5, 5 <= ub(a)
であるから、C_OUT[BB2]はlb(a) <= i-1, i+1 <
= ub(a)となる(先に示した記憶方法では(1)a
(2)i(3)+1(4)ー1)。一方、C_IN[BB
2]は、C_GEN[BB2]とbackward(C_OUT[BB2],BB
2)の和集合となる。backward(C_OUT[BB2],BB2)は、BB2
に1(定数)の加算操作を含むので、lb(a) <= i, i+2
<= ub(a)となる(先に示した記憶方法では(1)a
(2)i(3)+2(4)0)。C_GEN[BB2]はl
b(a) <= i-1, i+1 <= ub(a)であるから、最終的にC_
IN[BB2]はlb(a) <= i-1, i+2 <= ub(a)となる(先
に示した記憶方法では(1)a(2)i(3)+2
(4)−1)。
【0117】C_OUT[BB1]はC_IN[BB2]から
得られる。よって、C_OUT[BB1]はlb(a) <= i-1,
i+2 <= ub(a)となる(先に示した記憶方法では(1)
a(2)i(3)+2(4)−1)。C_IN[BB1]
はC_GEN[BB1]とbackward(C_OUT[BB1], BB1)の和
集合になる。しかし、C_GEN[BB1]は空であり、B
ackward処理の中でBB1にはiの定数代入(i=0)があ
るので、C_OUT[BB1]の全てのCは除去されてT
は空になる。よって、C_IN[BB1]は空となる。以
下、上の処理結果をまとめておく。
【0118】次にステップ230の処理を実施する。ま
ず、C_OUT[BB1]を用いてBB1を処理する。しか
し、BB1には配列アクセスがないので、配列レンジ・チ
ェックのためのコードは生成されない。次にC_OUT
[BB2]を用いてBB2を処理する。BB2には配列アクセス
が存在する。本処理適用前には、check(i<=ub(a))及びc
heck(i-2>=lb(a))が必要であった。しかし、C_OUT
[BB2]のi+1<= ub(a)の方がi<=ub(a)よりも広い範囲を
カバーすることになるので、check(i<=ub(a))はcheck(i
+1<=ub(a))で置換される。また、C_OUT[BB3]を
用いてBB3を処理する場合、本発明適用前には、check(i
<= ub(a))、check(lb(a) <= i-2)、check(lb(a) <=
5)、及びcheck(5 <= ub(a))が必要であった。しかし、
C_OUT[BB3]内のi+1 <= ub(a)はcheck(i <= ub
(a))より広い範囲をカバーするので、このcheck(i <= u
b(a))をcheck(i+1 <= ub(a))に置換してコードを生成す
る。BB3には配列インデックス変数を定数で加算する操
作が含まれるが、実行とは逆順でその操作の後に配列ア
クセスが存在しないので影響はない。次にC_OUT
[BB4]を用いてBB4を処理するが、C_OUT[BB4]
が空であるから、本処理の適用前と同じ状態になる。BB
5についても処理は必要ない。以下表28に表27に対
し本処理を実施した結果を示す。なお、表28は本処理
の適用結果がわかるように示しているものであって、現
実には実行可能コードが生成される。
【表28】 i = 1; t = 0; do { i++; check(lb(a) <= i-2); check(i+1 <= ub(a)); /*check(i <= ub(a))の置換後*/ t += a[i] + a[i-1] + a[i-2]; if (t < 0) { i++; check(lb(a) <= i-2); check(i+1 <= ub(a)); /* check(i <= ub(a))の置換後*/ check(lb(a) <= 5); /* lb(a)が5以下の言語はこのチェックは必要ない */ check(5 <= ub(a)); t += a[i] + a[i-1] + a[i-2] + a[5]; } i++; check(lb(a) <= i-3); check(i <= ub(a)); t += a[i] + a[i-1] + a[i-2] + a[i-3]; } while(i < n);
【0119】Appendix D 不要な配列レンジ・チェックの除去処理 図14に本処理の概要を示す。まず、各ベーシック・ブ
ロック内において、実行の順番で、所定の条件に従って
チェック済みとして取り扱われる配列レンジ・チェック
の集合C_GEN[B]を収集する(ステップ31
0)。このC_GEN[B]は記憶装置に記憶される。
そして、プログラムのデータフロー解析の順番で、C_
GEN[B]を第2の条件で修正しつつ伝搬させ、各ベ
ーシック・ブロックの先頭においてチェック済みとして
取り扱われる配列レンジ・チェックの集合C_IN
[B]を生成する(ステップ320)。C_IN[B]
は記憶装置に記憶される。そして、最後に、各ベーシッ
ク・ブロック内において、実行順番に各命令をたどり、
C_IN[B]を第3の条件で修正し(表30内のvをv
-c、又はf(v)をf(v-c)として置き換える)、C_IN
[B]を用いて配列レンジ・チェックを除去する(ステ
ップ330)。
【0120】ではステップ310について説明する。こ
こでは配列ベースを変更する命令を本発明の対象外とす
る。一方、配列インデックス変数の正又は負の定数によ
る加算命令が含まれていても、当該配列インデックス変
数に関連する配列レンジ・チェックは本発明の対象であ
るとして取り扱う。それ以外の変更命令に関連する配列
レンジ・チェックは本発明の対象外である。このような
条件の下、ベーシック・ブロック内でチェック済みとし
て取り扱われる配列レンジ・チェックの集合C_GEN
[B]を実行順に収集する。なお、配列インデックス変
数iをi+c(cは正又は負の定数)のように変更する
場合には、C_GEN[B]の配列インデックスの式f
(i)をf(i−c)として配列レンジ・チェックの情
報を更新する。以下、この処理の擬似コードを示す。
【表29】 for (各ベーシック・ブロックについて実行順に命令を取り出す){ switch(命令){ 配列アクセス命令: その配列レンジ・チェックCに対し C_GEN[B] += C; C_GEN[B] += Cの拡張; break; 配列のベース変数 a の変更: for (全てのC∈ C_GEN[B]){ if (Cの中に変更された配列ベース a による lb(a)またはub(a)が含まれる){ C_GEN[B] -= C; } } break; インデックス v の変更: for (全てのC∈ C_GEN[B]){ if (Cは変更されたインデックス v 又は v の式 f(v) で構成される){ if (インデックス v が i = i + c (cは正又は負の定数)で変更される){ C内の v を v - c、又はf(v)をf(v - c)として置き換える。 } else { C_GEN[B] -= C; } } } break; } }
【0121】ステップ310では実行の順番で各ベーシ
ック・ブロックの命令を走査していく。そして、配列ア
クセス命令である場合には、当該配列アクセスの配列レ
ンジ・チェックCをC_GEN[B]に入れる。可能で
あれば、Cの拡張についてもC_GEN[B]に入れ
る。この拡張は以下のようなものである。 (1)配列インデックスの最小定数オフセット値及び最
大定数オフセット値及び配列の下限から計算される範囲
の配列レンジ・チェック。 すなわち、(配列の下限,配列の下限+(最大定数オフ
セット値−最小定数オフセット値))の定数インデック
スの範囲がチェック済みであるとされる。例えば、Ja
va言語でa[i-1]、a[i+1]が配列レンジ・チェック済み
である場合には、定数インデックスに関してa[0]からa
[2]もチェック済みであるとしてC_GEN[B]に加
える。 (2)配列の下限及び配列インデックス変数の下限値及
び上限値から計算される範囲の配列レンジ・チェック 次のいずれかの条件を満たし、下限値又は上限値を基に
計算したインデックスの式の値が配列の下限以上の値を
とる時に、(配列の下限,変数の下限値又は上限値を基
に計算したインデックスの式の値)の定数インデックス
の範囲がチェック済みであるとされる。条件: インデックスの式が単調増加し、インデックス変数の下
限値が分かるとき インデックスの式が単調減少し、インデックス変数の上
限値が分かるとき 例えばJava言語で配列アクセスがa[2*i+1]という形
で行われ、iの下限値が5であと分かった場合には、こ
のチェックが行われた時点でa[0]からa[13]までもチェ
ック済みであるとしてC_GEN[B]に追加する。ま
た、配列アクセスがa[10-i]という形であり、iの上限
値が5であることが分かった場合には、このチェックが
行われた時点でa[0]からa[5]までもチェック済みである
としてC_GEN[B]に加える。
【0122】配列のベース変数aの変更の処理は上のA
ppendix Cの場合と変わりない。配列インデッ
クス変数vの変更処理は上で述べたAppendix
Cの場合とは異なる。当該配列レンジ・チェックがv又
はf(v)で表され且つ正又は負の定数による加算又は
減算による場合のみC_GEN[B]に含めておくこと
ができる。すなわち、正又は負の定数による加算でない
場合には、変更される配列インデックス変数vに関連す
るC_GEN[B]の要素はC_GEN[B]から除去
される。一方、正又は負の定数による加算の場合には、
その変更とは反対に当該定数による減算がC_GEN
[B]内の関係する配列レンジ・チェックに対して実施
される。すなわち、変更がv+cの場合には、配列レン
ジ・チェックCのv又はf(v)がv−c又はf(v−
c)に置換される。
【0123】このように反対の変更を実施しなければな
らないのは、命令をたどる方向が異なるからである。上
で述べたAppendix Cの場合には実行とは逆順
であったので、例えばi++という変更がC_GEN
[B]に収集されたi≦ub(a)より上(前)に存在
している場合には、このi≦ub(a)のiはそのベー
シック・ブロックの先頭から見るとi+1になる。一
方、ここでは実行順に命令をたどるので、例えばi++
という変更がC_GEN[B]に収集されたi≦ub
(a)より下(後)に存在している場合には、このi≦
ub(a)のiをそのベーシック・ブロックの後端から
見るとi−1になる。よってこのような取扱いの差が生
じるのである。
【0124】次にステップ320を説明する。ここでは
上で収集したC_GEN[B]を用いて次の式によるデ
ータ・フロー解析(data-flow analysis)を行う。全て
のP∈Pred(B)について、Bが初期ブロックでない場
合、 C_IN[B] = ∩ C_OUT[P] Bが初期ブロックである場合、 C_IN[B] = φ C_OUT[B] = C_GEN[B] ∪ forward(C_IN[B], B) なお、Pred(B)は、Bの直前にくるベーシック・ブロッ
クPを示すものである。また、forward(C_IN[B], B)は
以下に詳述する。上の式でC_IN[B]は、そのベー
シック・ブロックBの直前のベーシック・ブロックPの
C_OUT[P]の積集合となることを示している。但
し、Bがプログラムの先頭のベーシック・ブロックであ
る場合には、C_IN[B]は空である。そして、この
C_IN[B]をもちいて、C_OUT[B]が求めら
れる。すなわち、C_OUT[B]=C_GEN[B]
∪ forward((C_IN[B], B)である。これを図15にまと
めておく。
【0125】ステップ330の処理はC_IN[B]を
基に次のようなアルゴリズムで行う。
【表30】 for (各ベーシック・ブロックについて実行順に命令を取り出す){ switch(命令){ 配列アクセス命令: その配列レンジ・チェックCに対して if (CがC_IN[B]からチェック済と判断できる){ 配列レンジ・チェックCを除去 } else { C_IN[B] += C; } break; 配列のベース変数 a の変更: for (全てのC∈ C_IN[B]){ if (Cの中に変更された配列ベース a による lb(a)またはub(a)が含まれる){ C_IN[B] -= C; } } break; インデックス v の変更: for (全てのC∈ C_IN[B]){ if (Cは変更されたインデックス v 又は v の式 f(v) で構成される){ if (インデックス v が i = i + c (cは正又は負の定数)で変更される){ v を v - c、又はf(v)をf(v - c)として置き換える。 } else { C_IN[B] -= C; } } } break; } }
【0126】表30が表29と異なる部分は、取り出し
た配列アクセス命令の場合の処理である。ここでは、当
該配列アクセスの配列レンジ・チェックCがC_IN
[B]からチェック済みであると判断できる場合には、
当該配列レンジ・チェックCを除去対象として選択す
る。そうでなければ配列レンジ・チェックが必要である
からその配列レンジ・チェックは残す。但し、残した場
合には後の配列レンジ・チェックを除去するのに用いる
ことができるので当該配列レンジ・チェックCをC_I
N[B]に入れる。ところで、C_IN[B]からチェ
ック済であると判断できる場合とは、C_IN[B]の
配列レンジ・チェックに直接包含される場合される場合
に限定されない。以下の場合も、除去対象として選択す
ることができる。
【0127】(1)配列インデックスが (I1 + I2 +
... + In) / N の時にインデックス変数I1 から In
で全て配列ベースに対してチェック済みであり、Nがn
に等しい時、この式も配列レンジ・チェック済みの部分
にカバーされているとして扱うことができる。また、配
列の下限が0の言語に限ってはNがn以上の値ならばチ
ェック済として扱える。 (2)Java言語においては、配列のインデックス
が、A(任意の式) modN(Nは定数)というように剰
余の形になっている時、Aが必ず正の値をとれば結果は
0からabs(N)−1(absは絶対値)の範囲に収まる。こ
れを利用してAが必ず正の値をとる時、abs(N)−1の定
数値が配列ベースに対してチェック済であればこの配列
アクセスもチェック済として扱える。もし、配列インデ
ックスの下限が0でないプログラミング言語の場合に
は、定数0がチェック済みであるかどうかということも
検査しなければならない。
【0128】以上の処理を表27に適用した場合の例を
示す。まず、ステップ310を表27に適用した場合
に、C_GEN[B]は以下のようになる。すなわち、
BB1については、配列アクセスがないのでC_GEN[B
B1]は空である。また、BB2には2つの配列レンジ・チ
ェックが存在しており、lb(a)≦i−2,i+1≦
ub(a)はそのままC_GEN[BB2]に入れられる
((1)配列ベース(2)配列インデックスのうちイン
デックス変数を含む項(3)配列インデックスの最大定
数オフセット及び(4)配列インデックスの最小定数オ
フセットのように記憶装置に記憶する場合には、(1)
a(2)i(3)+1(4)−2となる。)。さらに、
これらの拡張として、i+1−(i−2)=3であるか
らlb(a)+3≦ub(a)もチェック済であるとし
て扱える。よってこの情報もC_GEN[BB2]に入れ
られる(Java言語の場合であって、先に示した記憶
方法では(1)a(2)null(3)3(4)0)。BB3
には4つの配列レンジ・チェックが存在しており、lb
(a)≦i−2,i+1≦ub(a),lb(a)≦
5,及び5≦ub(a)はそのままC_GEN[BB3]
に入れられる(先に示した記憶方法では、(1)a
(2)i(3)+1(4)−2、(1)a(2)null
(3)5(4)5)。ここでは、lb(a)+3≦ub
(a)をC_GEN[BB3]に入れてもよいが、lb
(a)が0のようなJava言語等では5≦ub(a)
に包含されるので、ここでは入れない。BB4について
は、配列レンジ・チェックが2つ存在している。lb
(a)≦i−3及びi≦ub(a)はそのままC_GE
N[BB4]に入れられる(先に示した記憶方法の場合、
(1)a(2)i(3)0(4)−3)。またlb
(a)+3≦ub(a)もこれらから導き出されるので
C_GEN[BB4]に入れる(Java言語の場合であ
って、先に示した記憶方法では(1)a(2)null
(3)3(4)0)。BB5は配列アクセスがないのでC
_GEN[BB5]は空である。以下にC_GEN[B]
の結果をまとめておく。
【0129】次にステップ320の結果を考える。BB1
は初期ブロックであるのでC_IN[BB1]は空であ
る。またBB1ではC_GEN[BB1]も空であるからC_
OUT[BB1]も空である。C_IN[BB2]はC_OU
T[BB1]が空であるから同じく空である。C_GEN
[BB2]が存在するのでC_GEN[BB2]がそのままC
_OUT[BB2]となる。すなわち、lb(a)≦i−
2,i+1≦ub(a),lb(a)+3≦ub(a)
である(先に示した記憶方法では、(1)a(2)i
(3)+1(4)−2、Java言語である場合には
(1)a(2)null(3)3(4)0)。C_IN[BB
3]は、C_OUT[BB2]と同じになる。C_OUT
[BB3]は、C_GEN[BB3]とforward(C_IN[BB3], B
B3)との和集合である。T=forward(C_IN[BB3], BB3)
は、BB3がi++を含むので、C_IN[BB3]のlb
(a)≦i−2,i+1≦ub(a),lb(a)+3
≦ub(a)は、lb(a)≦i−3,i≦ub
(a),lb(a)+3≦ub(a)に修正される(先
に示した記憶方法では、(1)a(2)i(3)0
(4)−3、Java言語である場合には(1)a
(2)null(3)3(4)0)。よって、C_GEN
[BB3]のlb(a)≦i−2,i+1≦ub(a),
lb(a)≦5,及び5≦ub(a)との和集合は、l
b(a)≦i−3,i+1≦ub(a),lb(a)≦
5,及び5≦ub(a)及びlb(a)+3≦ub
(a)である(先に示した記憶方法では、(1)a
(2)i(3)+1(4)−3、(1)a(2)null
(3)5(4)5、Java言語である場合には(1)
a(2)null(3)3(4)0)。
【0130】C_IN[BB4]はC_OUT[BB2]及び
C_OUT[BB3]の積集合となる。よって、lb
(a)≦i−2,i+1≦ub(a),lb(a)+3
≦ub(a)となる(先に示した記憶方法では、(1)
a(2)i(3)+1(4)−2、Java言語である
場合には(1)a(2)null(3)3(4)0)。C_
OUT[BB4]はC_GEN[BB4]とforward(C_IN[BB
4], BB4)の和集合である。forward(C_IN[BB4], BB4)
は、BB4にi++が含まれているので、lb(a)≦i
−3,i≦ub(a),lb(a)+3≦ub(a)と
なる(先に示した記憶方法では、(1)a(2)i
(3)0(4)−3、Java言語である場合には
(1)a(2)null(3)3(4)0)。よって、C_
GEN[BB4]であるlb(a)≦i−3,i≦ub
(a),lb(a)+3≦ub(a)との和集合C_O
UT[BB4]は、lb(a)≦i−3,i≦ub
(a),lb(a)+3≦ub(a)となる(先に示し
た記憶方法では、(1)a(2)i(3)0(4)−
3、Java言語である場合には(1)a(2)null
(3)3(4)0)。C_IN[BB5]は、C_OUT
[BB4]と同じである。また、C_OUT[BB5]も、C
_GEN[BB5]が空であり且つBB5には配列インデック
スの操作が存在してないので、C_IN[BB5]と同じ
である。以下、結果をまとめておく。
【0131】なお、配列aの下限lb(a)が0である
言語の場合には、以下のような結果が得られる。
【0132】ステップ330の処理を実施すると以下の
ようになる。BB1には配列アクセスはないので処理は行
われない。BB2にはまずi++が存在しているのがC_
IN[BB2]は空であるから内容の修正は行われず、且
つ2つの配列レンジ・チェックは除去されずに残る。こ
こで2つの配列レンジ・チェックはC_IN[BB2]に
追加されるが、このBB2にはもう配列アクセスは存在し
ないのでBB2についての処理は終了する。次にBB3に処理
は移行する。C_IN[BB3]はlb(a)≦i−2,
i+1≦ub(a),lb(a)+3≦ub(a)で、
まずi++が存在するのでこれを修正する。C_IN
[BB3]はlb(a)≦i−3,i≦ub(a),lb
(a)+3≦ub(a)となる(先に示した記憶方法で
は、(1)a(2)i(3)0(4)−3、Java言
語である場合には(1)a(2)null(3)3(4)
0)。次に、4つの配列レンジ・チェック(lb(a)
≦i−2,i+1≦ub(a),lb≦5及び5≦ub
(a))が存在するので、C_IN[BB3]から除去で
きるものは、lb(a)≦i−2である。残った配列レ
ンジ・チェックはC_IN[BB3]に入れられるがその
後の処理はない。次にBB4に処理は移行する。C_IN
[BB4]はlb(a)≦i−3,i≦ub(a),lb
(a)+3≦ub(a)である。BB4にはまずi++が
あるので、lb(a)≦i−2,i+1≦ub(a),
lb(a)+3≦ub(a)をlb(a)≦i−3,i
≦ub(a),lb(a)+3≦ub(a)に修正する
(先に示した記憶方法では、(1)a(2)i(3)0
(4)−3、Java言語である場合には(1)a
(2)null(3)3(4)0)。そして、BB4に存在す
る2つの配列レンジ・チェック(lb(a)≦i−3,
i≦ub(a))は共に修正されたC_IN[BB4]に
カバーされる。よって、BB4では配列レンジ・チェック
は全て除去されることになる。BB5には配列レンジ・チ
ェックは存在しないので、処理は終了する。以上の結果
を表nに示す。なお、表31では擬似コードを示すが、
実際には実行可能なコードが生成される。
【表31】 i = 1; t = 0; do { i++; check(lb(a) <= i-2); check(i+1 <= ub(a)); t += a[i] + a[i-1] + a[i-2]; if (t < 0) { i++; check(i+1 <= ub(a)); check(lb(a) <= 5); /* lb(a)が5以下の言語はこのチェックは必要ない */ check(5 <= ub(a)); t += a[i] + a[i-1] + a[i-2] + a[5]; } i++; t += a[i] + a[i-1] + a[i-2] + a[i-3]; } while(i < n);
【図面の簡単な説明】
【図1】本発明のシステム全体の概要図である。
【図2】本発明の第1の態様(処理A.)の処理フロー
を示す図である。
【図3】命令の実行順番の例を示す図である。
【図4】図3の実際の命令を示す図である。
【図5】本発明の第2の態様(処理B.)の処理フロー
を示す図である。
【図6】本発明の第3の態様(処理C.)の処理フロー
を示す図である。
【図7】本発明の第3の態様と第1の態様を組み合わせ
た場合の処理フローの例1を示す図である。
【図8】本発明の第3の態様と第1の態様を組み合わせ
た場合の処理フローの例2を示す図である。
【図9】本発明の第3の態様において3バージョンに分
ける場合の処理フローを示す図である。
【図10】バージョニングをしない場合において本発明
の第1の態様と第3の態様を組み合わせた場合の処理フ
ローを示す図である。
【図11】データ・フロー解析を実行順序とは逆順に行
って配列レンジ・チェックを最適化する部分のメイン・
フローを表した図である。
【図12】図11のステップ220の処理フローを表し
た図である。
【図13】表27の例のフローグラフである。
【図14】データ・フロー解析を実行順に行って配列レ
ンジ・チェック済の情報を取得し、この情報から不要な
配列レンジ・チェックを除去する部分のメイン・フロー
を表した図である。
【図15】図14のステップ320の処理フローを表し
た図である。
【符号の説明】
100−850 処理ステップ
フロントページの続き (72)発明者 小松 秀昭 神奈川県大和市下鶴間1623番地14 日本 アイ・ビー・エム株式会社 東京基礎研 究所内 (72)発明者 安江 俊明 神奈川県大和市下鶴間1623番地14 日本 アイ・ビー・エム株式会社 東京基礎研 究所内 (56)参考文献 特開2000−47879(JP,A) 特開 平2−148330(JP,A) 特開 平10−275087(JP,A) 特許3280332(JP,B2) Midkiff,S.P.,et.a l.,”Optimizing arr ay rederence check ing in Java Progra ms”,IBM SYSTEMS JO URNAL,1998年,Vol.37,N o.3,pp.409−453 Wei−Ngan Chin and Eak−Khoon Goh,”A Reexamination of " Optimization of Ar ray Subscript Rang e Checks””,ACM Tra nsactions on Progr amming Language an d Systems(TOPLAS), 1995年,Vol.17,No.2,pp. 217−227 Asuru,J.M.,”Optim ization of Array S ubscript Range Che cks”,ACM Letters o n Programming lang uages and Syatems (LOPLAS),1992年,Vol. 1,No.2,pp.109−118 Ali−Reza Adl−Taba tabai,et.al.,”Fas t,Effective Code G eneration in a Jus t−In−Time Java Com piler”,ACM SIGPLAN Notices,1998年,Vol. 33,No.5,pp.280−290 Kolte,P.,et.al.," Elimination of red undant array subsc ript range check s”,ACM SIGPLAN Not ices,1995年,Vol.30,No. 6,pp.270−278 Gupta,R.,”Optimiz ing array bound Ch ecks using flow an alysis”,ACM Letter s on Programming L anguages and Syate ms(LOPLAS),1993年,Vo l.2,No.1−4,pp.135−150 Gupta,R.,”A fresh look at optimizin g array bound chec king”,ACM SIGPLAN Notices,1990年,Vol.25, No.6,pp.272−282 (58)調査した分野(Int.Cl.7,DB名) G06F 9/45 G06F 9/06 G06F 12/00 - 12/06 G06F 9/30 - 9/36 JSTファイル(JOIS) CSDB(日本国特許庁) WPI/L(DIALOG) INSPEC(DIALOG)

Claims (14)

    (57)【特許請求の範囲】
  1. 【請求項1】プログラム内の配列アクセスに対する配列
    レンジ・チェックのためのコードを生成する方法であっ
    て、 複数の配列アクセスに対応する複数の配列レンジ・チェ
    ックを統合した統合配列レンジ・チェックの結果を記憶
    領域に格納する第1コードを生成し且つ記憶装置に記憶
    する第1ステップと、 前記記憶領域を検査し且つ当該記憶領域が前記統合配列
    レンジ・チェックの成功を示している場合には前記複数
    の配列レンジ・チェックに包含される配列レンジ・チェ
    ックのための第2コードを無効化する第3コードを生成
    し且つ記憶装置に格納する第2ステップと、 を含む配列レンジ・チェックのためのコード生成方法。
  2. 【請求項2】バージョニングを実施する場合、 当該バージョニングの条件である前記統合配列レンジ・
    チェックの結果を格納した記憶領域を参照し且つ前記記
    憶領域が前記バージョニングの条件である前記統合配列
    レンジ・チェックの成功を示している場合には前記バー
    ジョニングの条件である前記統合配列レンジ・チェック
    に包含される配列レンジ・チェックのためのコードを含
    まないバージョンに分岐させ且つ前記記憶領域が前記バ
    ージョニングの条件である前記統合配列レンジ・チェッ
    クの不成功を示している場合には前記第2及び第3コー
    ドを含むバージョンに分岐するコードを生成し且つ記憶
    装置に格納するステップと、 をさらに含む請求項1記載の配列レンジ・チェックのた
    めのコード生成方法。
  3. 【請求項3】前記記憶領域が、プロセッサのフラグであ
    ることを特徴とする請求項1記載の配列レンジ・チェッ
    クのためのコード生成方法。
  4. 【請求項4】プログラム内のループのバージョニングを
    実行する方法であって、 前記ループ内のいずれの実行経路を通過したとしても必
    ず行われる配列アクセスに対する配列レンジ・チェック
    の第1集合情報を収集し、収集結果を記憶装置に格納す
    るステップと、 前記収集結果を用いて、バージョニングのための検査コ
    ードを生成し且つ記憶装置に格納するステップと、 前記収集結果を用いて不要な配列レンジ・チェックを除
    去し、除去不可能な配列レンジ・チェックのためのコー
    ドを含む、前記検査コードによる配列レンジ・チェック
    が成功した場合におけるバージョンを生成し且つ記憶装
    置に格納するステップと、 前記検査コードによる配列レンジ・チェックが不成功の
    場合におけるバージョンを生成し且つ記憶装置に格納す
    るステップと、 を含むバージョニング実行方法。
  5. 【請求項5】前記ループ内のいずれの実行経路を通過し
    たとしても必ず行われる配列アクセスに対する配列レン
    ジ・チェックに限定せずに配列レンジ・チェックの第2
    集合情報を収集し、第2の収集結果を記憶装置に格納す
    るステップと、 前記第2集合情報から前記第1集合情報に含まれる配列
    レンジ・チェックを除去した第3集合情報を用いて、前
    記検査コードによる配列レンジ・チェックが成功した場
    合におけるバージョンのさらなるバージョニングのため
    の第2検査コードを生成し且つ記憶装置に格納するステ
    ップと、 前記第2の収集結果を用いて不要な配列レンジ・チェッ
    クを除去し、除去不可能な配列レンジ・チェックのため
    のコードを含む、前記第2検査コードによる配列レンジ
    ・チェックが成功した場合におけるバージョンを生成し
    且つ記憶装置に格納するステップと、 をさらに含み、 前記第2検査コードによる配列レンジ・チェックが不成
    功であった場合には、前記検査コードによる配列レンジ
    ・チェックが成功した場合におけるバージョンのコード
    を実行する、 請求項4記載のバージョニング実行方法。
  6. 【請求項6】前記除去不可能な配列レンジ・チェックと
    インデックス変数の範囲とによる第1配列レンジ・チェ
    ックの結果を、生成されたコードを実行するプロセッサ
    のフラグに格納するためのコードを生成し且つ記憶装置
    に格納するステップと、 前記フラグを検査し且つ当該フラグが前記第1配列レン
    ジ・チェックの成功を示している場合には前記除去不可
    能な配列レンジ・チェックのためのコードを無効化する
    他のコードを生成し且つ記憶装置に格納するステップ
    と、 をさらに含む請求項4記載のバージョニング実行方法。
  7. 【請求項7】前記ループ内のいずれの実行経路を通過し
    たとしても必ず行われる配列アクセスに対する配列レン
    ジ・チェックに限定せずに配列レンジ・チェックの第2
    集合情報を収集し、第2の収集結果を記憶装置に格納す
    るステップと、 前記第2集合情報から前記第1集合情報に含まれる配列
    レンジ・チェックを除去した第3集合情報の結果を、生
    成されたコードを実行するプロセッサのフラグに格納す
    るためのコードを生成し且つ記憶装置に格納するステッ
    プと、 前記フラグを検査し且つ当該フラグが前記第3集合情報
    に含まれる配列レンジ・チェックが成功したことを示し
    ている場合には前記除去不可能な配列レンジ・チェック
    のためのコードを無効化する他のコードを生成し且つ記
    憶装置に格納するステップと、 をさらに含む請求項4記載のバージョニング実行方法。
  8. 【請求項8】前記第1ステップが、 前記プログラムのある部分のいずれの実行経路を通過し
    たとしても必ず行われる配列アクセスに対する配列レン
    ジ・チェックの第1集合情報を収集し、収集結果を格納
    する領域を記憶装置内に割り当てるステップと、 前記ある部分のいずれの実行経路を通過したとしても必
    ず行われる配列アクセスに対する配列レンジ・チェック
    に限定せずに配列レンジ・チェックの第2集合情報を収
    集し、第2の収集結果を格納する領域を記憶装置内に割
    り当てるステップと、 前記第2集合情報に含まれる配列レンジ・チェックの結
    果を1つの記憶領域に割り当て、前記第2集合情報から
    前記第1集合情報に含まれる配列レンジ・チェックを除
    去した第3集合情報の配列レンジ・チェックの結果を1
    又は複数の記憶領域に割り当てるステップと、 を含む請求項1記載の配列レンジ・チェックのためのコ
    ード生成方法。
  9. 【請求項9】プログラム内の配列アクセスに対する配列
    レンジ・チェックのためのコードを生成する装置であっ
    て、 記憶装置と、 プロセッサにより使用可能な記憶領域と、 複数の配列アクセスに対応する複数の配列レンジ・チェ
    ックを統合した統合配列レンジ・チェックの結果を記憶
    領域に格納する第1コードを生成し且つ前記記憶装置に
    記憶する第1手段と、 前記記憶領域を検査し且つ当該記憶領域が前記統合配列
    レンジ・チェックの成功を示している場合には前記複数
    の配列レンジ・チェックに包含される配列レンジ・チェ
    ックのための第2コードを無効化する第3コードを生成
    し且つ前記記憶装置に格納する第2手段と、 を有する配列レンジ・チェックのためのコード生成装
    置。
  10. 【請求項10】プログラム内のループのバージョニング
    を実行する装置であって、 記憶装置と、 前記ループ内のいずれの実行経路を通過したとしても必
    ず行われる配列アクセスに対する配列レンジ・チェック
    の第1集合情報を収集し、収集結果を前記記憶装置に格
    納する手段と、 前記収集結果を用いて、バージョニングのための検査コ
    ードを生成し且つ前記記憶装置に格納する手段と、 前記収集結果を用いて不要な配列レンジ・チェックを除
    去し、除去不可能な配列レンジ・チェックのためのコー
    ドを含む、前記検査コードによる配列レンジ・チェック
    が成功した場合におけるバージョンを生成し且つ前記記
    憶装置に格納する手段と、 前記検査コードによる配列レンジ・チェックが不成功の
    場合におけるバージョンを生成し且つ前記記憶装置に格
    納する手段と、 を有するバージョニング実行装置。
  11. 【請求項11】処理対象プログラム内の配列アクセスに
    対する配列レンジ・チェックのためのコードを生成する
    ためのプログラムを格納した記憶媒体であって、 前記プログラムは、プロセッサに、 複数の配列アクセスに対応する複数の配列レンジ・チェ
    ックを統合した統合配列レンジ・チェックの結果を記憶
    領域に格納する第1コードを生成し且つ記憶装置に記憶
    する第1ステップと、 前記記憶領域を検査し且つ当該記憶領域が前記統合配列
    レンジ・チェックの成功を示している場合には前記複数
    の配列レンジ・チェックに包含される配列レンジ・チェ
    ックのための第2コードを無効化する第3コードを生成
    し且つ記憶装置に格納する第2ステップと、 を実行させる、記憶媒体。
  12. 【請求項12】処理対象プログラム内のループのバージ
    ョニングを実行するためのプログラムを格納した記憶媒
    体であって、 前記プログラムは、コンピュータに、 前記ループ内のいずれの実行経路を通過したとしても必
    ず行われる配列アクセスに対する配列レンジ・チェック
    の第1集合情報を収集し、収集結果を記憶装置に格納す
    るステップと、 前記収集結果を用いて、バージョニングのための検査コ
    ードを生成し且つ記憶装置に格納するステップと、 前記収集結果を用いて不要な配列レンジ・チェックを除
    去し、除去不可能な配列レンジ・チェックのためのコー
    ドを含む、前記検査コードによる配列レンジ・チェック
    が成功した場合におけるバージョンを生成し且つ記憶装
    置に格納するステップと、 前記検査コードによる配列レンジ・チェックが不成功の
    場合におけるバージョンを生成し且つ記憶装置に格納す
    るステップと、 を実行させる、記憶媒体。
  13. 【請求項13】複数の配列レンジ・チェックを統合し
    て、統合された配列レンジ・チェックのためのコードを
    生成し、記憶装置に格納するステップと、 前記統合された配列レンジ・チェックの結果が失敗であ
    った場合のために、前記複数の配列レンジ・チェックに
    含まれる配列レンジ・チェックのためのコードを生成
    し、記憶装置に格納するステップと、 を含む配列レンジ・チェックのためのコード生成方法。
  14. 【請求項14】プログラム内のある部分のバージョニン
    グを実行する方法であって、 前記ある部分内のいずれの実行経路を通過したとしても
    必ず行われる配列アクセスに対する配列レンジ・チェッ
    クの第1集合情報を収集し、収集結果を記憶装置に格納
    するステップと、 前記収集結果を用いて、バージョニングのための検査コ
    ードを生成し且つ記憶装置に格納するステップと、 前記収集結果を用いて不要な配列レンジ・チェックを除
    去し、除去不可能な配列レンジ・チェックのためのコー
    ドを含む、前記検査コードによる配列レンジ・チェック
    が成功した場合におけるバージョンを生成し且つ記憶装
    置に格納するステップと、 前記検査コードによる配列レンジ・チェックが不成功の
    場合におけるバージョンを生成し且つ記憶装置に格納す
    るステップと、 を含むバージョニング実行方法。
JP00071299A 1999-01-05 1999-01-05 配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置 Expired - Fee Related JP3437932B2 (ja)

Priority Applications (2)

Application Number Priority Date Filing Date Title
JP00071299A JP3437932B2 (ja) 1999-01-05 1999-01-05 配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置
US09/473,858 US6665864B1 (en) 1999-01-05 1999-12-28 Method and apparatus for generating code for array range check and method and apparatus for versioning

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
JP00071299A JP3437932B2 (ja) 1999-01-05 1999-01-05 配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置

Publications (2)

Publication Number Publication Date
JP2000207221A JP2000207221A (ja) 2000-07-28
JP3437932B2 true JP3437932B2 (ja) 2003-08-18

Family

ID=11481388

Family Applications (1)

Application Number Title Priority Date Filing Date
JP00071299A Expired - Fee Related JP3437932B2 (ja) 1999-01-05 1999-01-05 配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置

Country Status (2)

Country Link
US (1) US6665864B1 (ja)
JP (1) JP3437932B2 (ja)

Families Citing this family (13)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7127559B2 (en) * 2001-07-10 2006-10-24 Micron Technology, Inc. Caching of dynamic arrays
US7062761B2 (en) 2001-07-10 2006-06-13 Micron Technology, Inc. Dynamic arrays and overlays with bounds policies
JP3900485B2 (ja) * 2002-07-29 2007-04-04 インターナショナル・ビジネス・マシーンズ・コーポレーション 最適化装置、コンパイラプログラム、最適化方法、及び記録媒体
US7885792B2 (en) * 2003-04-15 2011-02-08 The Mathworks, Inc. Programming Environment
US8117170B2 (en) * 2004-10-06 2012-02-14 International Business Machines Corporation Transient range versioning based on redirection
US8006239B2 (en) * 2007-01-16 2011-08-23 Nec Laboratories America, Inc. Program analysis using symbolic ranges
US7937695B2 (en) * 2007-04-27 2011-05-03 International Business Machines Corporation Reducing number of exception checks
US8087012B2 (en) * 2007-08-21 2011-12-27 International Business Machines Corporation Eliminating maximum/minimum operations in loop bounds
US8484613B2 (en) * 2010-01-28 2013-07-09 Synopsys, Inc. Optimizing bounds checking using computer algebra
US9348596B2 (en) 2013-06-28 2016-05-24 International Business Machines Corporation Forming instruction groups based on decode time instruction optimization
US9372695B2 (en) * 2013-06-28 2016-06-21 Globalfoundries Inc. Optimization of instruction groups across group boundaries
US10082538B2 (en) 2014-11-14 2018-09-25 Cavium, Inc. Testbench builder, system, device and method
US10282315B2 (en) 2015-03-27 2019-05-07 Cavium, Llc Software assisted hardware configuration for software defined network system-on-chip

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP3280332B2 (ja) 1998-07-10 2002-05-13 インターナショナル・ビジネス・マシーンズ・コーポレーション ループに対するバージョニングを実行する方法及び装置、配列レンジ・チェックに関する情報をベーシック・ブロック内において収集する方法及び装置、配列レンジ・チェックに関する情報を変更する方法、配列レンジ・チェック最適化方法、配列レンジ・チェックのためのコードを生成する方法、不要配列レンジ・チェック除去方法及び装置、配列レンジ・チェックを選択する方法、配列レンジ・チェック変更方法、配列レンジ・チェック収集方法、及び配列レンジ・チェック取扱判断方法

Family Cites Families (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5537620A (en) * 1994-09-16 1996-07-16 International Business Machines Corporation Redundant load elimination on optimizing compilers
US5797013A (en) * 1995-11-29 1998-08-18 Hewlett-Packard Company Intelligent loop unrolling
US6202204B1 (en) * 1998-03-11 2001-03-13 Intel Corporation Comprehensive redundant load elimination for architectures supporting control and data speculation
US6343375B1 (en) * 1998-04-24 2002-01-29 International Business Machines Corporation Method for optimizing array bounds checks in programs
JP3813019B2 (ja) * 1998-05-11 2006-08-23 インターナショナル・ビジネス・マシーンズ・コーポレーション プログラム処理方法、指定メソッドに関連するフレームを検出する方法、及び記憶媒体

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP3280332B2 (ja) 1998-07-10 2002-05-13 インターナショナル・ビジネス・マシーンズ・コーポレーション ループに対するバージョニングを実行する方法及び装置、配列レンジ・チェックに関する情報をベーシック・ブロック内において収集する方法及び装置、配列レンジ・チェックに関する情報を変更する方法、配列レンジ・チェック最適化方法、配列レンジ・チェックのためのコードを生成する方法、不要配列レンジ・チェック除去方法及び装置、配列レンジ・チェックを選択する方法、配列レンジ・チェック変更方法、配列レンジ・チェック収集方法、及び配列レンジ・チェック取扱判断方法

Non-Patent Citations (7)

* Cited by examiner, † Cited by third party
Title
Ali−Reza Adl−Tabatabai,et.al.,"Fast,Effective Code Generation in a Just−In−Time Java Compiler",ACM SIGPLAN Notices,1998年,Vol.33,No.5,pp.280−290
Asuru,J.M.,"Optimization of Array Subscript Range Checks",ACM Letters on Programming languages and Syatems(LOPLAS),1992年,Vol.1,No.2,pp.109−118
Gupta,R.,"A fresh look at optimizing array bound checking",ACM SIGPLAN Notices,1990年,Vol.25,No.6,pp.272−282
Gupta,R.,"Optimizing array bound Checks using flow analysis",ACM Letters on Programming Languages and Syatems(LOPLAS),1993年,Vol.2,No.1−4,pp.135−150
Kolte,P.,et.al.,"Elimination of redundant array subscript range checks",ACM SIGPLAN Notices,1995年,Vol.30,No.6,pp.270−278
Midkiff,S.P.,et.al.,"Optimizing array rederence checking in Java Programs",IBM SYSTEMS JOURNAL,1998年,Vol.37,No.3,pp.409−453
Wei−Ngan Chin and Eak−Khoon Goh,"A Reexamination of "Optimization of Array Subscript Range Checks"",ACM Transactions on Programming Language and Systems(TOPLAS),1995年,Vol.17,No.2,pp.217−227

Also Published As

Publication number Publication date
US6665864B1 (en) 2003-12-16
JP2000207221A (ja) 2000-07-28

Similar Documents

Publication Publication Date Title
US7725883B1 (en) Program interpreter
US7120898B2 (en) Intermediate representation for multiple exception handling models
US5768595A (en) System and method for recompiling computer programs for enhanced optimization
JP3707727B2 (ja) プログラムの最適化方法及びこれを用いたコンパイラ
JP3280332B2 (ja) ループに対するバージョニングを実行する方法及び装置、配列レンジ・チェックに関する情報をベーシック・ブロック内において収集する方法及び装置、配列レンジ・チェックに関する情報を変更する方法、配列レンジ・チェック最適化方法、配列レンジ・チェックのためのコードを生成する方法、不要配列レンジ・チェック除去方法及び装置、配列レンジ・チェックを選択する方法、配列レンジ・チェック変更方法、配列レンジ・チェック収集方法、及び配列レンジ・チェック取扱判断方法
US8533680B2 (en) Approximating finite domains in symbolic state exploration
US6173444B1 (en) Optimizing compilation of pointer variables in the presence of indirect function calls
US6131189A (en) System and method to efficiently represent aliases and indirect memory operations in static single assignment form during compilation
JP3311462B2 (ja) コンパイル処理装置
EP0533813B1 (en) Method for representing scalar data dependencies for an optimizing compiler
US6412105B1 (en) Computer method and apparatus for compilation of multi-way decisions
US7950005B2 (en) Method and apparatus for performing versioning for loop, method and apparatus for collecting array range check information in basic blocks, method for modifying array range check information, method for optimizing array range checks, method for generating codes for array range checks, method and apparatus for eliminating redundant array range checks, method for selecting array range checks, method for modifying array range checks, method for collecting array range checks, and method for determining handling of array range checks
US6233733B1 (en) Method for generating a Java bytecode data flow graph
Heydon et al. Caching function calls using precise dependencies
EP1618470B1 (en) Method and apparatus for recovering data values in dynamic runtime systems
US8146070B2 (en) Method and apparatus for optimizing software program using inter-procedural strength reduction
EP1004961B1 (en) Method and system for correlating profile data dynamically generated from an optimized executable program with source code statements
JP3437932B2 (ja) 配列レンジ・チェックのためのコード生成方法及び装置、並びにバージョニング方法及び装置
US20040230957A1 (en) Methods for comparing versions of a program
JPH09330233A (ja) 最適目的コード生成方法
US20020166115A1 (en) System and method for computer program compilation using scalar register promotion and static single assignment representation
US6330714B1 (en) Method and computer program product for implementing redundant lock avoidance
US5854928A (en) Use of run-time code generation to create speculation recovery code in a computer system
JP3049814B2 (ja) マイクロコンピュータの言語処理装置
JPH02176938A (ja) 機械語命令最適化方式

Legal Events

Date Code Title Description
LAPS Cancellation because of no payment of annual fees