02. 알아두면 정말 유용한 C소스 컴파일 과정(2)

Language/C 2011. 9. 8. 12:14

|| cc1에 의한 어셈블리 소스 파일로 컴파일


 전처리 과정이 끝났으면 이제 진짜 C컴파일인 cc1이 나설 차례다.

cc1의 컴파일 과정은 크게 세부분으로 나뉠 수 있는데, 전단부 - 중단부 - 후단부 


GCC 컴파일러(cc1, cc1plus, jc1)의 컴파일 과정 

 전처리파일(like.i) → 전단부 → 중간 표현(GIMPLE트리) → 중단부 → 중간표현(RTL) → 후반부 → 

→ 목적코드(like.s)



전단부에서는 소스 코드가 올바르게 작성되었는지 분석


중단부에서는 전단부에서 넘겨받은 GIMPLE 트리를 이용해 아키텍쳐 비종속적인 최적화를 수행


후단부에서는 아케텍쳐 비종속적인 최적화와 함께 아키텍쳐 종속적인 최적화가 수행


비로소 목적 코드를 생성




1) cc1 전단부에서 하는 일

cc1 전단부 처리 과정 

 전처리파일(like.i) → 전단부(어휘/구문/의미 분석) → 중간표현(GIMPLE 트리)

cc1의 전단부는 소스코드의 문법상, 의미상의 오류를 파악하고 최종적인 GIMPLE트리를 생성하는 일이다.


* 중간 표현 생성

GIMPLE트리는 언어 독립적인 특성을 제공하기 위해 사용하는 트리 형태의 중간표현, 여러프로그래밍 언어 소스를 공통된 언어 표현으로 바꾼 후 소스 코드를 트리 형태로 표현한 것으로 GIMPLE 트리가 생성되는 과정은 다음과 같다. 

중간 표현 생성 과정 

 C(AST) → C(genericize)            ↘   

 C++(AST) → C++(genericize)       →  GENERIC 트리 →  Gimplify → GIMPlE 트리

 Java(AST) → JAVA(genericize)  ↗ 


GENERIC 트리는 소스를 트리 구조로 표현하는 데 있어 언어 독립적인 특징을 제공하기 위해 만들어졌다. 그래서 GCC에서 지원하는 많은 언어의 소스 코드는 GENERIC 트리로 표현 가능하다.

이렇게 컴파일러가 언어 종속적이게 되는 문제를 해결하기 위해 GENERIC틀 같은 공통된 중간 표현으로 바꾼다.



GIMPLE 트리 확인

CTest.c 내용 

#include<stdio.h>


int main()

{

        int i, j, k;


        j = 0;

        k = 0;


        for(i=0; i<10; i++)

        {

                if((i%2) != 0) {

                        j += 1;

                }

                else {

                        k += 1;

                }

                printf("j = %d, k = %d\n", j, k);

        }


        return 0;

}

 


다음 명령으로 GIMPLE트리를 확인 할 수 있다.

[testone@oneone study]$ gcc -o CTest Ctest.c -fdump-tree-all

[testone@oneone study]$ gcc -o CTest Ctest.c -fdump-tree-all 

[testone@oneone study]$ ls

CTest                  CTest.c.006t.vcg      CTest.c.013t.cfg           like

CTest.c                CTest.c.007t.useless  CTest.c.014t.cplxlower0    like.c

CTest.c.001t.tu        CTest.c.010t.lower    CTest.c.015t.veclower      love.c

CTest.c.003t.original  CTest.c.011t.ehopt    CTest.c.021t.cleanup_cfg1  Makefile

CTest.c.004t.gimple    CTest.c.012t.eh       CTest.c.051t.apply_inline

 



 CTest.c.004t.gimple 파일 내용

 main ()

{

  int D.1593;

  _Bool D.1594;

  int D.1595;

  int i;

  int j;

  int k;


  j = 0;

  k = 0;

  i = 0;

  goto <D.1591>;

  <D.1590>:;

  D.1593 = i & 1;

  D.1594 = (_Bool) D.1593;

  if (D.1594)

    {

      j = j + 1;

    }

  else

    {

      k = k + 1;

    }

  printf (&"j = %d, k = %d\n"[0], j, k);

  i = i + 1;

  <D.1591>:;

  if (i <= 9)

    {

      goto <D.1590>;

    }

  else

    {

      goto <D.1592>;

    }

  <D.1592>:;

  D.1595 = 0;

  return D.1595;




출처:

http://www.oneone.kr/?mid=UnixPUtil&page=1&document_srl=5657 
: