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

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

2) cc1 중단부에서 하는 일

 중단부에서 하는 일은 GIMPLE트리를 입력받아 SSA형태로 변환한 후 SSA에 기초한 아키텍쳐 비종속적인 최적화를 수행하고, 최종적으로 cc1후단부에서 사용할 RTL을 생성하는 일이다.

 -아키텍쳐 비종속적 : 아키텍쳐에 구애 받지 않는 최적화


cc1 중단부 과정 

 중간표현(GIMPLE트리) → 중간표현(SSA) → [Tree SSA Optimizer] → 중간표현(RTL) 


* SSA 변환

i = 10

j = i + 10

k = j + 20 

이를 SSA로 변경하면

i_1 = 10

j_2 = i_1 + 10

k_3 = j_2 + 20

이처럼 된다.


컴파일시 -fdump-tree-all -O3 옵션을 지정하고 컴파일하면 ssa파일이 생성된다.

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

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

[testone@oneone study]$ ls

CTest                             CTest.c.056t.ccp2         CTest.c.093t.copyprop4

CTest.c                           CTest.c.057t.phiprop      CTest.c.094t.dceloop1

CTest.c.001t.tu                   CTest.c.058t.fre          CTest.c.095t.lim

CTest.c.003t.original             CTest.c.059t.dce2         CTest.c.096t.pcom

CTest.c.004t.gimple               CTest.c.060t.forwprop2    CTest.c.097t.unswitch

CTest.c.006t.vcg                  CTest.c.061t.copyprop2    CTest.c.098t.sccp

CTest.c.007t.useless              CTest.c.062t.mergephi2    CTest.c.099t.empty

CTest.c.010t.lower                CTest.c.063t.vrp1         CTest.c.102t.ivcanon

CTest.c.011t.ehopt                CTest.c.064t.dce3         CTest.c.103t.ifcvt

CTest.c.012t.eh                   CTest.c.065t.cselim       CTest.c.104t.vect

CTest.c.013t.cfg                  CTest.c.066t.dom1         CTest.c.105t.veclower2

CTest.c.014t.cplxlower0           CTest.c.067t.phicprop1    CTest.c.106t.dceloop2

CTest.c.015t.veclower             CTest.c.068t.ifcombine    CTest.c.107t.cunroll

CTest.c.021t.cleanup_cfg1         CTest.c.069t.phiopt1      CTest.c.110t.ivopts

CTest.c.023t.early_optimizations  CTest.c.070t.tailr2       CTest.c.111t.loopdone

CTest.c.024t.ssa                  CTest.c.071t.ch           CTest.c.114t.reassoc2

CTest.c.026t.einline2             CTest.c.073t.cplxlower    CTest.c.115t.vrp2

CTest.c.027t.cleanup_cfg2         CTest.c.074t.sra          CTest.c.116t.dom3

CTest.c.028t.copyrename1          CTest.c.075t.copyrename3  CTest.c.117t.phicprop3

CTest.c.029t.ccp1                 CTest.c.076t.dom2         CTest.c.118t.cddce

CTest.c.030t.forwprop1            CTest.c.077t.phicprop2    CTest.c.120t.dse2

CTest.c.031t.addressables1        CTest.c.078t.reassoc1     CTest.c.121t.forwprop4

CTest.c.032t.sdse1                CTest.c.079t.dce4         CTest.c.122t.phiopt3

CTest.c.033t.esra                 CTest.c.080t.dse1         CTest.c.123t.tailc

CTest.c.034t.copyprop1            CTest.c.081t.forwprop3    CTest.c.124t.copyrename4

CTest.c.035t.mergephi1            CTest.c.082t.phiopt2      CTest.c.125t.uncprop

CTest.c.036t.dce1                 CTest.c.083t.objsz        CTest.c.126t.optimized

CTest.c.037t.addressables2        CTest.c.084t.store_ccp    CTest.c.127t.nrv

