[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

17.13 操作の相対的コストの記述

以下のマクロ群を使って、ターゲットマシンの色々な操作の相対的な 速度を記述する。

CONST_COSTS (x, code, outer_code)

C の switch 文の一部を定義する。この switch 文の 断片では、定数 RTL 式の相対的なコストを記述する。 式コード const_intconstsymbol_reflabel_refconst_double にそれぞれ対応する case ラベル が含まれていなければならない。各ケースでは、最終的には return 文に 達して、その種類の定数値を式の中で使うことの相対的なコストを返さなくては ならない。コストは、定数の具体的な値に依存する可能性がある。この定数は x を調べるのに使うことができる。そして、それを含む式の RTX コードは outer_code に入っている。

code は式コードである。これは冗長である。というのは、 GET_CODE (x) で求めることができるからである。

RTX_COSTS (x, code, outer_code)

CONST_COSTS とほぼ同じだが、違いは非定数 RTL 式に適用されること である。これを使って、例えば、乗算命令のコストがどれぐらいかを 示すことができる。このマクロを書くときは、定数 COSTS_N_INSNS (n) を使って、n 個の高速な命令に 等しいコストを指定することができる。outer_code は、 x が含まれている式のコードである。

このマクロはオプションであり、デフォルトのコストの想定がターゲット機種に 適しているなら定義しないこと。

DEFAULT_RTX_COSTS (x, code, outer_code)

このマクロが定義されていると、RTX_COSTSCONST_COSTS マクロで取り扱われない場合に呼び出される。 これにより、case のラベルをマクロにいれる必要がなくなるが、 そのコード、あるいはそれを呼び出す関数は、x 中の RTL は 既に取り扱われたことの内どんな型にでもなりうることを保証しなければならない。 引数は RTX_COSTS のものと同じである。そしてこのマクロは、 取扱いが可能な任意の RTL 式のコストを与える return 文を 実行する必要がある。このマクロが値を返さない RTL に対しては、 デフォルトのコスト計算が使われる。

このマクロはオプションである。デフォルトのコスト想定がターゲット機種に てきせつであるなら定義しないこと。

ADDRESS_COST (address)

address を含むアドレッシングモードのコストを与える式である。 定義されていないと、コストは address 式と CONST_COSTS の 値から計算される。

ほとんどの CISC マシンでは、デフォルトのコストが、そのアドレッシング モードの実際のコストの良い近似になっている。 だが、RISC マシンでは、普通、全ての命令が同じ命令長と実行時間になる。 このため、全てのアドレスのコストが等しくなる。

アドレス形式が複数ある場合には、コストが最小の形式が使われる。 複数の形式が同じ最小のコストになる場合には、最も複雑なものが使われる。

例えば、あるレジスタとある定数の和に等しいアドレスが同じ基本ブロック内 で二回使われたとしよう。このマクロが定義されていないときは、このアドレスは あるレジスタで計算され、メモリ参照はそのレジスタを通した間接参照になる。 この和を含むアドレッシングモードのコストが、単純な間接参照のコストより 高くない機種では、これにより、命令が一個追加され、恐らく追加のレジスタも 一個必要になるだろう。このマクロで適切に指定すると、こういう機種での オーバーヘッドを消去する。

このマクロは、ループの強度削減においても似たような使い方をされる。

address はアドレスとして有効である必要はない。 その場合、コストは関係ないのでどんな値にもなりうる。無効なアドレスに 別のコストを割り当てる必要はない。

レジスタ一個よりも多くのものを含むアドレスの計算コストがレジスタを 一個しか含まないアドレスのコストと同じである機種では、 ADDRESS_COST を定義してそのことを反映させると、ADDRESS_COST がそのように定義されていなければ一つしか生存できないような あるコードの範囲で、二つのレジスタが生存できるようになる。 この効果はこのマクロを定義するときに考慮に入れる必要がある。 コストが等しくなるのは、おそらく、たくさんレジスタのある機種上で、 異なる数のレジスタを含むアドレスの場合だけになるはずである。

このマクロは普通は、定義しないか、定数として定義されるかのどちらかである。

REGISTER_MOVE_COST (from, to)

クラス from のレジスタから、クラス to のレジスタへデータを 移動するコストを表す式。クラスは、GENERAL_REGS のような 列挙値で表される。2 という値がデフォルトである。 その他の値は、2 に相対的な値として解釈される。

fromto と同じである場合、コストが常に 2 である 必要はない。機種によっては、汎用レジスタでないレジスタ間での移動が 高くつくものがある。

再ロードパスで二つのハードレジスタを使った一個の set から なる insn を見つけると、それらのレジスタのクラスに REGISTER_MOVE_COST を適用すると 2 という値を返すなら、再ロードパスはその insn の制約が 満たされることを保証するための検査を行なわない。 レジスタ移動のコストを 2 以外にすると再ロードパスは制約が満たされることを 検証する。‘movm’ というパターンの制約がこのようなコピーを 許さないのであれば、コストを 2 以外にすべきである。

MEMORY_MOVE_COST (mode, class, in)

モード mode のデータをクラス class のレジスタとメモリの間で 移動するコストを表す式。in は、値がメモリに書き込まれるべきものなら ゼロであり、読み出すべきものならゼロでない値となる。 このコストは、REGISTER_MOVE_COST のコストに相対的な値である。 レジスタとメモリの間の移動が、二つのレジスタ間のものより高く付くなら、 このマクロが相対的なコストを表すように定義すべきである。

このマクロを定義しない場合、GCC はデフォルトのコスト 4 に、 もしそれが必要であれば、第二の再ロードレジスタを経由して コピーするコストを足したものを使う。メモリと class のレジスタの 間でコピーをするのに第二の再ロードレジスタを必要とするが、 再ロードの機構が中間を経由してコピーするより複雑な場合は、 このマクロを定義して、そういう移動の実際のコストを反映させるようにする。

GCC は、第二の再ロードレジスタが必要な場合、memory_move_secondary_cost という関数を定義する。これは、第二の再ロードレジスタ経由のコピーによる コストを計算する。読者の機種では、メモリから第二のレジスタを使って 伝統的な方法でコピーを行うが、しかしデフォルトのベース値の 4 では 合わないという場合は、このマクロを定義して、この関数の結果に何か 他の値を加えるようにする。この関数への引数は、このマクロへの引数と 同じである。

BRANCH_COST

分岐命令のコストを表す C の式。1 という値がデフォルトである。 その他の値は 1 に対しての相対値として解釈される。

以下に示すマクロは、正確な相対的コストは指定せず、 ある動作が GNU CC が普通期待するよりも高くつくということだけを示す。

SLOW_BYTE_ACCESS

大きさがワードより小さなメモリをアクセスするのが、ワードをアクセスするより 速くないなら、すなわち、二個以上の命令を必要とするか、バイトのロードと (整合されている)ワードのロードの間でコストに差がないなら、 0 でない値を持つ C の式をこのマクロに定義する。

このマクロが定義されていない場合は、コンパイラはフィールドをアクセス するのに、それを含む最小のオブジェクトを探すことで行なう。 定義されていれば、アラインメントが許せば、全ワードのロードが使われる。 バイト単位のアクセスがワード単位のアクセスよりも高速でないかぎり、 ワード単位のアクセスが望ましい。というのは、 後続のメモリアクセスが、その構造体の同じワード内の異なるバイトに ある他のフィールドをアクセスする場合は、そのメモリ参照を 消去できるからである。

SLOW_ZERO_EXTEND

char または shortint へのゼロ拡張が、 デスティネーションがゼロであることがわかっているレジスタの 場合には高速に行なわれるなら、このマクロを定義する。

このマクロを定義する場合は、以下のような構造の RTL を 認識する命令パターンを持っていなければ成らない。

 
(set (strict_low_part (subreg:QI (reg:SI …) 0)) …)

HImode についても同様である。

SLOW_UNALIGNED_ACCESS

整合の取れていないアクセスのコストが整合しているアクセスのコストよりも 何倍も高い場合、例えばトラップハンドラでエミュレートされているような場合は、 このマクロを値 1 に定義すること。

このマクロがゼロでない場合は、GNU CC は、ブロック移動用のコードを 生成するとき STRICT_ALIGNMENT がゼロでないかの用に動作する。 これにより、非常にたくさんの命令が生成される可能性がある。 このため、整合の取れていないアクセスが、1 サイクルか 2 サイクル程度しか メモリアクセスの時間に加わらない場合は、このマクロをゼロでない値に 定義しないこと。

このマクロの値が常にゼロなら、定義する必要はない。

DONT_REDUCE_ADDR

このマクロを定義すると、メモリアドレスの強度削減が禁止される。 機種によっては、そういう強度削減は百害あって一利なしである。

MOVE_RATIO

スカラのメモリ-メモリ移動 insn の数の敷居値である。この値より小さい と、ある insn 列を、文字列移動命令やライブラリ呼出しの代わりに 生成する必要がある。 。この値を大きくすると必ずコードが速くなるが、いつかはコードサイズが 増大することによるコストが高くなる。

メモリ-メモリ移動命令がない機種では、このマクロは 対応する、メモリ-メモリ 命令列 の数を表す。

これを定義しない場合は、適切なデフォルトが使われる。

MOVE_BY_PIECES_P (size, alignment)

一個の C の式。この式は、メモリの塊を一つコピーするのに move_by_pieces が使われるかどうか、あるいは何か他のブロック移動のための機構が使われるか どうかを決定するのに使われる。move_by_pieces_ninsnsMOVE_RATIO より小さい値を返すなら、デフォルトは 1 になる。

MOVE_MAX_PIECES

一個の C の式。 move_by_pieces で、メモリをコピーするのに使われるロードあるいは ストアの最大単位を決定するのに使われる。 デフォルトは MOVE_MAX になる。

USE_LOAD_POST_INCREMENT (mode)

一個の C の式。 ロード・ポストインクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_POST_INCREMENT の値に なる。

USE_LOAD_POST_DECREMENT (mode)

一個の C の式。 ロード・ポストデクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_POST_DECREMENT の値に なる。

USE_LOAD_PRE_INCREMENT (mode)

一個の C の式。 ロード・プリインクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_PRE_INCREMENT の値に なる。

USE_LOAD_PRE_DECREMENT (mode)

一個の C の式。 ロード・プリインクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_PRE_INCREMENT の値に なる。

USE_STORE_POST_INCREMENT (mode)

一個の C の式。 ストア・ポストインクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_POST_INCREMENT の値に なる。

USE_STORE_POST_DECREMENT (mode)

一個の C の式。 ストア・ポストデクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_POST_DECREMENT の値に なる。

USE_STORE_PRE_INCREMENT (mode)

一個の C の式。 ストア・プリインクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_PRE_INCREMENT の値に なる。

USE_STORE_PRE_DECREMENT (mode)

一個の C の式。 ストア・プリデクリメントを、指定したモードに使うのが良いかどうかを 決めるのに使われる。デフォルトは HAVE_PRE_DECREMENT の値に なる。

NO_FUNCTION_CSE

定数の関数アドレスを呼び出すほうが、レジスタに保持されたアドレスを 呼び出すよりも効率が良いか同等なら、このマクロを定義する。

NO_RECURSIVE_FUNCTION_CSE

関数が自分自身を呼び出すのに、明示的なアドレスを使ったほうが、 レジスタに保持されているアドレスを呼び出すより効率が良いか同等なら、 このマクロを定義する。

ADJUST_COST (insn, link, dep_insn, cost)

一個の C の文(セミコロンなし)。この文は、整数変数 cost を、 insn との関係に基づいて更新する。 insn は、依存関係 link を通じて dep_insn に 依存する。 デフォルトでは、cost の調整はなんら行なわれない。 これは、例えば、スケジューラに対し、出力依存や逆依存は データ依存と同じコストは被らないことを指示するのに使うことができる。

ADJUST_PRIORITY (insn)

一個の C の文(セミコロンなし)。この文は整数のスケジューリング優先度 INSN_PRIORITY(insn) を更新する。 insn を早めに実行するには優先度を下げ、遅めに実行するには 優先度を上げる。insn のスケジューリング優先度を調整する 必要がなければこのマクロは定義しないこと。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html 1.78.