我有一些简单的C循环代码,我想简化 尽可能。这是原始的C文件:
#include <stdio.h>
char *foo(char *s)
{
while (*s == 'a' || *s == 'b')
{
s++;
}
return s;
}
int main(int argc, char **argv)
{
char *s1 = argv[1];
char *s2 = foo(s1);
return 0;
}
我尝试将opt
与-licm
标志一起使用,该标志应该:
从循环体内删除尽可能多的代码。它可以通过将代码提升到preheader块中来实现
但是,当我看一下循环主体时,我发现第21和22行确实是冗余,因为%s.addr
并没有变化,因此行可以安全地删除21和22,我们可以从第23行使用%tmp3
代替%tmp1
向前。
13 while.cond: ; preds = %while.body, %entry
14 %tmp = load i8*, i8** %s.addr, align 8
15 %tmp1 = load i8, i8* %tmp, align 1
16 %conv = sext i8 %tmp1 to i32
17 %cmp = icmp eq i32 %conv, 97
18 br i1 %cmp, label %lor.end, label %lor.rhs
19
20 lor.rhs: ; preds = %while.cond
21 %tmp2 = load i8*, i8** %s.addr, align 8
22 %tmp3 = load i8, i8* %tmp2, align 1
23 %conv2 = sext i8 %tmp3 to i32
24 %cmp3 = icmp eq i32 %conv2, 98
25 br label %lor.end
我想念什么?还有其他途径可以实现这个目标吗?
答案 0 :(得分:1)
您丢失了%s.addr
在while循环中不是不变的。循环不变代码运动优化可识别在迭代之间不改变的表达式,并尝试将其从循环中取出。您正在寻找的是诸如常见子表达式消除之类的东西。此优化可识别相同子表达式的重复计算,并尝试删除除一个子表达式之外的所有表达式。
在我的opt
版本中,此优化是通过-early-cse
开关启用的。