Misexpect¶
開発者が llvm.expect
組み込み関数、つまり __builtin_expect(...)
を使用する場合、コードが実行時にどのように動作するかをオプティマイザに伝えようとしています。しかし、これらのアノテーションは、コードベースの変更によって暗黙的に無効化されたり、開発者が誤ってアノテーションを付けたり(たとえば、UNLIKELY
の代わりに LIKELY
を使用したり)、アノテーションを記述したときに何かを誤って想定したりするなど、さまざまな理由で不正確になる可能性があります。理由に関係なく、オプティマイザがコードについてより有用な決定を下せるように、これらの状況を検出することは有用です。MisExpect 診断は、llvm.expect
組み込み関数の使用をプロファイリング入力によって提供されるグランドトゥルースと比較することにより、開発者がこれらの状況を特定して対処するのに役立つことを目的としています。
LLVM バックエンドの MisExpect チェックは、単純な手順に従います。プロファイリング中に収集された分岐の重みと llvm.expect
組み込み関数によって提供された分岐の重みに不一致がある場合、ユーザーに診断メッセージを出力します。
検証を実行する最も自然な場所は、分岐の重みが分岐重みメタデータの形式でターゲット命令に割り当てられる直前です。
LLVM バックエンドには、プロファイリング情報または llvm.expect
組み込み関数の使用に基づいて分岐の重みが作成および割り当てられる 3 つの主要な場所があり、実装ではこれらの場所に焦点を当てて検証を実行します。
MisExpect 関連の診断を出力するためのしきい値は、コンパイラが llvm.expect
組み込み関数に割り当てる値に基づいて計算します。これらの値は、-likely-branch-weight
および -unlikely-branch-weight
LLVM オプションを使用して設定できます。検証中に、プロファイルの重みが計算されたしきい値と一致しない場合、潜在的なパフォーマンスの低下を詳述したリマークまたは警告を出力します。診断では、アノテーションがプロファイリング中に正しかった時間の割合も報告され、開発者がどのように対処するかを判断するのに役立ちます。
診断は、最適化リマークの形式でも利用できます。これは、LLVM の opt-viewer.py
スクリプトを使用してシリアル化および処理できます。
- -pass-remarks=misexpect¶
プロファイリングデータが
llvm.expect
組み込み関数の使用と競合する場合、misexpect の最適化リマークを有効にします。
- -pgo-warn-misexpect¶
プロファイリングデータが
llvm.expect
組み込み関数の使用と競合する場合、misexpect 警告を有効にします。
LLVM は、フロントエンド、IR、CS-IR、サンプリングの 4 種類のプロファイル形式をサポートしています。MisExpect 診断は、すべてのプロファイリング形式と互換性があります。
プロファイルの種類 |
説明 |
---|---|
フロントエンド |
コンパイル中にフロントエンド(例: |
IR |
LLVM バックエンドによって追加されたプロファイリング計測 |
CS-IR |
コンテキスト依存の IR ベースのプロファイル |
サンプリング |
Linux の |