考虑以下C99代码(使用alloca扩展名。)
void print_int_list(size_t size, int x[size]) {
int y[size];
memcpy(y, x, size * sizeof *x);
for (size_t ii = 0; ii < size; ++ii)
printf("%i ", y[ii]);
printf("\n");
}
void print_int_list_2(size_t size, int x[size]) {
for (size_t ii = 0; ii < size; ++ii)
printf("%i ", x[ii]);
printf("\n");
}
void print_int(int x) {
int * restrict const y = alloca(sizeof x);
memcpy(y, &x, sizeof x);
printf("%d\n", *y);
}
void print_int_2(int x) {
printf("%d\n", *x);
}
在代码中,print_int被优化为与Clang 3.0版上的print_int_2完全相同,但函数print_int_list未优化到print_int_2。相反,保留了无用的数组副本。
对于大多数人来说,这种事情不是问题,但它适合我。我打算通过生成用于Clang的C代码来构建编译器的原型(后来直接将它移植到LLVM),我想生成极其愚蠢,简单且明显正确的代码,并让LLVM完成优化代码的工作
我需要知道的是如何让Clang优化掉无用的数组副本,以便像print_int_list这样的愚蠢代码优化到像print_int_list_2这样的代码中。
答案 0 :(得分:1)
首先,我会更加谨慎。在你拥有的两个案例之间有一个步骤,固定大小的数组。我认为现在编译器可以跟踪也用编译时常量索引的数组组件。
另外,请不要忘记memcpy
将数组转换为指向第一个元素的指针,然后将它们void*
。所以它丢失了所有信息。
所以我去了
memcpy
,而是使用分配循环并尝试从那里取消约束。