JPH0675987A - ループ変換方法 - Google Patents

ループ変換方法

Info

Publication number
JPH0675987A
JPH0675987A JP5150130A JP15013093A JPH0675987A JP H0675987 A JPH0675987 A JP H0675987A JP 5150130 A JP5150130 A JP 5150130A JP 15013093 A JP15013093 A JP 15013093A JP H0675987 A JPH0675987 A JP H0675987A
Authority
JP
Japan
Prior art keywords
loop
array
node
program
child
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.)
Pending
Application number
JP5150130A
Other languages
English (en)
Inventor
Ichiro Kushima
伊知郎 久島
Masahiro Uminaga
正博 海永
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.)
Hitachi Ltd
Original Assignee
Hitachi Ltd
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 Hitachi Ltd filed Critical Hitachi Ltd
Priority to JP5150130A priority Critical patent/JPH0675987A/ja
Publication of JPH0675987A publication Critical patent/JPH0675987A/ja
Pending legal-status Critical Current

Links

Landscapes

  • Complex Calculations (AREA)
  • Devices For Executing Special Programs (AREA)

Abstract

(57)【要約】 【目的】 メモリ上でのアドレスが連続する2つのデー
タを1つの命令でそれぞれレジスタにロードができるプ
ロセッサに対して、該命令を利用できるようにループを
変換する方法を与える。 【構成】 ステップ101でプログラム中で繰り返し実
行される部分を特定し、ステップ102でループ内でア
クセスされている配列参照を同じ配列への参照であるか
という基準で同値類に分類する。ステップ103では同
値類のうち、配列転置化により一括ロードまたはストア
命令が利用できるものを選ぶ。ステップ104で選ばれ
た同値類に対応する配列を転置化してコピーする中間語
を生成する。ステップ105で、転置化される前の配列
の要素への参照を、転置化した配列への参照となるよう
に変更する。

Description

