関数記号は「.part」サフィックスを使用してコンパイルされます。

関数記号は「.part」サフィックスを使用してコンパイルされます。

Linuxカーネル3.18.10をクロスコンパイルすると、コンパイラは.part.<N>いくつかのシンボルの末尾にサフィックスを追加します(以下の例を参照)。<N>他の defconfig を使用すると、数値が変更されます。どのような条件でコンパイラがシンボルの末尾に部分サフィックスを追加するのかを知っている人はいますか?

$ arm-none-linux-gnueabi-readelf -a vmlinux | grep do_kernel_fault
与えられた
c03a48f8 116 FUNC LOCAL DEFAULT 2 __do_kernel_fault.part.10

ベストアンサー1

で終わる記号は、.part一種の機能的な装飾ではなく、真の機能的な記号です。より正確には、で終わる関数は、.partより大きな関数でGCCによって生成された関数です。

時々、GCCは簡単にインライン化できる大きな関数の制御フローの特定の部分を評価しますが、大きな関数全体をインライン化することはできません。したがって、関数を分割し、そのほとんどを独自の関数に入れます。この関数は元の関数名と.part+を名前で受け取り.<some number>、残りは別の関数にインライン化します。

gcc/ipa-split.cこれは少なくともgcc-4.8.3のGCCソースコードで説明されている最適化の一部です(そしておそらく後で今は確認できません)。

/* The purpose of this pass is to split function bodies to improve
   inlining.  I.e. for function of the form:

   func (...)
     {
       if (cheap_test)
   something_small
       else
   something_big
     }

   Produce:

   func.part (...)
     {
  something_big
     }

   func (...)
     {
       if (cheap_test)
   something_small
       else
   func.part (...);
     }

   When func becomes inlinable and when cheap_test is often true, inlining func,
   but not fund.part leads to performance improvement similar as inlining
   original func while the code size growth is smaller.

   The pass is organized in three stages:
   1) Collect local info about basic block into BB_INFO structure and
      compute function body estimated size and time.
   2) Via DFS walk find all possible basic blocks where we can split
      and chose best one.
   3) If split point is found, split at the specified BB by creating a clone
      and updating function to call it.  

   The decisions what functions to split are in execute_split_functions
   and consider_split.  

   There are several possible future improvements for this pass including:

   1) Splitting to break up large functions
   2) Splitting to reduce stack frame usage
   3) Allow split part of function to use values computed in the header part.
      The values needs to be passed to split function, perhaps via same
      interface as for nested functions or as argument.
   4) Support for simple rematerialization.  I.e. when split part use
      value computed in header from function parameter in very cheap way, we
      can just recompute it.
   5) Support splitting of nested functions.
   6) Support non-SSA arguments.  
   7) There is nothing preventing us from producing multiple parts of single function
      when needed or splitting also the parts.  */

お分かりのように、このプロセスはコンパイラによって完全に制御されます。新しいシンボル名はの関数clone_function_nameによってgcc/cgraphclones.c。後で追加される番号は.part特別な意味を持たず、名前の衝突を防ぐためだけのものです。これは、GCCが既存の関数(GCC開発者が「レプリカ」と呼ぶ関数)から新しい関数を生成するたびに増加する単純なカウンタです。

このオプションを使用すると、-fdisable-ipa-fnsplitコンパイラがこの最適化を適用しないようにしたりアクティブにしたり-fenable-ipa-fnsplitできます。デフォルトでは最適化レベルで適用され、-O2それ-O3以外の場合は無効になります。

おすすめ記事