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

まず、私はもっと慎重に行きます。あなたが持っている2つのケース、固定サイズの配列の間にステップがあります。最近のコンパイラは、コンパイル時定数でインデックス付けされている配列コンポーネントをトレースできると思います。

また、配列を最初の要素へのポインターにmemcpy変換してから、それらを .xml にすることも忘れないでください。したがって、すべての情報が失われます。void*

だから私は行くだろう

  • 固定サイズの配列を試す
  • memcpy割り当てループ以外は使用しないでください

そこから制約を失わせようとします。

于 2012-09-12T06:15:07.310 に答える