日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS MACRO コンパイラ
|
目次 | 索引 |
4.3 コードの最適化 |
MACRO コンパイラは,生成されるコードに対してさまざまな最適化を行います。デフォルトでは,VAXREGS を除き,すべての最適化を実行します (VAXREGS は OpenVMS Alpha システムでのみ使用できます)。これらのデフォルトの動作は,コマンド行の /OPTIMIZE スイッチで変更できます。有効なオプションは以下のとおりです。
注意 最適化にはコードの再配置や再スケジューリングが含まれているため, /NOOPTIMIZE を指定するとデバッグが容易になります。詳細は, 第 2.13.1 項 を参照してください。 |
4.3.1 VAXREGS を使用した最適化 ( OpenVMS Alpha のみ) |
VAXREGS を使用して最適化する場合は,すべてのルーチンで,使用しているレジスタがルーチン宣言 .CALL_ENTRY,.JSB_ENTRY, .JSB32_ENTRY で正しく宣言されていることを確認する必要があります。また,呼び出されるルーチンが必要とする VAX レジスタや変更する VAX レジスタを明確にする必要があります。デフォルトでは,呼び出されているどのルーチンでも入力として VAX レジスタを必要とせず, R0 と R1 以外のすべての VAX レジスタが呼び出しの前後で保護されるものと想定されます。使用されていることを宣言するには,次の例のように,コンパイラ指示文 .SET_REGISTERS の修飾子 READ および WRITTEN を使用します。
.SET_REGISTERS READ=<R3,R4>, WRITTEN=R5 JSB DO_SOMETHING_USEFUL |
この例では,コンパイラは, R3 と R4 がルーチン DO_SOMETHING_USEFUL に対する入力で必要であり, R5 がルーチンで上書きされることを認識します。レジスタの使用状況は, DO_SOMETHING_USEFUL のinput マスクを READ 修飾子として使用し, output マスクとscratch マスクを組み合わせたものを WRITE 修飾子として使用することで判断できます。
注意 ルーチンのエントリ・ポイントとルーチンの呼び出しの両方でレジスタを正しく宣言せずに VAXREGS 修飾子を使用すると,誤ったコードが生成されます。 |
4.4 共通ベース参照 |
OpenVMS Alpha システムでは,一般にデータ・セルを参照する場合,リンケージ・セクションからデータ・セル・アドレスをロードするための参照と,データ・セル自体の参照の,合計 2 回メモリを参照する必要があります。いくつかのデータ・セルが互いに近くにあり, ADDRESSES 最適化を使用した場合,コンパイラは共通のベース・アドレスをレジスタにロードし,個々のデータ・セルをベース・アドレスからのオフセットとして参照します。これにより,データ・セル・アドレスを個別にロードする必要がなくなります。これは,共通ベース参照と呼ばれます。
ADDRESSES 最適化が有効になっていると,コンパイラはローカルなデータ psect に対して自動的にこの最適化を実行します。コンパイラは,$PSECT_BASEn の形式のシンボルを生成して,ローカル psect のベースとして使用します。
外部データ psect に対して共通ベース参照を使用するためには,シンボルを共通ベースからのオフセットとして定義したプレフィックス・ファイルを作成する必要があります。 VAX MACRO アセンブラでは,シンボルを外部シンボルからのオフセットとして定義できないため,モジュールを OpenVMS VAX 用にアセンブルする際にはプレフィックス・ファイルは使用できません。
次の例は,共通ベース参照を使用するためにプレフィックス・ファイルを作成することの利点を示しています。次の内容を示します。
次の単純なコード・セクション (CODE.MAR) について考えます。これは,別のモジュール (DATA.MAR) のデータ・セルを参照しています。
4.4.1 共通ベース参照のためのプレフィックス・ファイルの作成
Module DATA.MAR: .PSECT DATA NOEXE BASE:: A:: .LONG 1 B:: .LONG 2 C:: .LONG 3 D:: .LONG 4 .END Module CODE.MAR: .PSECT CODE NOWRT E:: .CALL_ENTRY MOVL A,R1 MOVL B,R2 MOVL C,R3 MOVL D,R4 RET .END |
共通ベース参照を使用せずに CODE.MAR をコンパイルすると,次のコードが生成されます。
リンケージ・セクションに生成されるコード
.ADDRESS A .ADDRESS B .ADDRESS C .ADDRESS D |
コード・セクションに生成されるコード (プロローグ・コードとエピローグ・コードは除く)
LDQ R28, 40(R27) ;Load address of A from linkage section LDQ R26, 48(R27) ;Load address of B from linkage section LDQ R25, 56(R27) ;Load address of C from linkage section LDQ R24, 64(R27) ;Load address of D from linkage section LDL R1, (R28) ;Load value of A LDL R2, (R26) ;Load value of B LDL R3, (R25) ;Load value of C LDL R4, (R24) ;Load value of D |
外部データ・セルを共通のベース・アドレスからのオフセットとして定義したプレフィックス・ファイルを作成することで,コンパイラが外部参照に対して共通ベース参照を使用するようにすることができます。この例のプレフィックス・ファイルでは, BASE からの相対として A,B,C,D を定義しています。
A = BASE+0 B = BASE+4 C = BASE+8 D = BASE+12 |
このプレフィックス・ファイルと最適化 ADDRESSES を使用して CODE.MAR をコンパイルすると,次のコードが生成されます。
リンケージ・セクションに生成されるコード
.ADDRESS BASE ;Base of data psect |
コード・セクションに生成されるコード (プロローグ・コードとエピローグ・コードは除く)
LDQ R16, 40(R27) ;Load address of BASE from linkage section LDL R1, (R16) ;Load value of A LDL R2, 4(R16) ;Load value of B LDL R3, 8(R16) ;Load value of C LDL R4, 12(R16) ;Load value of D |
この例では,共通ベース参照によって,コード・セクションとリンケージ・セクションのサイズがどちらも小さくなり, 3 つのメモリ参照が除去されています。このように,プレフィックス・ファイルを作成し,外部データ・セルの共通ベース参照を有効にする方法は,多数のモジュールから使用されるデータ領域を定義した大きな単独のモジュールがある場合に有効です。
OpenVMS I64 システムでも, 第 4.4.1 項 に示した効果と同じ効果が得られますが,コード・シーケンスの詳細が異なります。同じコードに対して,次のような命令シーケンスが生成されます。
4.4.1.1 OpenVMS I64 システムでのコード・シーケンスの相違点
add r19 = D, r1 add r22 = C, r1 add r23 = B, r1 add r24 = A, r1 ld8 r19 = [r19] ld8 r24 = [r24] ld8 r22 = [r22] ld8 r23 = [r23] ld4 r4 = [r19] ld4 r9 = [r24] ld4 r3 = [r22] ld4 r28 = [r23] sxt4 r4 = r4 sxt4 r9 = r9 sxt4 r3 = r3 sxt4 r28 = r28 |
第 4.4.1 項 に示したプレフィックス・ファイルの方法を使用することで,メモリ・アクセスのほぼ半分が除去された命令シーケンスが得られます。
add r24 = BASE, r1 ld8 r24 = [r24] mov r23 = r24 ld4 r9 = [r24] adds r18 = 12, r24 adds r19 = 8, r24 adds r22 = 4, r24 adds r24 = 12, r24 ld4 r4 = [r24], -4 sxt4 r9 = r9 ld4 r3 = [r24], -4 sxt4 r4 = r4 sxt4 r3 = r3 ld4 r28 = [r24], -4 sxt4 r28 = r28 |
目次 | 索引 |
|