Why should I know this?

LLVM Study 관련 팁 본문

LLVM-STUDY

LLVM Study 관련 팁

die4taoam 2023. 10. 25. 14:29

https://youtu.be/J5xExRGaIIY?si=nh8WkBmkIdjTMGGb

 

OPT를 사용하여 IR을 생성할 때 다음과 같은 옵션을 지정하면,
1.원본 변수/함수 이름이 남고
2. 불필요한 메모리할당이 없어

보기 좋다.

 

$ clang -O2 -Xclang -disable-llvm-passes -S -emit-llvm -fno-discard-value-names f.c -o f.ll

$ opt -S -passes='mem2reg' f.ll -o f_opt.ll

clang 을 사용할 때의 최적화 레벨이 남는 듯;

int f(int a, int b) {
  int x = a;

  if (a > b)
    x += 20;
  else
    x += b;

  return x;
}
define dso_local i32 @f(i32 noundef %a, i32 noundef %b) #0 {
entry:
  %a.addr = alloca i32, align 4
  %b.addr = alloca i32, align 4
  %x = alloca i32, align 4
  store i32 %a, ptr %a.addr, align 4
  store i32 %b, ptr %b.addr, align 4
  %0 = load i32, ptr %a.addr, align 4
  store i32 %0, ptr %x, align 4
  %1 = load i32, ptr %a.addr, align 4
  %2 = load i32, ptr %b.addr, align 4
  %cmp = icmp sgt i32 %1, %2
  br i1 %cmp, label %if.then, label %if.else

if.then:                                          ; preds = %entry
  %3 = load i32, ptr %x, align 4
  %add = add nsw i32 %3, 20
  store i32 %add, ptr %x, align 4
  br label %if.end

if.else:                                          ; preds = %entry
  %4 = load i32, ptr %b.addr, align 4
  %5 = load i32, ptr %x, align 4
  %add1 = add nsw i32 %5, %4
  store i32 %add1, ptr %x, align 4
  br label %if.end

if.end:                                           ; preds = %if.else, %if.then
  %6 = load i32, ptr %x, align 4
  ret i32 %6
}

define dso_local i32 @f(i32 noundef %a, i32 noundef %b) #0 {
entry:
  %cmp = icmp sgt i32 %a, %b
  br i1 %cmp, label %if.then, label %if.else

if.then:                                          ; preds = %entry
  %add = add nsw i32 %a, 20
  br label %if.end

if.else:                                          ; preds = %entry
  %add1 = add nsw i32 %a, %b
  br label %if.end

if.end:                                           ; preds = %if.else, %if.then
  %x.0 = phi i32 [ %add, %if.then ], [ %add1, %if.else ]
  ret i32 %x.0
}
C 코드 Clang -S -emit-llvm -fno-discard-value-names
옵션지정

 

https://youtu.be/3RCDB3_wUEM?si=Q8j2D9t8s_QDQ6S7

 

각 PASS 별로 IR의 변화를 계측할 수 있는 실행 옵션  : gcc의 -tree-dump-all  유사

# opt -S p.ll -debug-only=instcombine -O2 2>&1 > /dev/null

의 실행 결과 일부

INSTCOMBINE ITERATION #1 on g
ADD:   ret i32 %cond
ADD:   %cond = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
IC: Visiting:   %cond = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
IC: Visiting:   ret i32 %cond

 

# opt -S p.ll -debug-only=instcombine -passes='instcombine' -print-before-all -print-after-all 2>&1 > /dev/null

의 실행 결과 일부

IC: Visiting:   %a.addr = alloca i32, align 4
IC: Visiting:   store i32 %a, ptr %a.addr, align 4, !tbaa !6
IC: Visiting:   %cmp = icmp sgt i32 %a, 0
IC: Visiting:   br i1 %cmp, label %cond.true, label %cond.false
IC: Visiting:   %1 = load i32, ptr %a.addr, align 4, !tbaa !6
IC: Visiting:   %sub = sub nsw i32 0, %1
Negator: attempting to sink negation into   %1 = load i32, ptr %a.addr, align 4, !tbaa !6
Negator: failed to sink negation into   %1 = load i32, ptr %a.addr, align 4, !tbaa !6
IC: Visiting:   br label %cond.end
IC: Visiting:   %0 = load i32, ptr %a.addr, align 4, !tbaa !6
IC: Visiting:   br label %cond.end
IC: Visiting:   %cond = phi i32 [ %0, %cond.true ], [ %sub, %cond.false ]
IC: Visiting:   ret i32 %cond
; *** IR Dump After InstCombinePass on g ***
; Function Attrs: nounwind uwtable

 

# opt -S p.ll -O2 -print-before-all -print-after-all 2>&1 > /dev/null

의 실행 결과 일부

; *** IR Dump After PromotePass on g ***
; Function Attrs: nounwind uwtable
define dso_local i32 @g(i32 noundef %a) local_unnamed_addr #0 {
entry:
  %cmp = icmp sgt i32 %a, 0
  %sub = sub nsw i32 0, %a
  %cond = select i1 %cmp, i32 %a, i32 %sub
  ret i32 %cond
}
; *** IR Dump After InstCombinePass on g ***
; Function Attrs: nounwind uwtable
define dso_local i32 @g(i32 noundef %a) local_unnamed_addr #0 {
entry:
  %cond = call i32 @llvm.abs.i32(i32 %a, i1 true)
  ret i32 %cond
}
; *** IR Dump After SimplifyCFGPass on g ***
; Function Attrs: nounwind uwtable
define dso_local i32 @g(i32 noundef %a) local_unnamed_addr #0 {
entry:
  %cond = call i32 @llvm.abs.i32(i32 %a, i1 true)
  ret i32 %cond
}

clang 으로 -mllvm과 함께 opt 옵션 지정 가능

# clang -O2 -mllvm -print-after-all p.c

 

'LLVM-STUDY' 카테고리의 다른 글

computeKnownBits & KnownBits 관련 예제  (0) 2023.12.05
byval  (0) 2023.11.07
LLVM Pass 작성 - 2018년 이후  (0) 2023.10.11
Souper 분석 관련 키워드들  (0) 2023.09.23
LLVM 에 기여하기 (feat.UFTRACE)  (0) 2023.09.15
Comments