2016-09-19 15 views
0

エイリアス解析は、__restrict__noaliasのようなキーワードでどのように動作しますか? エイリアシングがないと証明していますか? または、ポインタに応じて独自の結果を計算するだけですか?まだエイリアス解析、 入力と出力ポインタが__restrictで十分にマークされていたにもかかわらず:、負荷-binopストアシーケンスをやって多くのタイトなループで、以下のボトルネックが見られたLLVMのエイリアス解析の結果を見るとエイリアス解析と_restrictキーワード - C

'MayAlias'とみなし、ループの最後のストアをループ内のすべてのロードに依存させました。

void _BitwiseOr_(unsigned char * __restrict * __restrict src1Addr, unsigned char * __restrict * __restrict src2Addr, unsigned char * __restrict * __restrict destAddr, unsigned int width) { 
     uchar16 * __restrict src1 = (uchar16 * __restrict) *src1Addr; 
     uchar16 * __restrict src2 = (uchar16 * __restrict) *src2Addr; 
     uchar16 * __restrict dest = (uchar16 * __restrict) *destAddr; 


     for (unsigned int i = 0; i < width; i += 4) { 
     *dest++ = *src1++ | *src2++; 
     *dest++ = *src1++ | *src2++; 
     *dest++ = *src1++ | *src2++; 
     *dest++ = *src1++ | *src2++; 
     } 
    } 

define void @_BitwiseOr_(i8** noalias nocapture readonly %src1Addr, i8** noalias nocapture readonly %src2Addr, i8** noalias nocapture readonly %destAddr, i32 %width) local_unnamed_addr #0 { 
entry: 
    %0 = bitcast i8** %src1Addr to <16 x i8>** 
    %1 = load <16 x i8>*, <16 x i8>** %0, align 4, !tbaa !2 
    %2 = bitcast i8** %src2Addr to <16 x i8>** 
    %3 = load <16 x i8>*, <16 x i8>** %2, align 4, !tbaa !2  
    %4 = bitcast i8** %destAddr to <16 x i8>** 
    %5 = load <16 x i8>*, <16 x i8>** %4, align 4, !tbaa !2   
    %6 = load <16 x i8>, <16 x i8>* %1, align 8, !tbaa !6 
    %7 = load <16 x i8>, <16 x i8>* %3, align 8, !tbaa !6 
    %or = or <16 x i8> %7, %6 
    store <16 x i8> %or, <16 x i8>* %5, align 8, !tbaa !6 
    ret void 
} 

エイリアス解析の回答のみに別名の間されていないこと:

i8** src1addr - i8** src2addr, 
i8** src1addr - i8** destaddr, 
i8** src2addr - i8** destaddr, 
i8** destaddr - i8** destaddr, 
i8** src1addr - i8** src1addr, 
i8** src2addr - i8** src2addr 

なぜそれ__restrictキーワードの使用ではない「利益」のか? それを動作させることは可能ですか?

上記

はと打ち鳴らすによってコンパイルされています

-cc1 -S -disable-free -main-file-name file.cpp -mllvm -disable-block-placement -funroll-loops -mllvm -unroll-allow-partial -mllvm -tail-merge-size=71 -mllvm -tail-dup-size=70 -fmath-errno -v -gcodeview -dwarf-column-info -coverage-file file.s -O3 -Wall -Werror=implicit-function-declaration -std=c++14 -fdeprecated-macro -fno-dwarf-directory-asm -ferror-limit 19 -fmessage-length 0 -ffreestanding -fallow-half-arguments-and-returns -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -mllvm -no-phi-elim-live-out-early-exit -mllvm -use-cfl-aa=anders -mllvm -use-cfl-aa-in-codegen=anders -mllvm -debug -mllvm -da-delinearize -mllvm -mllvm -enable-tbaa -mllvm -enable-scoped-noalias -mllvm -evaluate-aa-metadata -mllvm -print-all-alias-modref-info 
+0

その他の「エイリアスはありません」とお考えですか?入力したリストはすべての入力をカバーしているようですか? – Joky

+0

また、%1 - %3、%3 - %5ともいうべきです。src1 - src2 etc(更新されたソースコードを確認してください) – eternalStudent

答えて

1

あなたはC標準でルールを読む必要があります。

"制限"ポインタはもちろんエイリアスです。これは、場合によっては未定義の動作を生成するので、エイリアスになりますが、コンパイラはこれを完全に無視することができます。

「制限」は、「制限」ポインタから派生したポインタと、同じ「制限」ポインタから派生しないことが保証されているポインタにのみ影響を与えることにも注意する必要があります。たとえば、pが "restrict"ポインタでf(p)を呼び出すと、その呼び出しはpを任意の静的またはグローバルポインタ変数に格納できます。だから、呼び出しの後にそのようなポインタ変数を読み込んだ場合、コンパイラはrestrictポインタから派生したものかどうかを知らず、pから派生している場合はエイリアス規則が適用されます。

+0

しかし、C標準によると、エイリアシングが可能で、不可能な場合には直接指定しません。しかし、 には、1つのタイプのオブジェクトには、1つの関連タイプのうちの1つが である参照によってのみアクセスされるという値が格納されていることが記載されています。 と一致しないタイプのアクセスのペアが明示的にエイリアスできません。エイリアスの観点からこれらのルールを再記述すると、修飾子(const、volatile、およびrestrict)が の場合に互換性のある型が無視されます。だから私のここでの質問は... – eternalStudent