[기술] 컴파일러 한 걸음씩 - 첫번째

 



인사


오늘은 제가 컴파일 과정에 대해서 공부하고 거기에서 배운 정보들에 대해서 소개해 드리겠습니다. 

언어 역사


과거에는 **기계어(Machine Code)**를 이용해 컴퓨터에 명령을 입력했습니다. 이때는 ASCII 코드를 기반으로, 각 문자를 **이진수(Binary)**로 변환하여 입력해야 했기 때문에 사람이 이해하고 작성하기 매우 어려웠습니다.

이러한 불편함을 해결하기 위해 1940년대 후반, 보다 사람이 이해하기 쉬운 **어셈블리 언어(Assembly Language)**가 등장했습니다. 어셈블리 언어는 기계어 명령어를 **기호(Syntax)**로 표현한 것으로, 간단한 명령어들을 사람이 기억하기 쉽게 만들었습니다.

시간이 지나 1950년대, 프로그래밍 언어는 더 발전하여 C 언어와 같은 고급 컴파일러 언어가 등장하게 됩니다. C 언어는 인간이 작성한 코드를 컴파일러를 통해 한 번에 기계어로 변환하여 실행파일을 만들 수 있는 구조입니다.

이후 C 언어에 객체지향 개념과 전처리 기능이 추가된 C++ 언어가 등장했습니다. C++는 복잡한 프로그램을 더 잘 구조화할 수 있도록 도와줍니다.

그리고 1991년, 네덜란드의 귀도 반 로섬(Guido van Rossum)이 개발한 Python 언어가 등장합니다. Python은 인터프리터 언어로, 코드를 한 줄씩 읽고 실행하는 방식이며, 배우기 쉽고 문법이 간결해 지금도 널리 사용되고 있습니다.




컴파일 과정


컴파일 과정은 크게 프론트엔드(Frontend), 미들엔드(Middle-End), 백엔드(Backend) 의 세 단계로 나뉩니다.


1. 프론트엔드 (Frontend)

프론트엔드는 **소스 코드를 분석하여 중간 표현(IR, Intermediate Representation)**을 생성하는 단계입니다.
이 과정은 주로 문법 및 의미 분석에 집중하며, 다음과 같은 하위 단계로 구성됩니다:

  • Lexical Analysis (어휘 분석):
    소스 코드를 토큰(token) 단위로 분리

  • Syntax Analysis (구문 분석):
    토큰을 구조적으로 분석하여 구문 트리(CST) 또는 **추상 구문 트리(AST)**를 생성

  • Semantic Analysis (의미 분석):
    타입 검사, 선언 여부 확인, 제어 흐름 분석 등 의미적 오류를 검사

  • Intermediate Code Generation (중간 코드 생성):
    분석된 결과를 바탕으로 **중간 표현(IR)**을 생성


2. 미들엔드 (Middle-End)

미들엔드는 프론트엔드에서 생성한 IR을 최적화하는 단계입니다.
이 최적화는 기계에 독립적이며, 코드의 성능을 향상시키는 데 목적이 있습니다.

대표적인 최적화 작업:

  • Dead Code Elimination: 사용되지 않는 코드 제거

  • Loop Optimization: 반복문 성능 개선

  • Common Subexpression Elimination: 중복 계산 제거


3. 백엔드 (Backend)

백엔드는 최적화된 IR을 실제 실행 가능한 타겟 머신 코드로 변환하는 단계입니다.
여기서는 하드웨어 구조를 고려한 작업들이 이루어집니다:

  • Target Code Generation (타겟 코드 생성):
    IR을 해당 아키텍처(x86, ARM 등)에 맞는 어셈블리 코드로 변환

  • Register Allocation (레지스터 할당):
    실제 CPU 레지스터에 변수 및 임시값을 할당

    • 그래프 착색 알고리즘, 스필(spill) 처리 등으로 효율성 극대화

  • Machine Code Generation (기계어 생성):
    어셈블리 코드를 CPU가 이해할 수 있는 **이진 코드(Binary)**로 변환

  • Platform-Specific Optimization (플랫폼 특화 최적화):
    특정 하드웨어에 맞춰 명령어 재배열, 캐시 최적화, 분기 예측 개선 등 수행


컴파일러는 프론트엔드에서 소스 코드를 분석하고 IR을 생성하며, 미들엔드에서 이를 최적화한 뒤, 백엔드에서 최종 기계어로 변환함으로써 실행 가능한 프로그램을 생성합니다. 각 단계는 성능, 이식성, 하드웨어 효율성을 고려해 정교하게 설계되어 있습니다.




예고 


안녕하세요.
앞으로 컴파일러의 각 단계별 소제목을 중심으로 공부한 내용을 하나씩 소개해드릴 예정입니다. 최대한 자세하고 정확하게 정리해보려 합니다.
혹시 제가 잘못 이해하거나 잘못 설명한 부분이 있다면 언제든지 지적해주시면 감사하겠습니다. 그럼 오늘도 모두 하시는 일 잘 되시길 바랍니다. 화이팅!






개발자 김동완

개발, 비전공, 백엔드, 풀스택, 프로그래밍

댓글 쓰기

다음 이전