Implementing pragmas to control vectorization is important to work around deficiencies in the compiler, language or to create specific tests without confusing boilerplate or specific target defined. These pragmas are also great for probing what the compiler is able to do, and to pick and chose widths and unroll factors that the compiler gets the cost wrong. Hopefully, users will use them to report improvements to the compiler. The simplest vectorization pragmas to implement: #pragma vectorize enable/disable Simply turns the vectorizer on/off on that loop. This doesn't guarantee that the loop will get vectorized if it's not legal, but it will enable the vectorizer even if the optimization level is too low or if the cost model thinks it's a bad idea. #pragma vectorize width(4) for (i = 0; i < N; ++i) { A[i] = B[i]; } => for (i = 0; i < N; i +=4) { A[i:i+3] = B[i:i+3]; } #pragma vectorize unroll(2) for (i = 0; i < N; ++i) { A[i] = B[i]; } => for (i = 0; i < N; i +=2) { A[i] = B[i]; A[i+1] = B[i+1]; } Ultimately, the pragmas need to trigger warnings to the user, explaining why, if some of the instructions could not be followed, for instance if: - The target doesn't support the specified width - The loop cannot be vectorized because of memory dependencies
Metadata implementation: br i1 %exitcond, label %._crit_edge, label %.lr.ph, !llvm.loop !0 !0 = metadata !{ metadata !0, metadata !1, metadata !2 } !1 = metadata !{ metadata !"llvm.vectorizer.unroll", i32 2 } !2 = metadata !{ metadata !"llvm.vectorizer.width", i32 4 } To ignore a loop, simply add: !0 = metadata !{ metadata !0, metadata !1, metadata !2 } !1 = metadata !{ metadata !"llvm.vectorizer.unroll", i32 1 } !2 = metadata !{ metadata !"llvm.vectorizer.width", i32 1 } But to enable a loop on low-opt levels, we need something like this: !0 = metadata !{ metadata !0, metadata !1 } !1 = metadata !{ metadata !"llvm.vectorizer.enable", i1 true } So, we could also disable loops by using: !0 = metadata !{ metadata !0, metadata !1 } !1 = metadata !{ metadata !"llvm.vectorizer.enable", i1 false }
First part of #pragma llvm.vectorizer.enable implemented at: http://llvm-reviews.chandlerc.com/D2289 The second side-effect of this pragma, turn on vectorizer on that loop only, if the vectorizer is not enabled (ex. -O1, -O0, -Oz), is not implemented by this patch. The front-end part (in Clang) is also not implemented and to come on a separate patch, once the two side effects of this pragma are implemented. Arnold, I still can't add you as a reviewer, please check your username on phabricator. cheers, --renato
New round of discussions of the enable flag: http://llvm-reviews.chandlerc.com/D2328
#pragma vectorize enable's metadata got in on r196537, now we need to add the parsing to Clang to produce the three metadata.
Created attachment 11730 [details] parser detecting the pragmas Implemented the parser detecting the pragmas, now I need to mark the next lexical block with the vectorizer metadata.
Created attachment 11757 [details] updated parser detecting #pragma vectorize The new version adds the context to the CompoundStmt object (this is probably wrong) so that when we're lowering it, we can add the metadata. Haven't got to the lowering stage yet. I will be on holidays for two weeks, if anyone wants to continue, feel free. Otherwise, I'll pick it up when I come back.