LLVM通证不执行单静态赋值。

问题描述 投票:0回答:1

我使用的是预制的LLVM 6.0,当我执行 llvm pass -mem2reg 生成SSA,IR代码保持原样,没有被改变。但是当我使用预制的LLVM 3.8来做同样的事情时,llvm pass就可以了。但是,我需要使用LLVM 6.0,因为我在使用其他工具,利用这个LLVM版本。

举个具体的例子:下面是c代码。

int main(int argc, char** argv){
    int total_lines = 0;
    int total_chars = 0;

    int count_chars = 0;
    int count_lines = 0;

    if(argc == 1){
        printf("Please specify count line and chars\n");
    } else if (argc ==2){
        if (!strcmp(argv[1], "-c")){
            count_chars = 1;
        }else if (!strcmp(argv[1], "-l")){
            count_lines = 1;
        }
    }

    char buffer[1024];
    while (fgets(buffer, 1024,stdin)){
        if (count_chars)
            total_chars += sizeof(buffer);
        if (count_lines)
            total_lines += lineCount();
    }
    if (count_chars)
        printf("Count chars is:: %d\n", total_chars);
    if (count_lines)
        printf("Count Lines is:: %d\n", total_lines);
    return 0;
}

我运行LLVM通证来生成SSA,然后使用以下命令生成人类可读的IR代码。

LLVM_6.0_bin/bin/clang -c -emit-llvm example.c
LLVM_6.0_bin/bin/llvm-dis example.bc -o h1.ll

//SSA LLVM pass 
LLVM_6.0_bin/bin/opt -mem2reg example.bc -o example_SSA.bc
LLVM_6.0_bin/bin/llvm-dis example_SSA.bc -o h2.ll

diff h1 h2 //I receive the following

< ; ModuleID = 'example.bc'
---
> ; ModuleID = 'example_SSA.bc'

而当我做同样的步骤,但使用预制的LLVM 3. 8时,和: diff h1 h2 我得到了许多不同,包括以下几点

< ; <label>:50                                      ; preds = %29
<   %51 = load i32, i32* %count_chars, align 4
<   %52 = icmp ne i32 %51, 0
<   br i1 %52, label %53, label %56
< 
< ; <label>:53                                      ; preds = %50
<   %54 = load i32, i32* %total_chars, align 4
<   %55 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i32 0, i32 0), i32 %54)
<   br label %56
< 
< ; <label>:56                                      ; preds = %53, %50
<   %57 = load i32, i32* %count_lines, align 4
<   %58 = icmp ne i32 %57, 0
<   br i1 %58, label %59, label %62
< 
< ; <label>:59                                      ; preds = %56
<   %60 = load i32, i32* %total_lines, align 4
<   %61 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.5, i32 0, i32 0), i32 %60)
<   br label %62
---
> ; <label>:22                                      ; preds = %38, %21
>   %total_lines.0 = phi i32 [ 0, %21 ], [ %total_lines.1, %38 ]
>   %total_chars.0 = phi i32 [ 0, %21 ], [ %total_chars.1, %38 ]
>   %23 = getelementptr inbounds [1024 x i8], [1024 x i8]* %buffer, i32 0, i32 0
>   %24 = load %struct._IO_FILE*, %struct._IO_FILE** @stdin, align 8
>   %25 = call i8* @fgets(i8* %23, i32 1024, %struct._IO_FILE* %24)
>   %26 = icmp ne i8* %25, null
>   br i1 %26, label %27, label %39

llvm llvm-ir ssa
1个回答
0
投票

我找到了解决方案,它的基础上,这个答案 LLVM opt mem2reg没有效果

新版本的LLVM对由下面的程序生成的位码进行了注释 clang 以防止以后再进行额外的优化。所以我只需要添加这些标志 -Xclang -disable-O0-optnone 到clang命令

LLVM_6.0_bin/bin/clang -c -emit-llvm example.c

LLVM_6.0_bin/bin/clang -Xclang -disable-O0-optnone -c -emit-llvm example.c

© www.soinside.com 2019 - 2024. All rights reserved.