LLVM优化器无法处理简单情况?
LLVM optimizer can't handle simple case?
我写了一个.cpp文件,如下所示
int main() {
int a, b;
scanf( "%d", &b );
for ( int i = 0 ; i < 1000 ; i++ ) {
a = 0;
if ( b > 10 )
a = 3;
}
return a;
}
然后我用-O3选项编译了这个代码,输出的.ll文件是
define i32 @main() #0 {
entry:
%b = alloca i32, align 4
%call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b)
%0 = load i32* %b, align 4, !tbaa !1
%cmp1 = icmp sgt i32 %0, 10
%. = select i1 %cmp1, i32 3, i32 0
ret i32 %.
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
这个输出很好。LLVM优化器从代码中剥离了无意义的forloop
,然后直接指定3或0返回值。
现在我尝试另一种情况,如
int main() {
int a, b;
scanf( "%d", &b );
for ( int i = 0 ; i < 1000 ; i++ ) {
a = 0;
if ( true ) // I modified here only
a = 3;
}
return a;
}
输出文件为
define i32 @main() #0 {
entry:
%b = alloca i32, align 4
%call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b)
br label %for.cond
for.cond: ; preds = %for.cond, %entry
%a.0 = phi i32 [ 0, %entry ], [ 3, %for.cond ]
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
%inc = add nsw i32 %i.0, 1
%exitcond = icmp eq i32 %inc, 1001
br i1 %exitcond, label %for.end, label %for.cond
for.end: ; preds = %for.cond
ret i32 %a.0
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
尽管这段代码更容易分析(总是采用分支),LLVM优化器并没有剥离毫无意义的forloop
如果我是优化器,我想生成像这样的优化代码
define i32 @main() #0 {
entry:
%b = alloca i32, align 4
%call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b)
ret i32 3
}
有人能告诉我为什么优化器不能分析更简单的代码吗?
我已经用llvm 3.9
测试了您的代码片段,它生成了:
define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = bitcast i32* %1 to i8*
call void @llvm.lifetime.start(i64 4, i8* %2) #3
%3 = call i32 (i8*, ...) @scanf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32* nonnull %1)
call void @llvm.lifetime.end(i64 4, i8* %2) #3
ret i32 3
}
正如MikeMB所暗示的,我想这是优化器中的一个错误,现在已经修复。您的llvm
版本是什么?
相关文章:
- 如何在没有函数的情况下编写此代码并使C++更简单?
- 我们可以在不使用head指针的情况下通过使用head的简单变量而不是head的指针来实现链表吗
- 简单情况下的模板缓冲区行为(GL_ALWAYS、GL_LEQUAL)
- 将指针传递给函数在简单的情况下有效,但在"class" -izing 之后不起作用
- 我如何在不关闭的情况下使这个简单的程序返回
- 一种在没有 root 的情况下加载共享库的更简单方法
- 在这种简单的情况下,可能是僵局
- 是否存在简单的指向布尔值作为线程取消标志的现实情况,无法有效地取消线程?
- 在简单情况下,同时写并阅读布尔值的危险
- LLVM优化器无法处理简单情况?
- 在没有序列化库的情况下,在 c++ 中从结构体读取和写入文件的最简单方法是什么?
- 如何在没有Windows API的情况下在Turbo-C++中制作一个简单的文本编辑器
- pocketsphinx的简单示例适用于基本的c测试,但不适用于包含在c++项目中的情况
- 在简单的情况下使用scoped_ptr是不是矫枉过正
- 在没有硬件的情况下测试此功能的简单/创造性方法
- 如何在不重复每年的for循环的情况下使这个简单的代码更加高效
- 为什么volatile变量即使在非常简单的情况下也没有优化
- 如何在没有Win32 API的情况下制作一个简单的窗口
- 在关闭RTTI的情况下增强简单类的序列化(-fno-rtti)
- 如何在不提供构造函数的情况下创建和初始化一个简单结构