【発明の詳細な説明】
【0001】
【産業上の利用分野】本発明はループ変換方法に係り、
特に、一度に2つ分のデータをロードまたはストアする
命令を持つプロセッサに対して、多次元配列にアクセス
するループを高速に実行するオブジェクトコードを生成
するためのループ変換方法に関する。
【0002】
【従来の技術】コンパイラが生成するオブジェクトコー
ドの実行時の効率を向上させる最適化技術が従来より種
々提案されている。中でも、プログラム中で実行頻度が
高く、実行時間の多くの割合を占める部分はループであ
るので、ループの最適化手法が特に重要である。これら
従来のループ最適化技法については、佐々正孝著「プロ
グラミング言語処理系」(岩波講座ソフトウェア科学
5,1989年)459頁から493頁や、笠原博徳著
「並列処理技術」(コロナ社、1991年)113頁か
ら128頁などに記載されている。
【0003】一方、ハードウェアの面からもオブジェク
トコードの実行を高速化する方式が提案されている。そ
の一つに、スーパースカラ方式によるプロセッサがあ
る。スーパースカラプロセッサは、連続する複数の命令
(2または4)を同時にフェッチし、それらが並列に実
行可能であれば並列実行する。
【0004】スーパースカラ方式では並列実行可能な場
合だけ並列に実行するので、プロセッサを高速に動作さ
せるには、実行されるオブジェクトプログラム内にそれ
だけの並列性が存在することが必要である。例えば、あ
る命令で計算した値を直後の命令で使用する場合、この
二つの命令は並列には実行できない。そこで、RORT
RANやCのような高級言語で書かれたプログラムをコ
ンパイルして、スーパースカラプロセッサで実行しよう
とする場合、ソースプログラムに並列性が陽に現れてい
ない場合は、コンパイラが、ソースプログラムを機械語
に翻訳する際に、並列性を引き出すような最適化を行う
ことが普通である。特にループ部分に関しては並列性の
引き出しが顕著な効果をあげる。
【0005】例えば、以下のFORTRANの3重ルー
プを考えてみる。 DO 8 I=1,256 …(1) R(I,I) = 1.DO /R(I,I) …(2) DO 8 J = I+1, 256 …(3) R(J,I) = R(J,I)*R(I,I) …(4) DO 8 K = I+1, 256 …(5) R(J,K) = R(J,K) - R(J,I)*R(I,K) …(6) 8 CONTINUE このプログラムの実行で、最も実行回数の多いのは、ル
ープの最も内側の部分、すなわち(6)の文である。した
がって、このプログラムの最適化(並列化)はこの部分
に対して行うのが最も効果的である。(6)の文は、配列
のアドレス計算などを無視すると、以下の5つの命令に
よって実行される。 R(J,K)のロード …(8) R(I,K)のロード …(9) R(J,I)*R(I,K)の計算 …(10) R(J,K)-((10)の結果)の計算 …(11) ((11)の結果)をR(J,K)へストア …(12) R(J,I)のロードが含まれていないのは、この式の値がル
ープ中で変わらないので、ループ外で最初に一度ロード
しておけば、ループ内ではロードする必要がないからで
ある。
【0006】上の5つの命令のうち、並列に実行できる
のは(8)と(9)だけである。その他の命令はいずれもそれ
以前の命令の結果を使っているため、並列には実行でき
ない。よって同時に複数命令を発行できるというスーパ
ースカラプロセッサの特性はほとんど活かされていない
ことになる。
【0007】このようなプログラムから並列性を引き出
す手法の1つにループ展開がある。ループ展開とは、ル
ープ内部を複数コピーして展開し、ループ反復を減らす
とともに、ループ内部の独立した命令を増やすことによ
り並列実行の可能性を増加させるような最適化である。
例えば、さきほどのプログラムでは、最も内側のループ
を2倍に展開することにより、次のように展開できる。
(最も内側のループのみを示す。Kの値は2ずつ増える
ことに注意)。 DO 8 K = I+1, 256, 2 …(13) R(J,K) = R(J,K) - R(J,I)*R(I,K) …(14) R(J,K+1) = R(J,K+1) - R(J,I)*R(I,K+1) …(15) 8 CONTINUE …(16) この場合、ループ中のステートメント(14)と(15)で実行
される命令列は以下の通りである。 R(J,K)のロード …(17) R(I,K)のロード …(18) R(J,I)*R(I,K)の計算 …(19) R(J,K)-((19)の結果)の計算 …(20) ((20)の結果)をR(J,K)へストア …(21) R(J,K+1)のロード …(22) R(I,K+1)のロード …(23) R(J,I)*R(I,K+1)の計算 …(24) R(J,K+1)-((24)の結果)の計算 …(25) ((25)の結果)をR(J,K+1)へストア …(26) これらの命令のうち、(17)と(22)、(18)と(23)、(19)と
(24)、…は互いに独立であるので、(論理的には)並列
に実行可能である。つまり、ループ展開によりプログラ
ムの並列性を上げることがする。
【0008】しかし、論理的には並列実行可能であって
も、プロセッサのハードウェア的制約により命令が並列
実行できない場合がある。すなわち2つの命令が同一の
実行ユニット(加算器、乗算器、メモリポートなど)を
競合して使用する場合、2つの命令は並列実行できな
い。たとえば加算命令と加算命令、ロード命令とロード
命令、ロード命令とストア命令などである。上記命令列
の場合、(17)と(22)、(18)と(23)などはともにロード命
令であるので物理的に並列実行できない。上記の(17)か
ら(26)の命令列では、10個の命令のうち6つまでが
ロードまたはストア命令であるので十分な並列性が得ら
れない。一般のプログラムではこのようにロード・スト
アが高速化のボトルネックとなることが多い。
【0009】このような問題を解決するため、1つの命
令で2つのデータを一度にロードまたはストアする命令
を持つプロセッサがある。(ただしロードまたはストア
すべきデータがメモリ上に連続的に配置されていなけれ
ばならない。またロードとストアは同時には実行できな
い。)この命令を使えば、ロード・ストア命令数が減
り、よって実行ユニット(メモリポート)の競合の可能
性を減らすことができる。
【0010】
【発明が解決しようとする課題】上記従来技術で述べ
た、一度に2つ分のデータをロードまたはストアする命
令は、ロードまたはストアすべき2つのデータがメモリ
上で連続領域に配置されていなければならない。ところ
が、ループ展開を行っても、ロードまたはストアするデ
ータが必ずしも連続的に配置されているとは限らない。
【0011】例えばループ展開後の命令列((17)から(2
6))でロードするデータは、R(J,K),R(J,K+1),R(J,K+
2),R(J,K+2)の4つであるが、これらはメモリ上では連
続していない。これら4つの参照は右側の添字が連続的
に変化しているが、FORTRANの多次元配列は、R
(1,1),R(2,1),R(3,1),…というように、最も左側の添字
が変化しながらメモリに配置されるからである(逆にC
言語では添字の右側から変わるように配置される)。ま
た、ストアされるデータはR(J,K),R(J,K+1)の2つであ
るが、これらもメモリ上では連続していない。したがっ
て例のプログラムは、一度に2つ分のデータをロードま
たはストアする命令があってもそれを有効利用できな
い。したがって、ロード/ストアのボトルネックは解消
されないままである。
【0012】このような問題を解決する一つの方法とし
て、公知文献にも記載があるように、ループ交換(ルー
プインタチェンジ)という最適化手法がある。ループ交
換は、多重ループがあったとき、内側と外側のループを
入れ換える手法である。しかし、この手法はすべてのル
ープに適用できるわけではない。ループ交換によりプロ
グラムの意味(実行結果)が変わってしまう場合は適用
できない。例のループの場合も内側のループとその外側
のループを交換すると、プログラムの意味が変わってし
まう。
【0013】本発明の目的は、一度に2つ分のデータを
ロードまたはストアする命令を持つプロセッサに対し
て、例のように、多次元配列へのアクセスがあるループ
において、そのような命令を有効利用し、ロードまたは
ストア命令数を減らすようなループ変換方法を与えるこ
とにある。
【0014】
【課題を解決するための手段】上記目的は、ループ内で
連続的にアクセスする配列要素が、メモリ上でも連続的
に配置されるように、配列の内容を配置し直すことで達
成される。すなわち、ループネスト中で、時間的に連続
的にアクセスされる配列要素が、空間的には連続的にア
クセスされない配列を選択するステップと、選択された
配列全体を別の配列に複写するコードを、該ループネス
トの前に挿入するステップと、該ループネスト中での元
の配列要素へのアクセスコードを、複写先の配列要素へ
のアクセスコードに置換するステップと、必要に応じ
て、複写先の配列を、もとの配列に複写し直すコード
を、該ループネストの後に挿入するステップ、を有する
ループ変換方法により達成される。
【0015】上記の複写では、もとの配列をA、複写先
の配列をBとしたとき(ともにn次元配列とする)、F
ORTRANのように1番目の次元(最も左側)の添字
が連続的に変化するようにメモリ空間上に配置され、し
かもループ内ではi番目(i≠1)の次元の添字が連続
的に変化しながら配列にアクセスする場合には、 A(I1,I2,…,Ii,…,In)=B(Ii,I2
…,I1,…,In) が、すべての配列要素に対して満たされるようにAから
Bへ複写する。
【0016】一方、C言語のように最後の次元(最も右
側)の添字が連続的に変化するようにメモリ空間上に配
置される場合には、 A(I1,I2,…,Ii,…,In)=B(I1,I2
…,In,…,Ii,) が、すべての配列要素に対して満たされるようにAから
Bへ複写する。
【0017】また、上記配列を選択するステップでは、
少なくともループネスト中ですべての配列要素が2回以
上アクセスされるような配列を選択する。
【0018】
【作用】従来技術で示したループを例として説明する。
ループ展開後、最深のループ1回の繰り返しでアクセス
する配列要素は、R(J,K),R(J,K+1),R(J,K+2),R(J,K+3)
であり、配列の2番目の次元(右側)の添字が変化して
いる。一方、FORTRANの2次元配列は、1番目の
次元(左側)の添字が一番速く変化するようにメモリ空
間上に配置される。
【0019】そこで、まず元の配列Rを、1番目と2番
目の添字を交換して別の配列Xへ複写するコードを目的
のループの直前に挿入する。次に、目的のループ内で、
配列Rの要素を参照する箇所があれば、それを対応する
配列Xの要素を参照するように置き換える。たとえば、
R(J,K)をX(K,J)で置き換える。置換により目的のループ
は以下のように変換される。 DO 8 I=1,256 X(I,I) = 1.DO / X(I,I) DO 8 J = I+1, 256 X(I,J) = X(I,J) * X(I,I) DO 8 K = I+1, 256, 2 X(K, J) = X(K,J) - X(I,J) * X(K,I) X(K+1,J) = X(K+1,J) - X(I,J) * X(K+1,I) 8 CONTINUE そして配列Xを、1番目と2番目の添字を交換して元の
配列Rへ複写するコードを目的のループの直後に挿入す
る。
【0020】ループ変換後、目的のループの最も内側で
ロードされるデータは、X(K,J),X(K+1,J),X(K+2,J),X(K
+3,J)の4つである。これらはそれぞれメモリの連続領
域に配置されている。したがって、たとえばX(K,J)とX
(K+1,J)や、X(K,I)とX(K+1,I)を1度にロードできる。
必要なロード命令の数が半分で済む。ストアについても
同様に半分の命令数で済む。
【0021】上記ループ変換では、目的のループネスト
の前後に配列を複写するコードが挿入されるため、実行
時に複写によるオーバーヘッドがある。しかし、複写は
配列Xの全要素が1回だけアクセスされるのに対し、目
的のループネストでは、3重ループネストであるため全
要素が256回アクセスされている。すなわち、目的の
ループネスト中のアクセスの方が実行時間の点でよりク
リティカルな部分であり、配列複写のオーバーヘッドは
無視できる。
【0022】
【実施例】以下の本発明の一実施例を説明する。
【0023】図2は本発明に基づくCコンパイラが稼働
する計算機システムの構成図である。計算機システムは
CPU201、主記憶装置202、外部記憶装置20
3、ディスプレイ装置204、キーボード205より構
成されている。キーボード205より、ユーザからのコ
ンパイラ起動命令を受け付ける。コンパイル終了メッセ
ージやエラーメッセージはディスプレイ装置204に表
示される。外部記憶装置203にはCソースプログラム
206と、オブジェクトプログラム207が格納され
る。主記憶装置202にはコンパイル過程で必要となる
中間語208、シンボルテープ209、ループ内配列参
照テーブルテーブル210、およびループテーブル21
1が格納される。コンパイル処理はCPU201によっ
て制御される。
【0024】図3はコンパイラの処理を示すフローチャ
ートである。コンパイルは語彙解析301、構文解析3
02、転置化303、最適化304、コード生成305
の順に進む。このうち語彙解析、構文解析、最適化、コ
ード生成は従来のコンパイラにおける処理と同じである
ので、以下、簡単に説明する。
【0025】(ステップ301)ステップ301の語彙
解析では、単に文字の列として格納されているCソース
プログラムを、単語(lexicon)の列にする。語彙解析
の方法については例えばAHo他著「コンパイラI−原理
・技法・ツール」(サイエンス社)に記載がある。
【0026】図4はCソースプログラムの例である。こ
れを語彙解析とすると、図5のような単語の列となる。
図5で、各単語は種別501と字句502の組で表現さ
れ、また各単語はソースプログラムの出現順に並んでい
る。種別のkeywordはプログラムのキーワード、idは識
別子、puncは区切り記号、numは数字を表す。
【0027】(ステップ302)ステップ302におい
て単語の列を解析する。構文解析は解析される文が宣言
文であるか実行文であるかによって処理が異なる。宣言
文に対しては、宣言される識別子をシンボルテーブルに
登録する。実行文に対しては中間語を作成する。構文解
析の方法、シンボルテーブルの作成方法、中間語の作成
方法についてはやはり前記文献に記載がある。
【0028】シンボルテーブルの例を図6に示す(これ
は図4のプログラムに対応している)。図6のインボル
テーブルに登録されている情報は名称601、出現位置
602、型603、転置化フラグ604等である。名称
601は識別子の名称、出現位置602は識別子が宣言
された位置(関数内か関数外か)を表す。型603は識
別子の型を表し、たとえば「array(int,200,300」は
「要素型がintで要素数が300*200の(2次元)
配列」という型を表現する。転置化フラグ604は後述
する転置化処理303で設定されるフラグであり、最初
はすべてオフとなっている。
【0029】中間語の例を図7に示す(これも図4のプ
ログラムに対応している)。図7の中間語は木で表現さ
れている。木はノード(節)とエッジ(辺)の集合であ
る。計算機のメモリ上では、ノードは一定長または可変
長のメモリ領域で、エッジはその領域の番地を表すポイ
ンタとして表現されるが、図7では見やすさのため、ノ
ードは四角で、エッジはそれらを結ぶ線で表す。各ノー
ドは1つの親ノードと0個以上の子ノードを指す(ただ
しルートと呼ばれる特別なノードだけは親ノードを指さ
ない)。図では各ノードから上に延びたエッジが親ノー
ドを、下に延びたエッジが子ノードを指す。子は左から
第1子、第2子、…と呼ぶ。たとえば「{}」(703)の
親ノードは「func」(701)であり、子ノードは「for」(7
04)である。ルートノードは「func」(701)である。木は
プログラムの論理構造を表現するのに適しているので多
くのコンパイラで用いられている。
【0030】(ステップ303)転置化処理を行う。詳
しくは後述する。
【0031】(ステップ304)ステップ304では、
木構造で表現された実行文の部分を走査する。そして冗
長な部分を見つけてその冗長部分を削除するなどの最適
化処理を行う。この最適化処理はやはり前記文献に記載
があり、また本発明の本質的部分と無関係であるのでこ
れ以上の説明は省略する。
【0032】(ステップ305)ステップ305では、
アセンブリ言語表現されたオブジェクトプログラムを生
成し、オブジェクトファイル207に出力する(機械語
表現のオブジェクトモジュールを生成するコンパイラも
ある)。シンボルテーブルからはアセンブリ言語の領域
定義命令や定数定義命令を生成し、中間語からはアセン
ブリ言語の機械語命令を生成する。このコード生成処理
も本発明の本質的部分と無関係であり、これ以上の説明
は省略する。
【0033】次に本発明の特徴であるステップ303の
処理について詳しく説明する。
【0034】図1は転置化303をさらに詳しくしたフ
ローチャートである。転置化処理は、ループ構造の認識
101、ループ内配列参照の解析102、転置化対象配
列の選択103、配列コピーコードの生成104、配列
要素参照の転置化配列参照への変更105の順で進む。
以下これらの処理を具体的に説明していく。
【0035】(ステップ101)まずステップ101で
ループ構造の認識を行う。この処理では中間語を走査
し、ループを表すノードを見つけ、そのループで繰り返
し実行される文(これを以降単に「ループ実行文」と呼
ぶ)を認識し、それをループテーブル211に登録す
る。C言語でループを表すノードはfor,whileなどであ
る。ループ認識処理を図7の中間語の例で示す。木のル
ートから走査を始める。ルートのfunc(701)は関数定義
を表し、その第1子が関数名mainを、第2子が関数本体
を表す。第2子は{}(703)である。{}の第1子に移
ると、ループノードの1種であるfor(704)が見つかる
(最初のfor文)。forノードで実行される文を表すのは
第4子である(第1子は初期値設定文、第2子は繰り返
し判定文、第3子は制御変数更新文である。後述)の
で、第4子に移る。第4子のfor(705)は再びforノード
である(2番目のfor文)。そこでさらにその第4子へ
移ると、再びforノード(706)である3番目のfor文)の
でさらにその第4子へ移る。第4子は{}(707)であ
り、さらに{}(707)の子は=(707)である(=は代入を
表すノードである)。したがって704以下のループネス
トは3重ループであり、そのループ実行文はノード708
で表されることがわかる。
【0036】ループテーブルの構造を図10に示す。各
ループについて、ループ番号1001、ノード1002、制御変
数1003、子ループリスト1004、実行文リスト1005を、繰
り返し回数1006を登録する。ループ番号は出現順に1,2,
3,…とつける。ノードはそのループを表すノードであ
る。ループ制御変数は、ループノードの第1子で定義さ
れ、第2子で比較され、第3子で1だけ加算される変数
である。例えばforノード(706)の場合は、変数kが、第
1子の=(715)で定義され、第2子の<(716)で比較さ
れ、第3子の++(717)で1だけ加算されている。したが
ってkがループ制御変数となる。子ループリストはその
ループに直接含まれるループの番号をリストしたもので
ある。実行文リストはそのループに直接含まれる実行文
のノードをリストしたものである。例えばforノード(70
6)は代入ノード=(708)を実行文として含む。繰り返し
回数は、制御変数の動く範囲、すなわち最終値−初期値
+1である。例えばforノード(706)の場合はkの初期値
は0、最終値は299であるので(ループはk<300が成り
立っているあいだ繰り返すので、kの最終値は299)、
繰り返し回数は300となる。以上でループ構造の認識が
終わる。
【0037】(ステップ102)次にステップ102
で、ループ内の配列要素参照解析を行う。この処理では
ループ実行文の中間語を走査し、配列要素参照ノードを
見つけ、配列名、添字式、参照状況などを調べ、結果を
配列要素参照テーブル210に登録する。この処理を図7
の中間語の例を用いて説明する。この中間語では、配列
要素参照ノード([]で示される)のうち、第2子がよ
り右側の次元の添字を、第1子がより左側の次元の添字
または配列名を表す。また代入ノード(=で示される)
の第1子が代入先(定義側)を、第2子が代入元(使用
側)を表す。図7の例におけるループ実行文はノード70
8の代入文であるのでここから処理を始める。708の第1
子は[](709)であり、その第2子はj(710)である。し
たがってこの配列要素式の最も右側の添字はjである。
[](709)の第1子は再び[](711)であり、その第2子
はk(712)である。したがってこの配列要素式の右から2
番めの添字はkである。[](711)の第1子はa(713)で
あり、これは配列名である。以上をまとめると、=(70
9)以下の配列参照式の配列名はa、配列次元は2、1次
元目(最も左)の添字式はk、2次元目の添字式はj、
であることがわかる。またこの配列参照式は代入ノード
=(708)の第1子であるので、定義側である。=(708)の
第2子の配列要素参照式についても同様の解析を行う。
【0038】以上のような解析を行って図8に示す配列
要素参照テーブルを作成する。配列参照テーブルは実行
文中の各配列参照式について、その配列名801、次元数8
02、添字式リスト803(各次元の添字式をリストしたも
の)、参照状況(定義・使用の区別)、ループリスト
(該配列要素式を含むループノードをリストしたもの)
を保持する。
【0039】(ステップ103)次にステップ103
で、転置化の対象とする配列を選ぶ。ここでは配列要素
参照テーブルに出現する配列(配列名)ごとに、転置化
フラグcおよび転置する次元pを求める。c=falseま
たはp=0であればその配列は転置化の対象としない。
与えられた配列に対してcとpを求めるアルゴリズム
を、図9のフローチャートを使って説明する。例として
図8の配列参照式テーブルと図7の中間語を用いる。図
8のテーブルに出現する配列はaだけであるので、aに
対するcとpを求める。
【0040】(ステップ901)c=オフ,p=0とす
る。
【0041】(ステッ902)与えられた配列に対し
て、まだ処理していない配列要素参照式があるかを調べ
る。もしなければ終了する。あればそのうちの1つの参
照式をとりだしてステップ903へ進む。配列aの場合
は2つの参照式があるのでまず1つめの参照式806を取
り出す。
【0042】(ステップ903)参照式の添字リストの
中に、最も内側のループの制御変数があるかを調べる。
なければステップ902に戻る。あればステップ904
へ進む。最も内側のループは、ループリストの中の最後
(最も右側)のループ番号で示され、その制御変数はル
ープテーブルの制御変数903で示される。参照式80
6の場合、ノードリストの最後のループは1であり、そ
の制御変数はkである。参照式806の添字式リストに
は先頭にkがあるのでステップ904へ進む。
【0043】(ステップ904)最も内側のループ制御
変数を含む添字式の次元をqとする。参照式806の添
字式リストではkが1番目にリストされているので、q
=1である。
【0044】(ステップ905)qが参照式の次元数と
等しいか、すなわちqが最も右側の次元であるかを調べ
る。そうであればc=falseとして(ステップ90
6)、終了する。参照式806の場合はq=1、次元数
=2であるのでステップ907へ進む。
【0045】(ステップ907)p=0かまたはp=q
が成立するかを調べる。成立すればステップ908へ進
み、しなければc=falseとして終了する。参照式の場
合はp=0であるのでステップ908へ進む。
【0046】(ステップ908)参照式で指されるメモ
リロケーションが、ループ中で2回以上アクセスされる
かを調べる。されればc=true(ステップ909)と
し、されなければcはそのままにしてステップ902へ
戻る。ループ中で2回以上アクセスされるかどうかは、
ループの総繰り返し回数と、参照式が指すメモリロケー
ションの数を比較して行う。前者の方が大きければ2回
以上アクセスされると判断する。ループの総繰り返し回
数はループリストで示されるループの繰り返し回数を掛
け合わせたものである。参照式の指すメモリロケーショ
ンの数は、各次元の添字式の動く範囲をすべての次元に
ついて掛け合わせたものである。参照式806の場合、
ループの総繰り返し回数は1024*200*300=
61440000である(ループ1,2,3の繰り返し
回数はループテーブルからそれぞれ1024,200,
300であることがわかる)。一方、参照式の指すメモ
リロケーションの数は300*200=60000であ
る(1次元目の添字式であるkは0から299を、2時
限目の添字式であるjは0から199を動く)。前者の
方が大きいので、参照式806で指されるメモリロケー
ションはループ中で2回以上アクセスされる。よってc
=trueとなる。
【0047】以上で参照806の処理が終る。次にステ
ップ902に戻り、参照807についても同様にステッ
プ903からステップ908の処理が行われる。そして
再びステップ903に戻り、aに対する参照はもう残っ
てないので終了する。終了した時点で、p=1,c=tr
ueであるのでaは転置化の対象となる。
【0048】以上、ステップ103の説明した。
【0049】(ステップ104)次にステップ104
で、転置化対象となった配列のコピーコード生成を行
う。
【0050】まず、コピー先の配列シンボルを生成し、
シンボルテープに登録する。シンボルの名前はユニーク
な(他のシンボル名と一致しない)名前とする。シンボ
ルの型は、転置化対象の配列の型をarray(e,N1,…,Np,
…,Nm)、転置する次元をpとすると、array(e,N1,…,N
m,…Np)とする。図11に、例題プログラムの転置化処
理後のシンボルテーブルを示す。配列a(605)が転置化
対象となっているので、これに対してコピー先配列シン
ボルta(606)を生成されている。aの型はarray(int,30
0,200)、p=1であるので、taの型はarray(int,200,30
0)となる。また、転置化対象の配列の転置化フラグ(60
4)をオンにし、転置化配列フィールド(607)にtaを設定
し、転置化次元フィールド(608)にpの値、すなわち1
を設定する。
【0051】次に転置化対象配列をコピー先配列に転置
しながらコピーする中間語を生成する。転置しながらコ
ピーするノードはtcopyノードの第1子はコピー先の配
列名、第2子はコピー元の配列名とする。このノード
を、ループネストを表すノードの直前または直後または
両方に挿入する。この処理を図13のフローチャートで
説明する。
【0052】(ステップ1301)配列要素参照テーブ
ルにおける、各参照式の参照状況を調べる。参照状況が
「使用」になっている参照式が少なくとも1つあればス
テップ1302へ進み、なければステップ1303へ進
む。図8の例(例題プログラム)では参照式807の参
照状況が「使用」となっているのでステップ1302へ
進む。
【0053】(ステップ1302)新たに生成した配列
名を第1子、転置化対象の配列名を第2子とするtcopy
ノードを作り、ループネストの直前に挿入する。例題プ
ログラムの場合を図13に示す。tcopyノード(1401)が
挿入され、その第1子はta(1402)、第2子がa(1403)で
ある。
【0054】(ステップ1303)各参照式の参照状況
を調べ、参照状況が「定義」になっている参照式が少な
くとも1つあればステップ1304へ進み、なければス
テップ終了する。図8の例では参照式806の参照状況
が「定義」となっているのでステップ1302へ進む。
【0055】(ステップ1304)新たに生成した配列
名を第2子、転置化対象の配列名を第1子とするtcopy
ノードを作り、ループネストの直後に挿入する。例題プ
ログラムの場合を同じく図13に示す。tcopyノード(14
04)が挿入され、その第2子はta(1406)、第1子がa(14
05)である。
【0056】図13のtcopyノードの表す処理をCプロ
グラムのイメージで示したのが図15である。図15
(a)はaからtaへのコピー、(b)はtaからaへのコ
ピーに対応する。tcopyノードを生成するのではなく、
図15のプログラムに対応する中間語を生成してもよ
い。
【0057】(ステップ105)次にステップ105
で、配列要素参照の転置化メンバ参照への変更を行う。
すなわち、ループネストに対応する中間語を再度走査
し、転置化フラグがオンである配列要素への参照が見つ
かったら、それを転置化した後の配列要素参照(コピー
先配列要素参照)に置き換える。例題プログラムの場
合、aへの参照をtaへの参照に置き換える。これを図1
3と図14を用いて説明する。図13で、forノード(70
4)が書き換え対象のループであるので、そこから走査を
始める。するとノード713で転置化フラグ(604)がオンで
ある配列aが見つかる。そこでaを転置化配列(607)で
示されるtaに置き換える。これを図14に示す(ノード1
410)。さらに転置化次元(608)で表される添字式を、最
も右側の添字式と交換する。すなわち、図13のノード
712で示される添字式を、最も右側の添字式と交換す
る。すなわち、図13のノード712で示されるk(第
1次元)とノード710で示されるj(最右次元)を交
換する。これを図14に示す(ノード1409とノード141
1)。以上で最初の置き換えが終わる。さらに木の走査を
続けると、ノード715で再びaが見つかるので、これも
同様に置換を行う。その結果が図14に示されている。
【0058】以上でステップ303の転置化処理の詳細
な説明を終わる。
【0059】ステップ303を終った時点での中間語お
よびシンボルテーブルの内容をCプログラムのソースイ
メージで表したのが図12である(本コンパイラがこの
ようなプログラムを生成・出力するわけではないが、出
力することもできる)。行1202では新たにコピー先配列
taの宣言がされている。これは図11のシンボルテーブ
ルの606のエントリのシンボルに対応している。また行1
206と行1212ではtcopyという文があるが、これは中間語
の1401,1404で示されるノードに対応している。また行1
210の代入文は配列aではなくtaを参照し、添字の順序
もソースプログラムと異なる。ステップ303以降の、ス
テップ304(最適化)およびステップ305(コード生成)
は、あたかも図12のCプログラムがソースプログラム
であったかのように処理を行う。この処理は従来のコン
パイラと同じである。
【0060】ステップ304で行われる最適化の中に、
ループ展開という最適化が従来からある。これはループ
1回の繰り返しで、本来の2回分(またはそれ以上)を
実行するようにプログラムを書き換えるものである。こ
れによりループの終了判定の回数が半分になるなどの効
果がある。図16のプログラムは図4の例題プログラム
を最も内側ループに関してループ展開したものである。
図16プログラムでは代入文が行1608と行1609の2つあ
るが、行1607で示されているようにkは2ずつ増加する
のでループの繰り返し回数は半分になる。また図17の
プログラムは図12のプログラムを同様に展開したもの
である。
【0061】次に図16と図17、および図18を用い
て、転置化処理を行わなかった場合と行った場合のプロ
グラムの振舞いを、配列アクセスの面から説明し、本実
施例の効果を示す。
【0062】図16のプログラムではループ実行文(16
08と1609)で4つの配列要素がアクセスされる。すなわ
ちa[k][j],a[k+1][j−1],a[k+
1][j],a[k+1][j−1]である。これらの
要素のメモリ上での位置を示したのが図18(a)であ
る。あるマイクロプロセッサでは、メモリ上で連続的に
配置されている2つまたはそれ以上のデータを1つの命
令で1度に読み出す(ロード)、もしくは書き込む(ス
トア)命令を持っている。図18では4つの要素のうち
a[k+1][j−1]とa[k+1][j]の2つは
隣接しているが、そのうちa[k+1][j−1]は使
用(ロード)であり、a[k+1][j]は定義(スト
ア)であるので上述の命令は使用できない。また他の要
素は隣接していない。したがってループ実行文中では各
要素に1つのロードまたはストア、計4つの命令が必要
となる。
【0063】次に図17のプログラムの転置化を行った
プログラムを考えてみる。図17のプログラムではルー
プ実行文(1709と1710)で同じく4つの配列要
素がアクセスされる。すなわちta[j][k],ta
[j][k+1],ta[j−1][k+1],ta[j−
1][k+2]である。これらの要素のメモリ上での位
置を示したのが図18(b)である。図から明らかなよ
うにta[j][k]とta[j][k+1]、およびta
[j−1][k+1]とta[j−1][k+2]は隣接
している。また前者2つはともにロードであり、後者2
つはストアである。よって前述の、1度に2つのデータ
をロード・ストアする命令がそれぞれ使え、計2命令で
済む。
【0064】以上示したように、本実施例では1度に2
つのデータをロードまたはストアする命令を有する計算
機(プロセッサ)に対して有利な命令列を生成すること
ができる。
【0065】
【発明の効果】本発明によれば、ループ中で時間的に連
続してアクセスされる配列要素が空間的にも連続的にア
クセスされるようになるため、1度に2つのデータをロ
ードまたはストアする命令を利用したオブジェクトコー
ドが生成できる。
【0066】また、本ループ変換方法によれば、ループ
交換できないループに対してもループ交換と同様の効果
を得ることができるという効果がある。
【0067】また、本ループ変換方法によれば、配列コ
ピーのオーバーヘッドが無視できる場合にしか変換がな
されないという効果がある。
【図面の簡単な説明】
【図1】配列転置化処理のフローチャート。
【図2】本発明のコンパイラが稼働する計算機システム
の構成図。
【図3】コンパイル処理のフローチャート。
【図4】例題プログラム。
【図5】図4のプログラムの語彙解析結果。
【図6】シンボルテーブルの例。
【図7】中間語の例。
【図8】配列要素参照テーブル。
【図9】配列を転置化対象とするかを判定するフローチ
ャート。
【図10】ループテーブル。
【図11】配列転置化処理後のシンボルテーブル。
【図12】変換後のプログラムイメージ。
【図13】コピーノード挿入処理フローチャート。
【図14】転置化後の中間語。
【図15】tcopyノードの処理。
【図16】図4のプログラムをループ展開したもの。
【図17】図12のプログラムをループ展開したもの。
【図18】ループ実行文でアクセスされる配列要素。
【符号の説明】
101…ループ構造の認識、102…ループ内配列参照
の解析、103…転置化対象とする配列の選択、104
…配列コピーコードの生成、105…配列要素参照の置
換。

