• 検索結果がありません。

インライン関数展開の使用方法

インライン関数を呼び出すと、その関数の C/C++ ソース・コードが呼び出し位置に 挿入されます。これはインライン関数展開と呼ばれます。インライン関数展開は、次 の理由から小さい関数には有効です。

❏ 1 回の関数呼び出しのオーバーヘッドを削減できます。

❏ インライン展開を行うと、本オプティマイザは周囲のコードに合わせて自由に関 数を最適化できます。

インライン関数展開には次のような複数のタイプがあります。

❏ 組み込み演算子のインライン展開(組み込み関数は常にインライン展開されま す)

❏ 自動インライン展開

❏ 保護されない inline キーワードを使用した定義制御インライン展開

❏ 保護される inline キーワードを使用した定義制御インライン展開

注: 関数のインライン展開によりコード・サイズが大幅に増大する可能性がある 関数をインライン展開するとコード・サイズが増大します。特に複数の場所で呼び 出された関数をインライン展開する場合、増大します。関数のインライン展開は、少 ない場所からのみ呼び出される関数および小さい関数に適しています。

2.9.1 組み込み演算子のインライン展開

C28x には多数の組み込み演算子があります。コンパイラは組み込み演算子を効率の よいコード(通常 1 つの命令)に置き換えます。インライン展開は、オプティマイ ザを使用するかどうかに関係なく自動的に行われます。

組み込み関数の詳細、および組み込み関数のリストについては、7.4.5 項「組み込み 関数(intrinsics)を使用してアセンブリ言語文にアクセスする方法」(7-26 ページ)

を参照してください。

2.9.2 自動インライン展開

インライン関数展開の使用方法

2.9.3 保護されない定義制御インライン展開

inline キーワードは、標準の呼び出し手続きを使用するのではなく、呼び出し位置で 関数をインライン展開することを指定します。コンパイラは、inline キーワードを指 定して宣言された関数のインライン展開を実行します。

定義制御されたインライン展開をオンにするには、任意の -O オプション(-O0、-O1、 -O2、-O3)を指定してオプティマイザを起動する必要があります。また、-O3 を指 定する場合は自動インライン展開もオンになります。

次の例は inline キーワードの使用方法を示しています。ここでは、関数呼び出しが

呼び出し先関数の中のコードで置き換えられます。

例 2-1. inline キーワードの使用方法

-pi オプションは定義制御インライン展開をオフにします。このオプションは、特定 のレベルの最適化が必要で、定義制御インライン展開は不要な場合に便利です。

2.9.4 保護されたインライン展開と _INLINE プリプロセッサ・シンボル

ヘッダ・ファイル内で関数を static inline として宣言すると、-pi によりインライン展 開がオフにされた場合や、オプティマイザが稼働しない場合には、コード・サイズ が増大する危険性が潜在します。これを回避するためには、追加の手順が必要です。

inline int volume_sphere(float r) {

return 4.0/3.0 * PI * r * r * r;

}

int foo(...) {

...

volume = volume_sphere(radius);

...

}

インライン関数展開の使用方法

例 2-2 には、関数の定義が 2 つあります。最初の定義はヘッダ・ファイル内のもの

で、インライン定義です。この定義が有効になり static inline としてプロトタイプが 宣言されるのは、_INLINE が真の場合だけです(オプティマイザが使用されるとき に -pi が指定されていないと、_INLINE は自動的に定義されます)。

2 番目の定義により、インライン展開が無効にされたときには必ず呼び出し可能な関 数が存在することが保証されます。これはインライン関数ではないので、ヘッダ・

ファイルが組み込まれ関数のプロトタイプの非インライン・バージョンが生成され る前に _INLINE プリプロセッサ・シンボルは定義解除(#undef)されます。

例 2-2. ランタイムサポート・ライブラリでの _INLINE プリプロセッサ・シンボルの使用方法 (a) foo.h

(b) foo.c

#ifdef _INLINE

#define _IDECL static inline

#else

#define _IDECL extern

#endif

_IDECL int len (const char *str);

#ifdef _INLINE

static inline int len(const char *str) {

int n = -1;

const char *s = str - 1;

do n++; while (*++s);

return n;

}

#endif

#undef _INLINE

#include "foo.h"

int len(cont char * str) {

int n = -1;

const char *s = str - 1;

do n++; while (*++s);

return n;

}

インライン関数展開の使用方法

2.9.5 インライン展開の制約事項

自動インライン展開と定義制御インライン展開の両方に対して、どの関数をインラ イン展開できるかに関していくつかの制約事項があります。ローカルな静的変数や 可変数の引数をもつ関数はインライン展開されませんが、static inline として宣言さ れた関数は展開されます。static inline として宣言された関数の場合、ローカルな静 的変数が存在しても展開が行われます。また、再帰関数やノンリーフ関数に対して はインライン展開の深さが制限されます。さらに、インライン展開は小さい関数や 呼び出し箇所が少ない関数に対して使用してください(ただし、コンパイラがこれ を強制することはありません)。

次の条件に当てはまる関数は、インライン展開が不適格です。

❏ struct または union を戻す

❏ struct または union パラメータをもつ

❏ volatile パラメータをもつ

❏ 可変長引数リストをもつ

❏ struct、union、または enum 型が宣言されている

❏ 静的変数を含む

❏ volatile 変数を含む

❏ 再帰的である

❏ プラグマを含む

❏ スタックが大きすぎる(ローカル変数が多すぎる)

インターリストの使用方法