【问题标题】:LLVM pass doesn't perform single static assignmentLLVM pass 不执行单个静态分配
【发布时间】:2020-06-12 12:50:33
【问题描述】:

我使用的是预构建的 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 pass 以生成 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

【问题讨论】:

  • 您能否添加一个最小的工作示例来说明您的意思。还请为这两种解决方案提供生成的 IR。例如一个简单的 C 主函数,它根据输入参数进行一些赋值
  • 我添加了更多解释

标签: llvm llvm-ir ssa


【解决方案1】:

我找到了基于此答案LLVM opt mem2reg has no effect的解决方案

新版本的 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多