clang과 LLVM에 관하여

2025. 12. 13. 20:37·CS/이론
반응형

👋 들어가기 전

 

최근 프로젝트 빌드 프로세스 최적화 및 시간 단축과 관련하여, 관심이 생겨

 

컴파일 과정에서 등장하는 개념 중, 겉 핥기식으로 알고 있는 개념들을 이번기회에

조금 정리해볼까한다.

 

오늘 정리할 내용은 GPT + 다른분 블로글 글인데

정말 머리가 안좋은, 내가 봐도 너무나 잘 정리해주셨다. GPT가 거의 필요 없을 정도..

 

나는 해당 블로그글을 나같이 초보가 이해하기쉽도록 풀어내는 방향에 집중하여 작성하도록하겠다.

 

참고 블로그는 아래 출처에 남기겠다.


🏁 학습할 내용

  • GCC와 LLVM
  • clang
  • LLVM 최적화 기법
    • LTO
    • PGO
    • BOLT

🤖 GCC와 LLVM

 

1️⃣  GCC

GNU Compiler Collection

 

 

✅  정의

 

C / C++, Objective-C등을 지원하는 GNU 프로젝트의 오픈 소스 컴파일러

 

🚀  특징

 

  • 자유 소프트웨어 Free softwarfe 
  • 프론트엔드-미들엔드-백엔드 구조
  • 모놀리식 구조
  • 활발한 커뮤니티

 

💡 컴파일러 3단 구조

1. 프론트엔드

- 소스코드(텍스트) 구조 분석
- 결과로 AST(Abstract Syntax Tree)를 만듬
- 코드를 읽고 해석하는 단계

2. 미들엔드

- AST를 최적화
- 불필요한 연산제거
- 코드 최적화

3. 백엔드

- 최적화된 코드를 명령어셋과 매핑하여, 기계어 생성
- 플랫폼에 맞는 기계어 생성

 

 

2️⃣  LLVM

Low Level Virtual Machine

 

✅  정의

 

재사용 가능한 모듈러 컴파일러를 위한 프레임워크(툴체인)를 만드는 프로젝트 이름

 

가상머신과는 관련이 없음.. 그냥 프로젝트 이름

 

🚀  특징

 

  • GCC와 같은 프론트엔드-Optimizer(미들엔드)-백엔드 구조
  • 모듈식 구조
  • Optimizer(미들엔드)가 IR을 받아 처리함
💡IR과 bitcode


1. IR (Intermediate Representation)
- RISC셋으로 표현된 저수준 언어
- 여전히 사림이 읽을 수 있음

2. bitcode
- IR의 바이너리 형태
- 컴파일러가 다루기 좋은 압축된 바이너리 IR
- 프론트 엔드 언어가 달라도, LLVM bitcode 형태가되면, 백엔드에서 사용가능
- iOS에서는 특정 아키텍쳐에 맞게 최적화여 제공하려는 목적으로 사용됐었음
- 현재는 따로 제공하지 않아도 됨

 

 

3️⃣  GCC vs LLVM

모놀로식 vs 모듈식

 

GCC는 모놀리식 구조기 떄문에, GCC의 일부를 다른 컴파일러에서 사용하기 힘든구조다.

하지만 LLVM은 모듈식이기 떄문에, 프론트 엔드 쪽에서 Optimizer쪽으로 IR만 전달해주면


백엔드에서는 똑같이 동작한다.

 

이게 무엇을 의미할까?

 

  • VM 및 인터프리터 방식 언어도 지원 (GCC는 불가)
  • IR로 전달만해주면 무한히 확장 가능 (언어 제한 없음)

 

🍭 clang (클랭)

LLVM 기반으로 만들어진 C family 언어 컴파일러 프론트엔드

 

 

🍎 애플이 GCC말고 clang을 채택한 이유

 

 

먼저 macos 터미널에서 gcc --version 를 쳐보면 다음과 같은 출력 결과를 볼 수 있다.

결과적으로, 애플은 gcc가아닌 clang을 선택했다.

 

한번 그 이유에대해 살펴보자.

 

현재 iOS 생태계를 살펴볼 떄, Android와 큰 차이점 중 하나는 서명된 어플리케이션만 실행될 수 있다.

안드로이드, 윈도우는 서명되지 않은 앱을 따로 사용할 수 있다.

 

하지만 GCC는 오픈소스 프로젝트 GPLv3 섹션6에 의하면,
사용자가 소스코드를 수정해서 설치 및 이용이 가능해야한다.

 

