함수 기호는 ".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않으면 비활성화됩니다.

관련 정보