LLVM이란 Apache 2.0 License로 오픈소스이다. LLVM은 개발코드를 기계어로 변경하는 일종의 컴파일러 역할을 진행해주는 모듈 이다.
LLVM에는 llvm-gcc, clang등 다양한 모듈이 존재하고 있으며 clang의 경우 c/c++ 대상으로 컴파일하여 바이너리를 만드는데 빠른시간의 강한 성능을 자랑한다. 최근에는 c/c++ 컴파일을 진행하는데 front는 clnag으로 back은 llvm 구조로 많이 사용하는 것으로 보인다.
1. 구조
LLVM structure는 크게 3가지로 나누어 볼 수 있다.
http://www.aosabook.org/en/llvm.html
LLVM은 크게 Front-end, Optimizer, Back-end로 나눌 수 있으며 front-end는 C, C++, Java, 등의 코드들을 받아서 LLVM IR을 통해 변환하는 작업을 진행하고 Back-end는 optimizier된 코드를 최종적으로 x86, x86-64, ARM 등 CPU환경에 맞는 바이너리를 생성하는 작업을 진행한다.
위 동작들은 모두 LLVM IR을 통해서 이뤄지며 LLVM IR은 LLVM의 핵심이라고 할 수 있다.
어느 c언어 코드를 clang-llvm으로 바이너리 파일로 컴파일을 진행한다고 하자.
그럼 먼저 clang을 통해서 c언어를 llvm IR로 바꾸는 front-ent가 이루어질 것이고 llvm은 llvm IR을 system에 맞는 바이너리파일로 생성할 것이다.
define i32 @add1(i32 %a, i32 %b) { entry: %tmp1 = add i32 %a, %b ret i32 %tmp1 } define i32 @add2(i32 %a, i32 %b) { entry: %tmp1 = icmp eq i32 %a, 0 br i1 %tmp1, label %done, label %recurse recurse: %tmp2 = sub i32 %a, 1 %tmp3 = add i32 %b, 1 %tmp4 = call i32 @add2(i32 %tmp2, i32 %tmp3) ret i32 %tmp4 done: ret i32 %b } 출처: <http://www.aosabook.org/en/llvm.html> |
위와 같이 이루어진 코드가 바로 llvm IR이다. llvm IR은 중간언어답게 c/c++와 같은 고급언어보다는 해석하기 어려우나
기계어보다는 사람이 해석하기 쉬운 모습을 보이고 있다.
http://www.aosabook.org/en/llvm.html
위 과정은 LLVM의 동작과정을 조금 더 구체화하여 나타낸 것이다.
내용은 동일하다. clang이 llvm IR을만들고 optimizer가 최적화를 진행하여 .o파일을 생성하는 것을 컴파일 과정으로보고
이후에 LLVM linker를 통해서 메모리 영역을 정리하고 마지막으로 dead code제거 등 또 한 번의 optimizer를 통해서 바이너리를 만드는 Linker과정이 존재한다.
2. Debug
g++ 디버거 모듈로 gdb가 있듯이 LLVM(Clang)에는 LLDB라는 debug가 존재한다.
gdb와 마찬가지로 분석이 가능하고 break point등의 방법으로 코드를 동작시키면서 내용을 확인할 수 있다.
나중에 LLDB만을 따로 공부하는 시간을 가지면 좋을 것 같다.
- ref