본문 바로가기

Compiler/LLVM

LLVM Hello world IR생성

반응형

LLVM Hello world입니다.
clang으로 IR생성하는법을 적어봅니다.

먼저 add.c 파일을 아래와 같이 생성합니다

int globvar = 12;

int add(int a) {
    return globvar + a;
}

아래 명령어를 수행하면, (clang install해야합니다)

clang -emit-llvm -c -S add.c

아래와 같이 add.ll 파일이 생성됩니다.

; ModuleID = 'add.c'
source_filename = "add.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

@globvar = dso_local global i32 12, align 4

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @add(i32 noundef %0) #0 {
  %2 = alloca i32, align 4
  store i32 %0, i32* %2, align 4
  %3 = load i32, i32* @globvar, align 4
  %4 = load i32, i32* %2, align 4
  %5 = add nsw i32 %3, %4
  ret i32 %5
}

attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 1}
!4 = !{i32 7, !"frame-pointer", i32 2}
!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1"}

이제 생성된 IR (add.ll 파일)을 살펴보고 그것이 무엇인지 살펴보겠습니다.

첫번째 줄에서 add.c 파일에 대한 LLVM 모듈을 정의하는 ModuleID를 볼수 있습니다.
LLVM 모듈은 입력 LLVM 파일의 전체 내용을 포함하는 최상위 데이터 구조입니다.
함수, 전역 변수, 외부 함수 프로토타입 및 기호 테이블 항목으로 구성됩니다.

다음 줄은 대상 데이터 레이아웃과 대상 트리플을 보여줍니다.
target은 Linux가 실행되는 x86_64 프로세서임을 알 수 있습니다.
datalayout 문자열은 기계의 엔디안(‘e’는 리틀 엔디안을 의미)과 맹글링(m : e는 엘프형을 나타냄).
각 사양은 ‘-‘로 구분되며 다음 각 사양은 해당 유형의 유형과 크기에 대한 정보를 제공합니다.
예를 들어, i64:64는 64비트 정수가 64비트임을 나타냅니다.
그런 다음 전역 변수 globvar가 있습니다.

LLVM IR에서 모든 전역 변수는 ‘@’로 시작하고 모든 지역 변수는 ‘%’로 시작합니다.

이상으로 가장 기본적인 ll 파일을 생성하는 법을 한번 보았습니다.

반응형