2

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

4

1 回答 1

1

首先,我会更加小心。在您拥有的两种情况之间有一个步骤,即固定大小的数组。我认为现在编译器可以跟踪也用编译时间常数索引的数组组件。

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

所以我会去

  • 尝试固定大小的数组
  • 不要使用memcpy赋值循环

并尝试从那里失去约束。

于 2012-09-12T06:15:07.310 回答