CTest.c.038t.sdse2                CTest.c.085t.copyprop3    CTest.c.128t.blocks

CTest.c.039t.tailr1               CTest.c.086t.fab          CTest.c.129t.final_cleanup

CTest.c.040t.profile              CTest.c.087t.sincos       like

CTest.c.041t.release_ssa          CTest.c.088t.crited       like.c

CTest.c.051t.apply_inline         CTest.c.089t.pre          love.c

CTest.c.052t.salias               CTest.c.090t.sink         Makefile

CTest.c.054t.retslot              CTest.c.091t.loop

CTest.c.055t.copyrename2          CTest.c.092t.loopinit

 


* RTL 생성

RTL은 GCC에서 기계 독립적인 특성을 제공하기 위해 사용하는 중간표현의 한 형태다.

[testone@oneone study]$ gcc -o CTest CTest.c -da

옵션 -da를 붙여주면 *.expand파일이 생성되는데 RTL표현을 볼 수 있다.

3) cc1 후반부에서 하는 일
중단부에서 RTL이 전달되면 후단부에서는 RTL로 다음과 같은 일을 수행한다.

 후단부에서 하는 일

 RTL → RTL Optimizer → Code Generator → 목적 코드(like.s)



* RTL최적화

 지금까지 아키텍쳐 비종속적인 최적화만 수행하였으나 후단부에서는 비종속+종속적인 최적화가 함께 수행한다.


* 목적코드 생성

목적 코드는 타겟 아키텍처의 어셈블리 코드이다.

 [testone@oneone study]$ gcc -v -save-temps -o CTest CTest.c

[testone@oneone study]$ vi CTest.s

        .file   "CTest.c"

        .section        .rodata

.LC0:

        .string "j = %d, k = %d\n"

        .text

.globl main

        .type   main, @function

main:

        leal    4(%esp), %ecx

        andl    $-16, %esp

        pushl   -4(%ecx)

        pushl   %ebp

        movl    %esp, %ebp

        pushl   %ecx

        subl    $36, %esp

        movl    $0, -12(%ebp)

        movl    $0, -8(%ebp)

        movl    $0, -16(%ebp)

        jmp     .L2

.L5:

        movl    -16(%ebp), %eax

        andl    $1, %eax

        testb   %al, %al

        je      .L3

        addl    $1, -12(%ebp)

        jmp     .L4

.L3:

        addl    $1, -8(%ebp)

.L4:

        movl    -8(%ebp), %eax

        movl    %eax, 8(%esp)

        movl    -12(%ebp), %eax

        movl    %eax, 4(%esp)

        movl    $.LC0, (%esp)

        call    printf

        addl    $1, -16(%ebp)

.L2:

.. 생략 


|| as에 의한 기계어 코드 생성

gcc -o like like.c -v -save-temps 명령은 다음과 같다.

as -V -Qy -o like.o like.s


as에 의해 생성되는 like.o파일은 어셈블된 like.s의 어셈블리어명령어과 데이터가 들어있는 ELF 바이너리 포맷 구조를 가진다. 바이너리 포맷이란 바이너리 파일의 구조를 결정짓는 규약을 말한다.


readelf 명령으로 ELF헤더 정보다.

 

[testone@oneone study]$ readelf -a like.o

ELF Header:

  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

  Class:                             ELF32

  Data:                              2's complement, little endian

  Version:                           1 (current)

  OS/ABI:                            UNIX - System V

  ABI Version:                       0

  Type:                              REL (Relocatable file)

  Machine:                           Intel 80386

  Version:                           0x1

  Entry point address:               0x0

  Start of program headers:          0 (bytes into file)

  Start of section headers:          320 (bytes into file)

  Flags:                             0x0

  Size of this header:               52 (bytes)

  Size of program headers:           0 (bytes)

  Number of program headers:         0

  Size of section headers:           40 (bytes)

  Number of section headers:         11

  Section header string table index: 8

 


|| collect2에 의한 링킹 과정

  생략.


출처:

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

: