19

私はいつも、コンパイラはデッド コードを排除するのに十分賢いと言われてきた。私が書いているコードの多くは、コンパイル時にわかっている多くの情報を持っていますが、コードは最も一般的な形式で書かなければなりません。アセンブリがわからないため、生成されたアセンブリを調べることができません。最終的な実行可能ファイルで効果的に削除できるコードはどのようなものですか?

いくつかの例ですが、これらに限定されません

f(bool b){
 if(b){
  //some code
 }else{
  //some code
 }
}
f(true);
//////////////////////////
template<bool b>
f(){
 if(b){
  //some code
 }else{
  //some code
 }
}
f<true>();
///////////////////////////

の定義がf他の目的コードにあり、呼び出されf(true)たがメインにある場合はどうなりますか。リンク時間の最適化は、デッド コードを効果的に排除しますか? デッドコードの除去を容易にするコーディングスタイル/コンパイラオプション/トリックは何ですか?

4

3 に答える 3

27

通常、フラグ on を使用してコンパイルしている場合-Oのフラグがオンになっています。

      -fauto-inc-dec 
      -fcompare-elim 
      -fcprop-registers 
      -fdce  
      [...]

-fdceデッド コード エリミネーションの略です。バイナリが希望どおりに最適化されているかどうかを確認するために、このオプションの有無にかかわらず (つまり、明示的にオフにして) バイナリをコンパイルすることをお勧めします。

コンパイラのさまざまなパスについて読んでください。

  • SSA 攻撃的なデッド コードの排除。`-fssa-dce' オプションでオンにします。このパスは、プログラムに外部から見える影響を与えないため、不要と見なされるコードの削除を実行します。線形時間で動作します。

リンカがデッド コードを削除するのを支援する方法については、このプレゼンテーションを参照してください。主なポイントは次の 2 つです。

モジュールを -ffunction-sections -fdata-sections でコンパイルします – 欠点はありません!

  • これには、バイナリだけでなく静的ライブラリも含まれます。ライブラリのユーザーが、より効率的なデッド コードの削除の恩恵を受けることができます。
  • マジックセクションを使用する厄介なサードパーティの静的ライブラリにリンクする必要がない限り、バイナリを --gc-sections でリンクします。

この GCC バグも参照してください (最適化の可能性とその理由を確認するため)。

于 2012-05-30T03:13:58.807 に答える
3

あなたの例は、関数内のデッドコードの除去に焦点を当てています。

別のタイプのデッド コードの削除は、未使用のシンボル (関数または変数) 全体の削除です。これは次の方法で実現できます。

-fdata-sections -ffunction-sections -Wl,--gc-sections

で述べたように: GCC と ld で未使用の C/C++ シンボルを削除するには?

これらのフラグは、デフォルトではさまざまな GCC -O レベル (-O1、-O2 など) では有効になっていません。

于 2015-11-11T09:59:44.687 に答える
0

そのような if 式でテンプレート パラメーター定数を使用した場合、dce (Dead Code Elimination) コンパイラー (Linux の GCC 4.8.1) フラグは役に立たず、O2、O3 の最適化も役に立ちませんでした。テンプレート特殊化ラッパーを使用する必要がありました:

template<bool b>
f();

template<>
f<true>(){
  //some code on true condition
}

template<>
f<false>(){
  //some code on false condition
}

また、未使用のコード ブランチのコンパイルを回避するためにマクロを使用することもできますが、それはコンパイラによって異なります (マクロがコード内で発生したときに処理されるか、プリコンパイル段階で処理されるか)。

template<bool b>
f(){
 #if b
  //some code
 #elif
  //some code
 #endif  // b
}
于 2013-10-14T16:21:37.307 に答える