컴파일러

[컴파일러] 1. LLVM을 이용한 컴파일 방법 및 IR파일 읽기(feat. 소스코드와 IR 코드 )

용성군 2021. 7. 31. 07:42
728x90
반응형

글을 작성하기에 앞서 한양대 Computer Architecture and System Software LAB에서 제공받은 자료를 바탕으로 작성되었다.

 

이번 글에서는 clang, llvm-as, llvm-dis, llc의 명령어를 사용해 IR 코드 (.bc, .ll 파일)와 바이너리(실행 파일)로 컴파일하는 방법을 알아보도록 하겠다.

 

clangLLVM IR 기반 컴파일러 중 하나로, C, C++등 다양한 언어들을 IR 단계로 컴파일 하도록 지원한다

 

컴파일러는 프론트엔드와 백엔드로 나뉘어지는데 clang은 언어에 따라 컴파일 해주는 프론트엔드 부분을 담당하고 있다. 

다음을 보면 .c와 .cpp 소스코드는 clang을 통해 llvm bitcode로 컴파일되는것을 알 수 있다. 

출처 : https://www.praj.in/posts/2020/graalvms-secret-llvm-backend/

llvm-as, llvm-disIR 레벨의 AssemblerDisassembler로, 이를 사용하여 서로 human-readable assembly 형태의 코드(.ll 파일)와 bitcode 형태의 코드(.bc)로 바꿀 수 있다.

 

llcLLVM 백엔드 컴파일 명령어로, bitcode 형태를 머신 어셈블리로 변환한다.


Clang의 사용법

GCC에서 사용하는 컴파일 옵션을 대부분 지원하며 다음과 같이 사용한다.

$ clang <source_file> [-o output_path]

Clang을 사용하여 HelloWorld.c 파일을 컴파일하고 실행한다.

다음은 IR레벨 까지 compile 해주는 명령어이며 각각의 명령어는 .bc와 .ll파일로 만들어진다.

$ clang –emit-llvm -c <source_file> [-o output_path] # 소스파일을 bitcode 형태로 바꿔주는 명령

$ clang –emit-llvm -S <source_file> [-o output_path] # 소스파일을 Human readable assembly(*.ll)로 바꿔주는 명령

 

 clang을 사용하면 IR에서 실행가능한 바이너리로 컴파일 할 수 있습니다.
(llc
 IR코드를 어셈블리로 컴파일하고 어셈블리를 돌린 후 링킹해서 실행가능한 바이너리를 얻을 수도 있습니다.)

반응형

LLVM Assembler, Disassembler와 LLC

  • llvm-as(assembler), llvm-dis(disassembler)를 사용하여 LLVM IR의 형태를 변환 할 수 있다.
$ llvm-as <IR file> [-o=output path] # readable (*.ll) 에서 bitcode (*.bc)로 변환

$ llvm-dis <IR file> [-o=output path] # bitcode(*.bc) 에서 readable (*.ll)로 변환

  • llc를 사용하면 IR을 타겟 머신의 바이너리 (어셈블리)로 컴파일 할 수 있습니다.
$ llc <IR file> [-o output_path]

다음은 컴파일 한 assembly 파일(.s ) 입니다.


Human Readable Assembly 파일을 읽어오기

다음의 컴파일 옵션을 사용해 컴파일하고 .ll(Human Readable Assembly) 파일을 읽도록 하겠다.

$ clang++ <file> $(llvm-config --cxxflags --ldflags --system-libs --libs [name list])

 

ReadIR.cpp을 컴파일
ReadIR 실행하여 .ll파일을 읽어오기

 

ReadIR.cpp 파일은 llvm::Module을 통해 .ll파일을 읽어온다.

 

여기서 llvm::Module 클래스는 컴파일 및 최적화를 수행하기 위한 단위를 나타내는 클래스로 보통 하나의 파일을 의미한다.

 

IR파일을 parsing할 때 필요한 llvm::LLVMContext 클래스는 전체 컴파일과정에서 일관된 자료형 및 전역 변수 등을 포함하는 컨택스트를 나타낸다.

 

 

 

추가적인 참고사항

LLVM이란? 
https://zeddios.tistory.com/1175

 

728x90
반응형