LLVM循环不变代码运动(-licm)通过

时间:2018-11-05 04:03:31

标签: loops llvm compiler-optimization static-analysis

我有一些简单的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

我想念什么?还有其他途径可以实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

您丢失了%s.addr在while循环中不是不变的。循环不变代码运动优化可识别在迭代之间不改变的表达式,并尝试将其从循环中取出。您正在寻找的是诸如常见子表达式消除之类的东西。此优化可识别相同子表达式的重复计算,并尝试删除除一个子表达式之外的所有表达式。 在我的opt版本中,此优化是通过-early-cse开关启用的。