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