我想在源代码级别自动展开用C编写的目标程序中的循环(FYI,我使用linux和gcc编译器)。关于详细的描述,让我们看看下面的简单源代码。
1: int main(){
2: int i = 0;
3: while(i<3){
4: printf("hi\n");
5: i++;
6: }
7: }
我想转换上面的源代码如下。
1: int main(){
2: int i = 0;
3: if (i<3){
4: printf("hi\n");
5: i++;
6: }
7: if (i<3){
8: printf("hi\n");
9: i++;
10: }
11: if (i<3){
12: printf("hi\n");
13: i++;
14: }
15:}
我知道CBMC会自动地为软件模型检查解压缩循环,但我不确定CBMC会将源代码转换为源代码来解压缩循环。我需要一个程序源代码,在那里所有的循环都是展开的。
我试图找到工具或解决方案,但我找不到。如有任何建议或意见,将不胜感激。谢谢!
抱歉把你搞糊涂了。我将解释我的最终目标“在源代码级别的循环展开”的细节。展开循环的最后一个目标是测量测试用例的#,测试用例执行语句,这些语句是由循环展开生成的。参考下面的,一个示例。
1: void ex(int i){
2: int i = 0;
3: while(i<3){
4: printf("hi\n");
5: i++;
6: }
7: }
当我转换上面的源代码时,我想得到以下源代码
1: void ex(int i){
2: if (i<3){
3: printf("hi\n");
4: i++;
5: }
6: if (i<3){
7: printf("hi\n");
8: i++;
9: }
10: if (i<3){
11: printf("hi\n");
12: i++;
13: }
14:}
从上面转换的源代码,我将测量#测试用例执行来自“循环展开”的每条语句。例如,从原始源代码中的第4行和第5行转换的执行#3、4或#7、8或#11、12行的测试用例的数量将不同于原始源代码中执行line#4,5的测试用例。
FYI,如果有一种方法可以达到我的最终目标,不需要解环,这条路也是好的!谢谢!
发布于 2012-12-31 08:21:41
通常情况下,gcc会比您更好地确定某些代码是否适合于展开代码。根据我的经验,你能比gcc做得更好是非常罕见的--唯一合理的情况是,当你有非常复杂的代码做“奇怪”的事情时,你的例子肯定不是这样的。
实际上,您是否尝试过使用带有优化的-S选项来查看编译器的功能?
当然,编译器可能有理由不优化这个特定的循环,因为printf()比所有循环加在一起要重得多,但这是一个稍微不同的问题。
发布于 2012-12-31 08:17:32
您应该查看汇编程序,看看在循环展开中编译器实际上有多好。但是,您还可以帮助编译器编写更好的程序:
for (unsigned i = 0; i < 3; ++i) {
printf("hi\n");
}
也就是说,使用无符号整数类型作为循环变量(size_t
通常是个好主意),并让循环变量局部性。然后使用像-S -O3 -march=native
这样的编译器选项检查汇编程序。
然后,只有到那时,如果您对结果不满意,请查看P99。它有一组宏可以展开,而不仅仅是循环。寻找类似P99_FOR
的东西。
https://stackoverflow.com/questions/14099113
复制相似问题