하지만 애플은 수정된 버전의 사용을 막는 정책을 고집하고 있다.(DRM) - Digital Rights Management

따라서, 애플은 GCC를 대체할만한 다른 컴파일러가 필요한 상황...

 

이 때 눈이 뛴게 바로 LLVM에서 비롯된 clang이다.

 

또한 clang은 다음과 같은 점에서 애플에게 러블콜을 받앗다.

  • 코드 반영 속도 (GCC는 느림)
  • 모듈식 구조
  • 오래되지 않은 코드 베이스

🧪 LLVM 최적화 기법

 

LLVM에 적용된 최적화 기법 중 무난한 3가지 정도만 간단하게 정리하고 끝 마쳐보자.

 

먼저, 최적화 기법을 알아보기 전에, 컴파일 단계를 간단하게만 정리하고 가자.

 

0️⃣ 컴파일 과정

 

🧮 전처리 (Preprocess)

  • 헤더파일 삽입: #incldue에 해당하는 헤더파일 내용을 복사해 소스코드에 삽입
  • 매크로 확장: #define에 해당하는 매크로를 실제 값으로 확장(치환)
  • gcc -E [.c 파일명 또는 cpp] -o [결과 파일명.i]
  • 결과 파일: hello.i (전처리된 소스코드파일)  또는 .ii(cpp일 경우)

 

👷‍♂️ 컴파일 (Compile)

  • 컴파일러를 통해, 전처리된 소스 코드 파일(*.i 또는 *.ii)을 어셈블리어 파일로 변환하는 과정
  • 언어의 문법 검사 및 각 Static한 영역(Data, BSS)에 대한 메모리 할당을 진행
  • 기계어를 사람이 이해할 수 있는 마지막언어인 어셈블리어를 볼 수 있는 단계
  • gcc -S hello.i -o hello.s
  • 결과 파일: hello.s 

 

🤖 어셈블리 (Assembly)

  • 어셈블러를 통해, 어셈블리어 파일(*.s)을 완전하 기계어인 오브젝트 파일(*.o) 파일로 변환하는 고자어
  • 이제 사람이 읽기 힘듬
  • 파일 포맷은 OS에 종속적임
  • gcc -c hello.s -o hello.o

 

🔗 링킹 (Linking)

  • 링커를 통해, 오브젝트 파일(*.o)들을 묶어 실행 파일(executalbe)을 만드는 과정
  • 또한, 사용하는 라이브러리 파일들도 링킹에 포함됨
  • 이 떄, 라이브러리를 링크하는 방법에 따라 , 정적 링킹, 동적 링킹으로 나뉜다.
  • 링커는 실제로, 심볼을 해석하고, 데이터 주소나 코드의 메모리 참조 주소를 알맞게 재배치하는 과정을 거침
💡 심볼

- 
오브젝트 파일에 있는 함수 또는 변수들을 실제 코드/데이터 위치를 연결하기 위한 고유 표시

 

🧹 최종 정리

 

 

1️⃣ LTO (Link Time Optimization)

 

✅ 정의

 

이름에서도 추즉할 수 있다, 링킹 단계에서 수행되는 최적화

 

🚀  특징

  • 링킹 과정에서, 여러 오브젝트 파일들을 참고하니깐, 여기서 최적화를 진행한 실행한 파일을 만드는게 목적
  • 언어가 달라도 LLVM을 사용하면, 같은 형식의 오브젝트 파일을 사용
  • LLVM bitcode모듈을 읽고 합칠 수 있어, 언어와 상관없이 최적화를 수행할 수 있음
  • 즉, C로 사칙연산을 각각 정의하고, Rust에서 그 코드를 사용할 수 있다는 의미

 

2️⃣  PGO (Profile-Guided-Optimization)

 

✅ 정의

 

profile data를 사용해, 특정 시나리오에 성능을 높이는 최적화 기법

 

💡 profile data

특정 시나리오에서 프로그램의 사용량(CPU, 메모리, 함수 호출 횟수)등을 의미한다.

 

🚀  특징

  • 3가지 과정을 진행하여 최적화를 함
    • Instrumentation: profile data 얻는 과정
    • profile data 처리
    • 최적화

 

다음 2가지 과정을 통해, 좋은 성능 향상을 이끌어냄

  • inline
    • profile data를 사용하여, 많이 호출되는 부분만 inline처리를 하여 크기와 속도의 트레이드 오프를 맞춤

  • Layout
    • 실행 빈도가 높은 코드 경로를 메모리상에서 가깝게 배치

 

