【发布时间】:2016-02-28 20:19:19
【问题描述】:
我想演示 LLVM 中使用了冗余删除。
我从 opt 中找到了选项 -gvn(全局值编号)。我测试了以下示例:
int foo(int a, int b) {
int c, d, e, f, g;
c = a + b;
d = a + b;
e = a;
f = e + b;
g = c + d + e + f;
return f;
}
使用这些程序:
clang -S -emit-llvm eg.c
llvm-as eg.ll
opt -gvn eg.ll -o eg_opt.ll
但是,我观察到 add 操作的数量与以前相同。
例如.ll
define i32 @foo(i32 %a, i32 %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
%c = alloca i32, align 4
%d = alloca i32, align 4
%e = alloca i32, align 4
%f = alloca i32, align 4
%g = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
store i32 %b, i32* %b.addr, align 4
%0 = load i32, i32* %a.addr, align 4
%1 = load i32, i32* %b.addr, align 4
%add = add nsw i32 %0, %1
store i32 %add, i32* %c, align 4
%2 = load i32, i32* %a.addr, align 4
%3 = load i32, i32* %b.addr, align 4
%add1 = add nsw i32 %2, %3
store i32 %add1, i32* %d, align 4
%4 = load i32, i32* %a.addr, align 4
store i32 %4, i32* %e, align 4
%5 = load i32, i32* %e, align 4
%6 = load i32, i32* %b.addr, align 4
%add2 = add nsw i32 %5, %6
store i32 %add2, i32* %f, align 4
%7 = load i32, i32* %c, align 4
%8 = load i32, i32* %d, align 4
%add3 = add nsw i32 %7, %8
%9 = load i32, i32* %e, align 4
%add4 = add nsw i32 %add3, %9
%10 = load i32, i32* %f, align 4
%add5 = add nsw i32 %add4, %10
store i32 %add5, i32* %g, align 4
%11 = load i32, i32* %f, align 4
ret i32 %11
}
eg_opt.ll
define i32 @foo(i32 %a, i32 %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
%c = alloca i32, align 4
%d = alloca i32, align 4
%e = alloca i32, align 4
%f = alloca i32, align 4
%g = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
store i32 %b, i32* %b.addr, align 4
%0 = load i32, i32* %a.addr, align 4
%add = add nsw i32 %0, %b
store i32 %add, i32* %c, align 4
%1 = load i32, i32* %a.addr, align 4
%2 = load i32, i32* %b.addr, align 4
%add1 = add nsw i32 %1, %2
store i32 %add1, i32* %d, align 4
%3 = load i32, i32* %a.addr, align 4
store i32 %3, i32* %e, align 4
%4 = load i32, i32* %b.addr, align 4
%add2 = add nsw i32 %3, %4
store i32 %add2, i32* %f, align 4
%5 = load i32, i32* %c, align 4
%6 = load i32, i32* %d, align 4
%add3 = add nsw i32 %5, %6
%7 = load i32, i32* %e, align 4
%add4 = add nsw i32 %add3, %7
%add5 = add nsw i32 %add4, %add2
store i32 %add5, i32* %g, align 4
%8 = load i32, i32* %f, align 4
ret i32 %8
}
我错过了什么吗?
【问题讨论】:
-
您是否尝试过使用-basicaa?如果没有别名分析,它不会触及那些负载存储。
-
或者,更好的是,使用 mem2reg 获取 SSA。它不仅更有可能被优化,而且更容易遵循。
标签: compiler-construction clang llvm compiler-optimization llvm-clang