Claims (6)

    【特許請求の範囲】
  1. 【請求項1】メモリ空間上に連続的に配置された、2個
    またはそれ以上の配列要素を、一度にロードまたはスト
    アする命令を有するマシンに対して、多次元配列にアク
    セスするループを変換する方法であって、 ループネストを認識するステップと、 転置複写する配列を選択するステップと、 該配列の全要素を別の配列に転置複写するコードを、該
    ループネストの前に挿入するステップと、 該ループ内での元の配列要素へのアクセスコードを、複
    写先の配列要素へのアクセスコードに変換するステッ
    プ、とを有するループ変換方法。
  2. 【請求項2】請求項1のループ変換方法であって、さら
    に複写先の配列を、もとの配列に転置複写するコード
    を、該ループネストの後に挿入するステップ、を含むル
    ープ変換方法。
  3. 【請求項3】請求項1のループ変換方法であって、転置
    複写する配列を選択するステップで選択される配列は、
    少なくとも該ループネスト中ですべての要素が2回以上
    参照される配列である、ループ変換方法。
  4. 【請求項4】請求項1のループ変換方法であって、転置
    複写は、もとの配列をA、複写先の配列をBとしたとき
    (A,Bはともにn次元配列)、ある自然数iに対し
    て、 A(I1,I2,…,Ii,In)=B(Ii,I2,…,I
    1,…,In) が、すべての配列要素に対して満たされるようにAから
    Bへ複写する、ループ変換方法。
  5. 【請求項5】請求項1のループ変換方法であって、転置
    複写は、もとの配列をA、複写先の配列をBとしたとき
    (A,Bはともにn次元配列)、ある自然数iに対し
    て、 A(I1,I2,…,Ii,In)=B(I1,I2,…,I
    n,…,Ii) が、すべての配列要素に対して満たされるようにAから
    Bへ複写する、ループ変換方法。
  6. 【請求項6】請求項1記載のループ変換方法を用いるコ
    ンパイラ。
