Blog | Tag | Local | Guest | Login | Write |  RSS
GCC에 해당되는 글 1건
2008.11.10 :: GCC Introduction 2
GCC Introduction
** 앞으로 작성되는 모든 글은 GCC 4.x 버전대의 소스와, gcc internels문서, 각종 인터넷 분석자료( 정원교씨 분석자료, 그외 기타 등등), 책, 그리고 www.iamroot.org gcc 스터디 그룹에서 공부한 내용을 바탕으로 작성되어 집니다 **

GCC는 (GNU Compiler Collection)의 약자이다. GNU C Compiler라고 부르기도 하는데 GCC가  C++, JAva, Fortran, Ada등 많은 프로그래밍 언어를 지원하면서 부터 단순히 C Compiler라고 부르기보다는 전자의 경우가 맞을 것이라 생각한다.

GCC의 가장 큰 장점은 현존하는 수많은 Architecture의 지원이다. x86부터 시작하여 ARM, MIPS, PowerPC, Sparc등등 현존하는 대부분의 아키텍쳐를 지원한다. 이렇게 많은 아키텍쳐를 지원할 수 있었던 것은 각 아키텍쳐로의 포팅이 용이하게 구성되어져 있기 때문이다. 따라서 새로운 아키텍쳐를 GCC에 포팅하는 일도 간단하지는 않겠지만 새로운 컴파일러를 제작하는것에 비해 상당한 수고를 덜 수 있을 것이다.

그럼 간단히 GCC의 컴파일 과정을 알아보자.

소스파일(.c)  ->>  전처리후 파일(.i)  ->> 어셈블리 파일(.s)  ->> 오브젝트 파일 (.o)  ->> 최종 실행파일(ELF)
               (전처리과정)              (컴파일과정)             (어셈블러과정)              (링킹과정)

이것이 보통 gcc가 컴파일 되는 과정이다.

gcc로 보통 -o 옵션을 주게 되면 각 단계별로 생성되는 파일을 최종 ELF실행을 만들어 낸후 다 삭제 해 버린다. 중간 생성 파일들을 보기위해서는

gcc -E 옵션을 주면 .i파일을 볼 수 있고 -S 옵션을 주면 .s파일을 생성하며, -c 옵션을 주면 .o파일을 만들어내게 된다. 이것 모두를 다 보고 싶다면 --save-temps 옵션을 주게 되면 중간생성 파일들을 보두 볼 수 있다.

컴파일러는 단순히 고레벨 수준의 언어를 최종 아키텍쳐의 목적코드로 만들어내는데에 그 역할이 있지 않다. 현대 컴파일러에서 가장 중요한 부분은 최적화 부분이다. 사용자가 작성한 코드가 해당 아키텍쳐에서 최적으로 동작하게끔 목적코드를 생성해 주어야 한다. 그래야 프로그램의 성능을 극대화 시킬 수 있다. 그 과정이 .i 에서 .s로의 컴파일과정에 일어나게 된다.

이과정은 크게 4가지로 나뉘어 지는데

GENERIC tree -> GIMPLE tree -> SSA -> RTL

이런순서대로 GCC는 해당 소스파일을 여러단계에 걸쳐 최적화를 이루어내게 된다.

크게 최적화는 두가지 부류로 나누어 볼 수 있는데 컴퓨터 아키텍쳐에 종속적인 최적화와 그렇지 않은 최적화로 나누어 볼 수 있다. RTL전 까지는 아키텍쳐에 비종속적인 최적화가 일어나고 RTL변환후에는 아키텍쳐 종속적인 최적화가 이루어지게 된다.

보통 학부 컴파일러 과정에서는 파싱(토큰, 문법체크)과 의미분석(타입체크 등등)과정까지만 배우고 만다. 이런 부분을 front-end라고 부르고 그 뒤의 최적화 부분을 back-end라고 부른다. front-end는 이미 많은 해결책과 거의 최적화된 솔루션이 존재해 현재 연구분야에서는 거의 제외되고 있다고들 하고, 최적화 부분인 back-end가 주요 관심사라고 한다.( 생각해보면 컴퓨터 아키텍쳐의 발전에 따라 계속 고려되어야 하는 부분이니 계속 연구의 수요는 일어날 것이라 생각된다. )

여튼 학부과정에서 배운 파싱과정을 거쳐 파싱트리가 만들어지면 이것을 프로그래밍 언어에 독립적인 general한 트리로 만들게 된다. 이것이 바로 GENERIC 트리이다. 이후에 아키텍쳐 비종속적인 최적화를 이루기 위해 트리를 좀더 변경시키는데 이것이 GIMPLE 트리에 해당한다. GIMPLE 트리에서 한단계 더 변형을 가하는데 이것이 바로 SSA(Static Single Assignment)형태이다.
이렇게 아키텍쳐 비종속적인 최적화를 수행한후에 거의 어셈블리 형태와 유사한 RTL( Register Transfer Language)로 변환한후 여기서 아키텍쳐 종속적인 최적화를 수행하게 된다. ->각 트리에 대한 얘기는 추후에....