3️⃣  BOLT (Binary Optimization and Layout Tool)

 

✅ 정의

 

2018년 페이스북에서 제안한 바이너리 파일의 레이아웃을 최적화하는 기법

 

 

🚀  특징

  • CPU의 instruction cache / branch(분기) prediction 효율을 높이는 최적화
  • BOLT도 PGO처럼 profile data를 사용
  • 다른 점은 post-link 최적화라는 것, 즉 링킹까지 완료된 바이너리 파일에서 최적화를 진행
💡 바이너리 파일에서 진행하면 뭐가 좋을까?

- profile data는 바이너리 파일을 실행하면서 얻는다.
- 따라서 바이너리 파일에서 profile data를 이용하면, IR 레벨에서 사용할 떄보다 profile data 정확도가 높다.
- profile data는 컴파일러 파이프라인 어디든 사용할 수 있지만, 트레이드 오프가 크다


출처

https://pangyoalto.com/clang-and-optimization/

 

[LLVM & Clang] LLVM 최적화, 어디까지 아시나요?(LTO, PGO, BOLT)

Discover the depths of Clang optimization and learn about Link-Time Optimization (LTO), Profile-Guided Optimization (PGO), and Binary Optimization and Layout Tool (BOLT).

pangyoalto.com

https://en.wikibooks.org/wiki/GNU_C_Compiler_Internals/GNU_C_Compiler_Architecture?ref=pangyoalto.com

https://zeddios.tistory.com/655

 

App Thinning. 그리고 Bitcode

안녕하세요 :) Zedd입니다.음..ABI글을 쓰다가 또 Bitcode가 궁금해져서..이 Bitcode에 대해서 먼저 공부해보려고 합니다.ㅠ진짜 너무 어려워요..........Bitcode라던가 ABI라던가...이런 컴파일러(?)라고 해

zeddios.tistory.com

 

반응형

'CS > 이론' 카테고리의 다른 글

Throttle vs Debonuce  (4) 2025.08.06
[Text 시리즈 1] Typographical Concepts  (2) 2025.07.17
OAS(Open API Specification)  (1) 2025.07.04
아핀 변환(Affine Transformation)  (0) 2025.03.30
선형 변환  (0) 2025.03.30
'CS/이론' 카테고리의 다른 글
  • Throttle vs Debonuce
  • [Text 시리즈 1] Typographical Concepts
  • OAS(Open API Specification)
  • 아핀 변환(Affine Transformation)
Hamp
Hamp
남들에게 보여주기 부끄러운 잡다한 글을 적어 나가는 자칭 기술 블로그입니다.
  • Hamp
    Hamp의 분리수거함
    Hamp
  • 전체
    오늘
    어제
    • 분류 전체보기 (304)
      • CS (30)
        • 객체지향 (2)
        • Network (7)
        • OS (6)
        • 자료구조 (1)
        • LiveStreaming (3)
        • 이미지 (1)
        • 잡다한 질문 정리 (0)
        • Hardware (2)
        • 이론 (6)
        • 컴퓨터 그래픽스 (0)
      • Firebase (3)
      • Programing Langauge (37)
        • swift (32)
        • python (4)
        • Kotlin (1)
      • iOS (132)
        • UIKit (37)
        • Combine (1)
        • SwiftUI (32)
        • Framework (7)
        • Swift Concurrency (22)
        • Tuist (6)
        • Setting (11)
        • Modularization (1)
        • Instruments (6)
      • PS (59)
        • 프로그래머스 (24)
        • 백준 (13)
        • LeetCode (19)
        • 알고리즘 (3)
      • Git (18)
        • 명령어 (4)
        • 이론 (2)
        • hooks (1)
        • config (2)
        • action (7)
      • Shell Script (2)
      • Linux (6)
        • 명령어 (5)
      • Spring (13)
        • 어노테이션 (1)
        • 튜토리얼 (11)
      • CI-CD (4)
      • Android (0)
        • Jetpack Compose (0)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    AVFoundation
    투포인터
    CS
    property
    SwiftUI
    Spring
    dp
    boostcamp
    프로그래머스
    dfs
    lifecycle
    Swift
    GIT
    dispatch
    IOS
    concurrency
    UIKit
    protocol
    백준
    Tuist
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
Hamp
clang과 LLVM에 관하여
상단으로

티스토리툴바