Open lfeng14 opened 2 months ago
// example.c #include <stdio.h>
int main() { int a = 10; int b = 20; int c = a + b; // 有用的计算 int d = a * b; // 无用的计算,没有使用变量 d
printf("Sum: %d\n", c); return 0;
}
- 使用 clang 将源代码文件编译成 LLVM IR 文件:
clang -S -emit-llvm example.c -o example.ll
; example.ll ; ModuleID = 'example.c' source_filename = "example.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [7 x i8] c"Sum: %d\00", align 1
; Function Attrs: noinline nounwind optnone uwtable define i32 @main() #0 { entry: %a = alloca i32, align 4 %b = alloca i32, align 4 %c = alloca i32, align 4 %d = alloca i32, align 4 store i32 10, i32 %a, align 4 store i32 20, i32 %b, align 4 %0 = load i32, i32 %a, align 4 %1 = load i32, i32 %b, align 4 %add = add nsw i32 %0, %1 store i32 %add, i32 %c, align 4 %2 = load i32, i32 %a, align 4 %3 = load i32, i32 %b, align 4 %mul = mul nsw i32 %2, %3 store i32 %mul, i32 %d, align 4 %4 = load i32, i32 %c, align 4 %call = call i32 (i8, ...) @printf(i8 getelementptr inbounds ([7 x i8], [7 x i8] @.str, i32 0, i32 0), i32 %4) ret i32 0 }
declare dso_local i32 @printf(i8*, ...) #1
- 使用 opt 工具对生成的 LLVM IR 文件进行优化,删除无用指令
opt -S -passes=dce example.ll -o example_opt.ll
- 查看优化后的指令
; example_opt.ll ; ModuleID = 'example.c' source_filename = "example.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu"
; Function Attrs: noinline nounwind optnone uwtable define i32 @main() #0 { entry: %a = alloca i32, align 4 %b = alloca i32, align 4 %c = alloca i32, align 4 store i32 10, i32 %a, align 4 store i32 20, i32 %b, align 4 %0 = load i32, i32 %a, align 4 %1 = load i32, i32 %b, align 4 %add = add nsw i32 %0, %1 store i32 %add, i32 %c, align 4 %4 = load i32, i32 %c, align 4 %call = call i32 (i8, ...) @printf(i8 getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 %4) ret i32 0 }
步骤
int main() { int a = 10; int b = 20; int c = a + b; // 有用的计算 int d = a * b; // 无用的计算,没有使用变量 d
}
clang -S -emit-llvm example.c -o example.ll
; example.ll ; ModuleID = 'example.c' source_filename = "example.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [7 x i8] c"Sum: %d\00", align 1
; Function Attrs: noinline nounwind optnone uwtable define i32 @main() #0 { entry: %a = alloca i32, align 4 %b = alloca i32, align 4 %c = alloca i32, align 4 %d = alloca i32, align 4 store i32 10, i32 %a, align 4 store i32 20, i32 %b, align 4 %0 = load i32, i32 %a, align 4 %1 = load i32, i32 %b, align 4 %add = add nsw i32 %0, %1 store i32 %add, i32 %c, align 4 %2 = load i32, i32 %a, align 4 %3 = load i32, i32 %b, align 4 %mul = mul nsw i32 %2, %3 store i32 %mul, i32 %d, align 4 %4 = load i32, i32 %c, align 4 %call = call i32 (i8, ...) @printf(i8 getelementptr inbounds ([7 x i8], [7 x i8] @.str, i32 0, i32 0), i32 %4) ret i32 0 }
declare dso_local i32 @printf(i8*, ...) #1
opt -S -passes=dce example.ll -o example_opt.ll
; example_opt.ll ; ModuleID = 'example.c' source_filename = "example.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [7 x i8] c"Sum: %d\00", align 1
; Function Attrs: noinline nounwind optnone uwtable define i32 @main() #0 { entry: %a = alloca i32, align 4 %b = alloca i32, align 4 %c = alloca i32, align 4 store i32 10, i32 %a, align 4 store i32 20, i32 %b, align 4 %0 = load i32, i32 %a, align 4 %1 = load i32, i32 %b, align 4 %add = add nsw i32 %0, %1 store i32 %add, i32 %c, align 4 %4 = load i32, i32 %c, align 4 %call = call i32 (i8, ...) @printf(i8 getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 %4) ret i32 0 }
declare dso_local i32 @printf(i8*, ...) #1