如何让Clang优化无用的阵列副本

时间:2012-09-12 05:30:20

标签: c arrays llvm clang

考虑以下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这样的代码中。

1 个答案:

答案 0 :(得分:1)

首先,我会更加谨慎。在你拥有的两个案例之间有一个步骤,固定大小的数组。我认为现在编译器可以跟踪也用编译时常量索引的数组组件。

另外,请不要忘记memcpy数组转换为指向第一个元素的指针,然后将它们void*。所以它丢失了所有信息。

所以我去了

  • 尝试固定大小的数组
  • 不要使用memcpy,而是使用分配循环

并尝试从那里取消约束。