컴파일러는 보통 프런트엔드, 중간표현(IR), 옵티마이저, 백엔드로 설명한다.
프런트엔드는 소스 코드를 해석해 언어별 구조를 잡고, IR은 분석·최적화·코드 생성을 위해 쓰는 내부 표현이며, 옵티마이저와 백엔드는 이를 다듬어 최종 기계어로 바꾼다.
GCC도 언어별 프런트엔드와 언어 독립적인 중간 단계·백엔드를 가지며, LLVM은 이런 분리를 더 뚜렷하게 드러낸 모듈식 컴파일러 인프라다.
GCC는 1987년 GNU C Compiler로 시작했고, 여러 언어를 지원하면서 GNU Compiler Collection으로 확장됐다.
LLVM은 일리노이대 연구 프로젝트에서 출발해 2003년 공개됐고, 지금은 IR·옵티마이저·코드 생성기와 Clang 같은 하위 프로젝트를 포함하는 컴파일러 생태계로 성장했다.
GCC는 여러 언어용 컴파일러를 하나의 프로젝트 안에서 함께 제공하는 전통적인 통합형 툴체인에 가깝다.
그래서 새 언어를 제대로 지원하려면 GCC 내부 구조에 맞는 프런트엔드를 붙이고, 빌드·유지보수 흐름에도 함께 들어가야 하는 경우가 많다.
(새 언어를 GCC “안에” 넣는 느낌)
반면 LLVM은 최적화기와 코드 생성기 같은 기능을 외부 프로젝트가 비교적 독립적으로 가져다 쓸 수 있게 만든 재사용 가능한 컴파일러 인프라에 가깝다.
그래서 새 언어를 만들 때는 프런트엔드는 별도 프로젝트로 구현하고, 코드 생성과 최적화에는 LLVM을 활용하는 방식이 흔하다.
(별도 컴파일러 프로젝트가 따로 있고, LLVM 라이브러리를 가져다 쓰는 느낌)
이 차이는 새 언어 구현에서 LLVM 계열이 자주 선택되는 이유 중 하나다.
실제 선택에는 기존 툴체인, 빌드 의존성, 유지보수 비용,타깃 플랫폼 지원 같은 현실적인 요소도 크게 작용한다.
실제 언어로 예들 들면, Rust는 보통 LLVM으로 코드 생성을 하고,
Zig는 여러 코드 생성 백엔드를 가지며 현재 널리 쓰이는 주 백엔드는 LLVM이지만 자체 백엔드들도 함께 발전 중이다.
Go는 기본적으로 자체 컴파일러 gc를 쓰지만, GCC 프런트엔드인 gccgo도 공식적으로 존재한다.