Clang/LLVMでインライン関数を強制する方法はありますか?
AFAIK、以下はコンパイラへの単なるヒントですが、リクエストを無視することができます。
__attribute__((always_inline))
関数をインライン化できない場合、コンパイルが失敗してもかまいません。
ClangのデフォルトであるC99でコンパイルする場合、良い解決策があります。単にinline属性を使用します。
inline void foo() {}
Clangの互換性ページ :によく書かれています。
デフォルトでは、ClangはC99標準に従ってCコードを構築します。これは、GCCのデフォルトの動作とは異なるセマンティクスをインラインキーワードに提供します...
C99では、インラインとは、関数の定義がインライン化のためにのみ提供され、プログラムのどこかに別の定義(インラインなし)があることを意味します。これは、addがインライン化されていない場合(たとえば、最適化せずにコンパイルする場合)、mainが他の定義への未解決の参照を持つため、このプログラムが不完全であることを意味します。したがって、(正しい)リンク時間エラーが発生します...
GCCはそれを拡張機能として認識し、オプティマイザーへのヒントとして扱います。
したがって、関数がインライン化されていることを保証するには、次のようにします。
私はあなたの質問をClang/LLVMフレームワーク内のツールを求めるものとして扱います。これが私の提案です:コードをLLVMビットコードにコンパイルしてから 常にインラインパス を実行します。
例えば:
> clang <other CFLAGS> -emit-llvm -c -o foo.bc foo.c
> opt -always-inline foo.bc -o foo_inline.bc
> clang -c -o foo.o foo_inline.bc
以前にこのシーケンスを使用したことがあり、「always_inline」とマークされたすべての関数がインライン化されています。私の場合、ビットコードですでに他の分析と変換を行っていたので、optにフラグを追加するだけで済みました。
次の実験から始めることができます:clang -mllvm -inline-threshold = n
パラメータnが大きいほど、インライン化はより積極的になります。デフォルトは225なので、もっと大きい値に設定します。非常に積極的なインライン化により、大きなコードサイズと長いコンパイル時間が予想されます。収穫逓減のポイントに達したら、コードをプロファイリングして、頻繁に呼び出されるがインライン化されていない関数を探し、attribute((always_inline)でマークを付けることができます。 )さらにインライン化するため。
「インライン」とマークされた関数がある場合は、-inline-thresholdよりも大きい-inlinehint-thresholdを試して、これによって何かが変わるかどうかを確認することもできます。
また、リンク時間の最適化を使用してコンパイルしていますか?それらがないと、インライン化は個々のコンパイル単位に制限されます。
**から取得 groups.google.comフォーラム
役に立つかもしれないほんの少しの発言。
OPのコメントについて:
static inline
_定義は、それらの1つを変更すると、複数の異なる関数が発生し、多くのヘッドスクラッチが発生する可能性があるため、注意が必要です。 、特にインライン化が開始され、実際の呼び出しがステートメントのさまざまなシーケンスに蒸発する場合。有用な議論と推奨事項を見つけることができます ここ 。 C99のアドバイスは次のように要約されます。
ヘッダーファイルで以下を定義し、必要な場所にインクルードします。
inline void foo() { /*...*/ }
単一のソースファイルで、extern
を使用して外部シンボルを生成することを宣言します。
extern inline foo();
提案されたLLVMIRメソッドに関しては、それは機能しますが、ソース言語ドメインが渡され、異なるルールのセットが適用されます(ツールに大きく依存します)。簡単な説明的な議論は見つけることができます ここ 。
ブルートフォース方式は、それをマクロに変換するだけです。