JP5150130A 1992-06-22 1993-06-22 ループ変換方法 Pending JPH0675987A (ja)

Priority Applications (1)

Application Number Priority Date Filing Date Title
JP5150130A JPH0675987A (ja) 1992-06-22 1993-06-22 ループ変換方法

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
JP4-162519 1992-06-22
JP16251992 1992-06-22
JP5150130A JPH0675987A (ja) 1992-06-22 1993-06-22 ループ変換方法

Publications (1)

Publication Number Publication Date
JPH0675987A true JPH0675987A (ja) 1994-03-18

Family

ID=26479827

Family Applications (1)

Application Number Title Priority Date Filing Date
JP5150130A Pending JPH0675987A (ja) 1992-06-22 1993-06-22 ループ変換方法

Country Status (1)

Country Link
JP (1) JPH0675987A (ja)

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2019185486A (ja) * 2018-04-12 2019-10-24 富士通株式会社 コード変換装置、コード変換方法、及びコード変換プログラム

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2019185486A (ja) * 2018-04-12 2019-10-24 富士通株式会社 コード変換装置、コード変換方法、及びコード変換プログラム

Similar Documents

Publication Publication Date Title
US5671416A (en) Apparatus and a method for searching and modifying source code of a computer program
US8122442B2 (en) Method and system for array optimization
US5355494A (en) Compiler for performing incremental live variable analysis for data-parallel programs
Hall Managing interprocedural optimization
US9015690B2 (en) Proactive loop fusion of non-adjacent loops with intervening control flow instructions
US20080178149A1 (en) Inferencing types of variables in a dynamically typed language
JP5118745B2 (ja) メモリアクセス命令のベクトル化
JPH06103463B2 (ja) コード生成方法
Kudriavtsev et al. Generation of permutations for SIMD processors
Blindell Instruction Selection
US6016398A (en) Method for using static single assignment to color out artificial register dependencies
US6059841A (en) Updating data dependencies for loop strip mining
Elphick et al. Partial evaluation of MATLAB
US6055627A (en) Compiling method of accessing a multi-dimensional array and system therefor
Boute Functional declarative language design and predicate calculus: a practical approach
JPH0675987A (ja) ループ変換方法
Corbera et al. A framework to capture dynamic data structures in pointer-based codes
US20040003379A1 (en) Compiler, operation processing system and operation processing method
JPH10320212A (ja) キャッシュ向け最適化方法
Šinkarovs et al. Parallel scan as a multidimensional array problem
US7676799B1 (en) Address simplification by binary transformation
GB2420638A (en) Method of substituting code fragments in Internal Representation
Abe et al. Model checking stencil computations written in a partitioned global address space language
Cockshott et al. Orthogonal parallel processing in vector Pascal
Iannetta et al. Compiling pattern matching to in-place modifications