컴파일러는 세 단계로 이루어져 있음
프론트엔드 → 미들엔드 → 백엔드
언어 종속적인 부분 처리함
해당 언어로 올바르게 작성되었는지 확인함(어휘, 구문, 의미분석)
어휘 분석 : 소스 코드를 의미있는 최소 단위인 token으로 나눔
구문 분석 : token으로 파스 트리(parse tree)를 만들면서 문법적 오류를 검출
의미 분석 : parse tree를 이용해 문법적 오류는 없지만 의미상 오류가 있는지 검사.
ex) 함수의 매개변수의 잘못된 사용, 변수의 자료형의 불일치
중간표현 생성 : 언어 독립적인 특성을 제공하기 위해 GIMPLE트리를 생성
GIMPLE
단어의 표현 자체는 GENERIC SIMPLE를 뜻함
프론트엔드에 의해 GIMPLE의 대상이 정해지고, 미들엔드에 의해 최적화된 명령형 프로그래밍 구조의 하위 집합만을 포함하게 됨
소스 코드를 GIMPLE로 변환할 때 복잡한 표현은 임시 변수를 사용하여 3개의 주소 코드로 분할됨
아키텍쳐 비종속적인 최적화를 수행함
- 아키텍쳐 비종속적인 최적화 CPU 아키텍쳐가 무엇이든(arm, x86 등) 상관없이 특성에 따라 최적화를 수행
프론트엔드에서 넘겨받은 GIMPLE트리를 SSA(Static Single Assigment)형태로 변환함
아키텍쳐 비종속적 최적화를 수행함
고급 언어와 어셈블리 언어의 중간 형태인 RTL(Register Transfer Language)을 생성
아키텍쳐 비종석적인 최적화와 아키텍쳐 종속적인 최적화가 이루어짐
프론트엔드로부터 넘겨 받은 RTL을 RTL OPtimizer에 의해 아키텍쳐 비종속적인 최적화와 아키텍쳐 종속적인 최적화를 동시에 수행
Code Generator에 의해 어셈블리 언어로 구성된 (*.s)파일이 만들어짐