GNU Compiler Collection
여러 언어를 여러 아키텍쳐용 기계어로 바꿔 주는 컴파일러 모음
C, C++, Objective-C, Fortran, Ada 등을 컴파일하고
보통 C, C++에 가장 많이 사용한다
소스.c
→ 전처리(cpp) → 컴파일(중간표현→어셈블리) → 어셈블(as) → 링크(ld) → 실행파일
전처리: 헤더 포함 전개 — #include
를 실제 소스에 펼쳐 하나의 번역 단위를 만든다
컴파일 (프론트/미들/백 포함): + 아래 3줄
어셈블: 재배치 정보 기록 — 심볼이 아직 확정되지 않은 채 .o에 재배치(relocation) 항목을 담아 링크 단계가 주소를 정할 수 있게 한다
링크12: 심볼3 해석4 — 참조와 정의를 연결해 undefined reference를 해소하고 최종 배치 주소를 결정한다
로더(실행 시): 동적 라이브러리 로딩5·재배치6 — 필요 so
7를 매핑하고 PLT8/GOT9 등을 통해 실제 주소로 바인딩10한다
프론트엔드: 타입 검사(의미 분석) — 잘못된 프로그램을 이 단계에서 걸러내고 정확한 IR11을 만든다
미들엔드12: SSA13 변환(GIMPLE14 기반) — 데이터 흐름을 명확히 해 대부분의 최적화가 가능해지는 출발점
백엔드: 레지스터 할당 — 가상의 무한 레지스터를 실제 레지스터에 배치(부족분은 스필15), 성능·정확성의 핵심 병목
ㅅㅂ 개어렵네;;
정적 링크(Static Linking): 링크 시 모든 심볼 주소 확정·코드 포함(의존성 내장) ↩
동적 링크(Dynamic Linking): 실행 시 로더가 심볼을 찾아 주소 확정(공유 라이브러리 사용) ↩
심볼(Symbol): 함수/전역변수 등의 “이름→주소/속성” 매핑 항목(심볼 테이블에 저장) ↩
심볼 해석(Symbol Resolution): 참조된 이름을 실제 정의와 짝짓는 링크 단계 작업 ↩
동적 로더(ld.so): 실행 시 .so
를 적재하고 재배치·바인딩을 수행하는 시스템 구성요소 ↩
재배치(Relocation): 실제 배치 주소에 맞게 코드/데이터 참조를 수정하는 과정(링크/로드 시) ↩
.so
(Shared Object): 실행 시 동적 로더가 적재·공유하는 ELF 공유 라이브러리 ↩
PLT(Procedure Linkage Table): 함수 호출용 점프 스텁; 첫 호출에 로더 통해 GOT 채우는 지연 바인딩 경유지 ↩
GOT(Global Offset Table): 동적 링크1 시 실제 함수/데이터 주소를 저장해 두는 테이블 ↩
IR(Intermediate Representation): 언어/하드웨어 중립의 중간 코드(최적화·코드 생성의 재료) ↩
SSA(Static Single Assignment): 각 변수는 1회만 정의되도록 재작성한 형태(데이터 흐름 분석 쉬움) ↩
미들엔드(Middle-End): IR 위에서 공통 최적화를 수행하는 컴파일러 단계 ↩
GIMPLE: GCC의 단순 3-주소 IR(대부분 SSA로 다룸) 주요 최적화가 여기서 수행됨 ↩
스필(Spill): 레지스터가 부족해 값을 스택 메모리에 임시로 빼놓는 것(로드/스토어 비용↑) ↩