Change unroll metadata and unroll pragma names
Mark Heffernan
meheff at google.com
Wed Jul 23 10:41:43 PDT 2014
Addressed all of your comments. The formatting issues were due to using
clang-format.py without the "-style LLVM" option.
Committed as r213771 and r213772.
On Tue Jul 22 2014 at 12:06:58 PM, Aaron Ballman <aaron.ballman at gmail.com>
wrote:
> On Tue, Jul 22, 2014 at 2:33 PM, Mark Heffernan <meheff at google.com> wrote:
> > This patch does some renaming of the metadata and unrolling pragma terms
> to
> > hopefully remove a source of confusion. It was motivated the comments in
> > review: http://reviews.llvm.org/D4571. Prior to this patch we have the
> > following pragma syntax and the corresponding metadata it generates:
> >
> > #pragma clang loop unroll(enable) => !{metadata
> !"llvm.loop.unroll.enable",
> > i1 true}
> > #pragma clang loop unroll(disable) => !{metadata
> > !"llvm.loop.unroll.enable", i1 false}
> > #pragma clang loop unroll_count(N) => !{metadata
> !"llvm.loop.unroll.count",
> > i32 N}
> >
> > #pragma unroll => !{metadata !"llvm.loop.unroll.enable", i1 true}
> > #pragma unroll N => !{metadata !"llvm.loop.unroll.count", i32 N}
> >
> > Unroll disable and unroll count are pretty self explanatory. The issue
> is
> > with "unroll(enable)". "unroll(enable)" indicates to unroll the loop
> fully
> > which is a bit surprising. It also is not clear whether you need
> > "unroll(enable)" when you specify "unroll_count(N)". Both of these
> > potential sources of confusion are resolved with this patch which changes
> > the pragma and metadata to:
> >
> > #pragma clang loop unroll(full) => !{metadata !"llvm.loop.unroll.full"}
> > #pragma clang loop unroll(disable) => !{metadata
> > !"llvm.loop.unroll.disable"}
> > #pragma clang loop unroll_count(N) => !{metadata
> !"llvm.loop.unroll.count",
> > i32 N}
> >
> > #pragma unroll => !{metadata !"llvm.loop.unroll.full"}
> > #pragma unroll N => !{metadata !"llvm.loop.unroll.count", i32 N}
> >
> > Now it should (hopefully) be immediately clear what each of these do.
> The
> > loop unrolling transformation itself is not affected. Other than
> renaming,
> > the only functional difference is that a loop can now only have a single
> > loop unroll directive. Previously (and confusingly) a loop could have
> both
> > unroll(enable) and unroll_count(N).
>
> Some very minor comments below on the clang side of the patch. Aside
> from these nits, LGTM.
>
> > Index: docs/LanguageExtensions.rst
> > ===================================================================
> > --- docs/LanguageExtensions.rst (revision 213580)
> > +++ docs/LanguageExtensions.rst (working copy)
> > @@ -1830,7 +1830,7 @@
> > compile time. Partial unrolling replicates the loop body within the
> loop and
> > reduces the trip count.
> >
> > -If ``unroll(enable)`` is specified the unroller will attempt to fully
> unroll the
> > +If ``unroll(full)`` is specified the unroller will attempt to fully
> unroll the
> > loop if the trip count is known at compile time. If the loop count is
> not known
> > or the fully unrolled code size is greater than the limit specified by
> the
> > `-pragma-unroll-threshold` command line option the loop will be
> partially
> > @@ -1838,7 +1838,7 @@
> >
> > .. code-block:: c++
> >
> > - #pragma clang loop unroll(enable)
> > + #pragma clang loop unroll(full)
> > for(...) {
> > ...
> > }
> > Index: include/clang/Basic/Attr.td
> > ===================================================================
> > --- include/clang/Basic/Attr.td (revision 213580)
> > +++ include/clang/Basic/Attr.td (working copy)
> > @@ -1776,7 +1776,7 @@
> > /// vectorize_width: vectorize loop operations with width 'value'.
> > /// interleave: interleave multiple loop iterations if 'value != 0'.
> > /// interleave_count: interleaves 'value' loop interations.
> > - /// unroll: unroll loop if 'value != 0'.
> > + /// unroll: fully unroll loop if 'value != 0'.
> > /// unroll_count: unrolls loop 'value' times.
> >
> > let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">];
> > @@ -1830,6 +1830,10 @@
> > if (option == VectorizeWidth || option == InterleaveCount ||
> > option == UnrollCount)
> > OS << value;
> > + else if (option == Unroll && value)
> > + // Unroll loop hint does not use the keyword "enable". Instead, a
> true value
> > + // indicate full unrolling which uses the keyword "full".
>
> Typo: indicates? Also, instead of "true value", perhaps a "nonzero
> value" would read a bit easier, since these are integer arguments.
>
> > + OS << "full";
> > else if (value)
> > OS << "enable";
> > else
> > Index: include/clang/Basic/AttrDocs.td
> > ===================================================================
> > --- include/clang/Basic/AttrDocs.td (revision 213580)
> > +++ include/clang/Basic/AttrDocs.td (working copy)
> > @@ -1080,7 +1080,7 @@
> > }
> >
> > ``#pragma unroll`` and ``#pragma unroll _value_`` have identical
> semantics to
> > -``#pragma clang loop unroll(enable)`` and ``#pragma clang loop
> > +``#pragma clang loop unroll(full)`` and ``#pragma clang loop
> > unroll_count(_value_)`` respectively. See `language extensions
> > <http://clang.llvm.org/docs/LanguageExtensions.html#
> extensions-for-loop-hint-optimizations>`_
> > for further details including limitations of the unroll hints.
> > Index: include/clang/Basic/DiagnosticParseKinds.td
> > ===================================================================
> > --- include/clang/Basic/DiagnosticParseKinds.td (revision 213580)
> > +++ include/clang/Basic/DiagnosticParseKinds.td (working copy)
> > @@ -815,7 +815,7 @@
> > "expected non-wide string literal in '#pragma %0'">,
> InGroup<IgnoredPragmas>;
> > // - Generic errors
> > def err_pragma_missing_argument : Error<
> > - "missing argument to '#pragma %0'; expected %1">;
> > + "missing argument to '#pragma %0'%select{|; expected %2}1">;
> > // - #pragma options
> > def warn_pragma_options_expected_align : Warning<
> > "expected 'align' following '#pragma options' - ignored">,
> > Index: include/clang/Basic/DiagnosticSemaKinds.td
> > ===================================================================
> > --- include/clang/Basic/DiagnosticSemaKinds.td (revision 213580)
> > +++ include/clang/Basic/DiagnosticSemaKinds.td (working copy)
> > @@ -539,7 +539,7 @@
> > def err_pragma_loop_invalid_value : Error<
> > "invalid argument; expected a positive integer value">;
> > def err_pragma_loop_invalid_keyword : Error<
> > - "invalid argument; expected 'enable' or 'disable'">;
> > + "invalid argument; expected '%0' or 'disable'">;
> > def err_pragma_loop_compatibility : Error<
> > "%select{incompatible|duplicate}0 directives '%1' and '%2'">;
> > def err_pragma_loop_precedes_nonloop : Error<
> > Index: lib/CodeGen/CGStmt.cpp
> > ===================================================================
> > --- lib/CodeGen/CGStmt.cpp (revision 213580)
> > +++ lib/CodeGen/CGStmt.cpp (working copy)
> > @@ -586,55 +586,53 @@
> >
> > const char *MetadataName;
> > switch (Option) {
> > - case LoopHintAttr::Vectorize:
> > - case LoopHintAttr::VectorizeWidth:
> > - MetadataName = "llvm.loop.vectorize.width";
> > - break;
> > - case LoopHintAttr::Interleave:
> > - case LoopHintAttr::InterleaveCount:
> > - MetadataName = "llvm.loop.vectorize.unroll";
> > - break;
> > - case LoopHintAttr::Unroll:
> > - MetadataName = "llvm.loop.unroll.enable";
> > - break;
> > - case LoopHintAttr::UnrollCount:
> > - MetadataName = "llvm.loop.unroll.count";
> > - break;
> > + case LoopHintAttr::Vectorize:
> > + case LoopHintAttr::VectorizeWidth:
> > + MetadataName = "llvm.loop.vectorize.width";
> > + break;
> > + case LoopHintAttr::Interleave:
> > + case LoopHintAttr::InterleaveCount:
> > + MetadataName = "llvm.loop.vectorize.unroll";
> > + break;
> > + case LoopHintAttr::Unroll:
> > + // With the unroll loop hint, a non-zero value indicates full
> unrolling.
> > + MetadataName = ValueInt == 0 ? "llvm.loop.unroll.disable"
> > + : "llvm.loop.unroll.full";
> > + break;
> > + case LoopHintAttr::UnrollCount:
> > + MetadataName = "llvm.loop.unroll.count";
> > + break;
>
> The formatting here does not match our style guides.
>
> > }
> > -
> > llvm::Value *Value;
> > llvm::MDString *Name;
> > switch (Option) {
> > - case LoopHintAttr::Vectorize:
> > - case LoopHintAttr::Interleave:
> > - if (ValueInt == 1) {
> > - // FIXME: In the future I will modifiy the behavior of the
> metadata
> > - // so we can enable/disable vectorization and interleaving
> separately.
> > - Name = llvm::MDString::get(Context,
> "llvm.loop.vectorize.enable");
> > - Value = Builder.getTrue();
> > + case LoopHintAttr::Vectorize:
> > + case LoopHintAttr::Interleave:
> > + if (ValueInt == 1) {
> > + // FIXME: In the future I will modifiy the behavior of the
> metadata
> > + // so we can enable/disable vectorization and interleaving
> separately.
> > + Name = llvm::MDString::get(Context,
> "llvm.loop.vectorize.enable");
> > + Value = Builder.getTrue();
> > + break;
> > + }
> > + // Vectorization/interleaving is disabled, set width/count to 1.
> > + ValueInt = 1;
> > + // Fallthrough.
> > + case LoopHintAttr::VectorizeWidth:
> > + case LoopHintAttr::InterleaveCount:
> > + case LoopHintAttr::UnrollCount:
> > + Name = llvm::MDString::get(Context, MetadataName);
> > + Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
> > break;
> > - }
> > - // Vectorization/interleaving is disabled, set width/count to 1.
> > - ValueInt = 1;
> > - // Fallthrough.
> > - case LoopHintAttr::VectorizeWidth:
> > - case LoopHintAttr::InterleaveCount:
> > - Name = llvm::MDString::get(Context, MetadataName);
> > - Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
> > - break;
> > - case LoopHintAttr::Unroll:
> > - Name = llvm::MDString::get(Context, MetadataName);
> > - Value = (ValueInt == 0) ? Builder.getFalse() : Builder.getTrue();
> > - break;
> > - case LoopHintAttr::UnrollCount:
> > - Name = llvm::MDString::get(Context, MetadataName);
> > - Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
> > - break;
> > + case LoopHintAttr::Unroll:
> > + Name = llvm::MDString::get(Context, MetadataName);
> > + Value = nullptr;
> > + break;
>
> Same issue with formatting here as above.
>
> > }
> >
> > SmallVector<llvm::Value *, 2> OpValues;
> > OpValues.push_back(Name);
> > - OpValues.push_back(Value);
> > + if (Value) OpValues.push_back(Value);
>
> The controlled statement should be on its own line.
>
> >
> > // Set or overwrite metadata indicated by Name.
> > Metadata.push_back(llvm::MDNode::get(Context, OpValues));
> > Index: lib/Parse/ParsePragma.cpp
> > ===================================================================
> > --- lib/Parse/ParsePragma.cpp (revision 213580)
> > +++ lib/Parse/ParsePragma.cpp (working copy)
> > @@ -1670,8 +1670,7 @@
> > PP.Lex(Tok);
> > if (Tok.is(tok::eod)) {
> > PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
> > - << "clang optimize"
> > - << "'on' or 'off'";
> > + << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
> > return;
> > }
> > if (Tok.isNot(tok::identifier)) {
> > @@ -1718,8 +1717,12 @@
> > "Unexpected pragma name");
> > PragmaString = "unroll";
> > }
> > + // Don't try to emit what the pragma is expecting with the
> diagnostic
> > + // because the logic is non-trivial and we give expected values
> in sema
> > + // diagnostics if an invalid argument is given. Here, just note
> that the
> > + // pragma is missing an argument.
> > PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
> > - << PragmaString << "a positive integer value";
> > + << PragmaString << /*Expected=*/false;
> > return true;
> > }
> > }
> > @@ -1751,7 +1754,7 @@
> > /// loop-hint:
> > /// 'vectorize' '(' loop-hint-keyword ')'
> > /// 'interleave' '(' loop-hint-keyword ')'
> > -/// 'unroll' '(' loop-hint-keyword ')'
> > +/// 'unroll' '(' unroll-hint-keyword ')'
> > /// 'vectorize_width' '(' loop-hint-value ')'
> > /// 'interleave_count' '(' loop-hint-value ')'
> > /// 'unroll_count' '(' loop-hint-value ')'
> > @@ -1760,6 +1763,10 @@
> > /// 'enable'
> > /// 'disable'
> > ///
> > +/// unroll-hint-keyword:
> > +/// 'full'
> > +/// 'disable'
> > +///
> > /// loop-hint-value:
> > /// constant-expression
> > ///
> > @@ -1774,12 +1781,10 @@
> > /// only works on inner loops.
> > ///
> > /// The unroll and unroll_count directives control the concatenation
> > -/// unroller. Specifying unroll(enable) instructs llvm to try to
> > +/// unroller. Specifying unroll(full) instructs llvm to try to
> > /// unroll the loop completely, and unroll(disable) disables unrolling
> > /// for the loop. Specifying unroll_count(_value_) instructs llvm to
> > /// try to unroll the loop the number of times indicated by the value.
> > -/// If unroll(enable) and unroll_count are both specified only
> > -/// unroll_count takes effect.
> > void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
> > PragmaIntroducerKind
> Introducer,
> > Token &Tok) {
> > Index: lib/Sema/SemaStmtAttr.cpp
> > ===================================================================
> > --- lib/Sema/SemaStmtAttr.cpp (revision 213580)
> > +++ lib/Sema/SemaStmtAttr.cpp (working copy)
> > @@ -89,16 +89,22 @@
> > } else if (Option == LoopHintAttr::Vectorize ||
> > Option == LoopHintAttr::Interleave ||
> > Option == LoopHintAttr::Unroll) {
> > + // Unrolling uses the keyword "full" rather than "enable" to
> indicate full
> > + // unrolling.
> > + const char *TrueKeyword =
> > + Option == LoopHintAttr::Unroll ? "full" : "enable";
> > if (!ValueInfo) {
> > - S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
> > + S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
> > + << TrueKeyword;
> > return nullptr;
> > }
> > if (ValueInfo->isStr("disable"))
> > ValueInt = 0;
> > - else if (ValueInfo->isStr("enable"))
> > + else if (ValueInfo->getName() == TrueKeyword)
> > ValueInt = 1;
> > else {
> > - S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
> > + S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
> > + << TrueKeyword;
> > return nullptr;
> > }
> > } else if (Option == LoopHintAttr::VectorizeWidth ||
> > @@ -121,12 +127,14 @@
> >
> > static void CheckForIncompatibleAttributes(
> > Sema &S, const SmallVectorImpl<const Attr *> &Attrs) {
> > - // There are 3 categories of loop hints: vectorize, interleave, and
> > - // unroll. Each comes in two variants: an enable/disable form and a
> > - // form which takes a numeric argument. For example:
> > - // unroll(enable|disable) and unroll_count(N). The following array
> > - // accumulate the hints encountered while iterating through the
> > - // attributes to check for compatibility.
> > + // There are 3 categories of loop hints attributes: vectorize,
> interleave, and
> > + // unroll. Each comes in two variants: a boolean form and a numeric
> form. The
> > + // boolean hints selectively enables/disables the transformation for
> the loop
> > + // (for unroll a true value indicates full unrolling rather than
> enabling the
>
> Instead of true value, perhaps "nonzero value"? Also, missing a comma
> after "unroll."
>
> > + // transformation). The numeric hint provides an integer hint (for
> example,
> > + // unroll count) to the transformer. The following array accumulate
> the hints
>
> Pluralization mismatch (array accumulate).
>
> > + // encountered while iterating through the attributes to check for
> > + // compatibility.
> > struct {
> > const LoopHintAttr *EnableAttr;
> > const LoopHintAttr *NumericAttr;
> > @@ -141,19 +149,20 @@
> >
> > int Option = LH->getOption();
> > int Category;
> > + enum { Vectorize, Interleave, Unroll };
> > switch (Option) {
> > - case LoopHintAttr::Vectorize:
> > - case LoopHintAttr::VectorizeWidth:
> > - Category = 0;
> > - break;
> > - case LoopHintAttr::Interleave:
> > - case LoopHintAttr::InterleaveCount:
> > - Category = 1;
> > - break;
> > - case LoopHintAttr::Unroll:
> > - case LoopHintAttr::UnrollCount:
> > - Category = 2;
> > - break;
> > + case LoopHintAttr::Vectorize:
> > + case LoopHintAttr::VectorizeWidth:
> > + Category = Vectorize;
> > + break;
> > + case LoopHintAttr::Interleave:
> > + case LoopHintAttr::InterleaveCount:
> > + Category = Interleave;
> > + break;
> > + case LoopHintAttr::Unroll:
> > + case LoopHintAttr::UnrollCount:
> > + Category = Unroll;
> > + break;
>
> Formatting.
>
> > };
> >
> > auto &CategoryState = HintAttrs[Category];
> > @@ -176,10 +185,11 @@
> > << /*Duplicate=*/true << PrevAttr->getDiagnosticName()
> > << LH->getDiagnosticName();
> >
> > - if (CategoryState.EnableAttr && !CategoryState.EnableAttr->getValue()
> &&
> > - CategoryState.NumericAttr) {
> > - // Disable hints are not compatible with numeric hints of the
> > - // same category.
> > + if (CategoryState.EnableAttr && CategoryState.NumericAttr &&
> > + (Category == Unroll || !CategoryState.EnableAttr->getValue()))
> {
> > + // Disable hints are not compatible with numeric hints of the same
> > + // category. As a special case, numeric unroll hints are also not
> > + // compatible with "enable" form of the unroll pragma,
> unroll(full).
> > S.Diag(OptionLoc, diag::err_pragma_loop_compatibility)
> > << /*Duplicate=*/false
> > << CategoryState.EnableAttr->getDiagnosticName()
> > Index: test/CodeGen/pragma-loop.cpp
> > ===================================================================
> > --- test/CodeGen/pragma-loop.cpp (revision 213580)
> > +++ test/CodeGen/pragma-loop.cpp (working copy)
> > @@ -8,7 +8,7 @@
> > #pragma clang loop vectorize(enable)
> > #pragma clang loop interleave_count(4)
> > #pragma clang loop vectorize_width(4)
> > -#pragma clang loop unroll(enable)
> > +#pragma clang loop unroll(full)
> > while (i < Length) {
> > // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
> ![[LOOP_1:.*]]
> > List[i] = i * 2;
> > @@ -108,13 +108,13 @@
> > for_template_define_test<double>(List, Length, Value);
> > }
> >
> > -// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata
> ![[UNROLLENABLE_1:.*]], metadata ![[WIDTH_4:.*]], metadata
> ![[INTERLEAVE_4:.*]], metadata ![[INTENABLE_1:.*]]}
> > -// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata
> !"llvm.loop.unroll.enable", i1 true}
> > +// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata
> ![[UNROLL_FULL:.*]], metadata ![[WIDTH_4:.*]], metadata
> ![[INTERLEAVE_4:.*]], metadata ![[INTENABLE_1:.*]]}
> > +// CHECK: ![[UNROLL_FULL]] = metadata !{metadata
> !"llvm.loop.unroll.full"}
> > // CHECK: ![[WIDTH_4]] = metadata !{metadata
> !"llvm.loop.vectorize.width", i32 4}
> > // CHECK: ![[INTERLEAVE_4]] = metadata !{metadata
> !"llvm.loop.vectorize.unroll", i32 4}
> > // CHECK: ![[INTENABLE_1]] = metadata !{metadata
> !"llvm.loop.vectorize.enable", i1 true}
> > -// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata
> ![[UNROLLENABLE_0:.*]], metadata ![[INTERLEAVE_4:.*]], metadata
> ![[WIDTH_8:.*]]}
> > -// CHECK: ![[UNROLLENABLE_0]] = metadata !{metadata
> !"llvm.loop.unroll.enable", i1 false}
> > +// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata
> ![[UNROLL_DISABLE:.*]], metadata ![[INTERLEAVE_4:.*]], metadata
> ![[WIDTH_8:.*]]}
> > +// CHECK: ![[UNROLL_DISABLE]] = metadata !{metadata
> !"llvm.loop.unroll.disable"}
> > // CHECK: ![[WIDTH_8]] = metadata !{metadata
> !"llvm.loop.vectorize.width", i32 8}
> > // CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata
> ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[ENABLE_1:.*]]}
> > // CHECK: ![[UNROLL_8]] = metadata !{metadata
> !"llvm.loop.unroll.count", i32 8}
> > @@ -121,7 +121,7 @@
> > // CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata
> ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
> > // CHECK: ![[INTERLEAVE_2]] = metadata !{metadata
> !"llvm.loop.vectorize.unroll", i32 2}
> > // CHECK: ![[WIDTH_2]] = metadata !{metadata
> !"llvm.loop.vectorize.width", i32 2}
> > -// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata
> ![[UNROLLENABLE_0:.*]], metadata ![[WIDTH_1:.*]]}
> > +// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata
> ![[UNROLL_DISABLE:.*]], metadata ![[WIDTH_1:.*]]}
> > // CHECK: ![[WIDTH_1]] = metadata !{metadata
> !"llvm.loop.vectorize.width", i32 1}
> > // CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata
> ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
> > // CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata
> ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_8:.*]], metadata ![[WIDTH_8:.*]]}
> > Index: test/CodeGen/pragma-unroll.cpp
> > ===================================================================
> > --- test/CodeGen/pragma-unroll.cpp (revision 213580)
> > +++ test/CodeGen/pragma-unroll.cpp (working copy)
> > @@ -86,8 +86,8 @@
> > for_template_define_test<double>(List, Length, Value);
> > }
> >
> > -// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata
> ![[UNROLLENABLE_1:.*]]}
> > -// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata
> !"llvm.loop.unroll.enable", i1 true}
> > +// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata
> ![[UNROLL_FULL:.*]]}
> > +// CHECK: ![[UNROLL_FULL]] = metadata !{metadata
> !"llvm.loop.unroll.full"}
> > // CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata
> ![[UNROLL_16:.*]]}
> > // CHECK: ![[UNROLL_16]] = metadata !{metadata
> !"llvm.loop.unroll.count", i32 16}
> > // CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata
> ![[UNROLL_8:.*]]}
> > Index: test/PCH/pragma-loop.cpp
> > ===================================================================
> > --- test/PCH/pragma-loop.cpp (revision 213580)
> > +++ test/PCH/pragma-loop.cpp (working copy)
> > @@ -10,7 +10,7 @@
> > // CHECK: #pragma clang loop unroll(disable)
> > // CHECK: #pragma clang loop interleave(disable)
> > // CHECK: #pragma clang loop vectorize(enable)
> > -// CHECK: #pragma clang loop unroll(enable)
> > +// CHECK: #pragma clang loop unroll(full)
> > // CHECK: #pragma clang loop interleave(enable)
> > // CHECK: #pragma clang loop vectorize(disable)
> > // CHECK: #pragma unroll
> > @@ -47,7 +47,7 @@
> > int i = 0;
> > #pragma clang loop vectorize(disable)
> > #pragma clang loop interleave(enable)
> > -#pragma clang loop unroll(enable)
> > +#pragma clang loop unroll(full)
> > while (i - 3 < Length) {
> > List[i] = i;
> > i++;
> > Index: test/Parser/pragma-loop.cpp
> > ===================================================================
> > --- test/Parser/pragma-loop.cpp (revision 213580)
> > +++ test/Parser/pragma-loop.cpp (working copy)
> > @@ -8,7 +8,7 @@
> >
> > #pragma clang loop vectorize(enable)
> > #pragma clang loop interleave(enable)
> > -#pragma clang loop unroll(enable)
> > +#pragma clang loop unroll(full)
> > while (i + 1 < Length) {
> > List[i] = i;
> > }
> > @@ -49,15 +49,15 @@
> >
> > /* expected-error {{expected ')'}} */ #pragma clang loop
> vectorize(enable
> > /* expected-error {{expected ')'}} */ #pragma clang loop
> interleave(enable
> > -/* expected-error {{expected ')'}} */ #pragma clang loop unroll(enable
> > +/* expected-error {{expected ')'}} */ #pragma clang loop unroll(full
> >
> > /* expected-error {{expected ')'}} */ #pragma clang loop
> vectorize_width(4
> > /* expected-error {{expected ')'}} */ #pragma clang loop
> interleave_count(4
> > /* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4
> >
> > -/* expected-error {{missing argument to '#pragma clang loop vectorize';
> expected a positive integer value}} */ #pragma clang loop vectorize()
> > -/* expected-error {{missing argument to '#pragma clang loop
> interleave_count'; expected a positive integer value}} */ #pragma clang
> loop interleave_count()
> > -/* expected-error {{missing argument to '#pragma clang loop unroll';
> expected a positive integer value}} */ #pragma clang loop unroll()
> > +/* expected-error {{missing argument to '#pragma clang loop
> vectorize'}} */ #pragma clang loop vectorize()
> > +/* expected-error {{missing argument to '#pragma clang loop
> interleave_count'}} */ #pragma clang loop interleave_count()
> > +/* expected-error {{missing argument to '#pragma clang loop unroll'}}
> */ #pragma clang loop unroll()
> >
> > /* expected-error {{missing option}} */ #pragma clang loop
> > /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop
> badkeyword
> > @@ -92,7 +92,7 @@
> >
> > /* expected-error {{invalid argument; expected 'enable' or 'disable'}}
> */ #pragma clang loop vectorize(badidentifier)
> > /* expected-error {{invalid argument; expected 'enable' or 'disable'}}
> */ #pragma clang loop interleave(badidentifier)
> > -/* expected-error {{invalid argument; expected 'enable' or 'disable'}}
> */ #pragma clang loop unroll(badidentifier)
> > +/* expected-error {{invalid argument; expected 'full' or 'disable'}} */
> #pragma clang loop unroll(badidentifier)
> > while (i-7 < Length) {
> > List[i] = i;
> > }
> > @@ -101,7 +101,7 @@
> > // constants crash FE.
> > /* expected-error {{invalid argument; expected 'enable' or 'disable'}}
> */ #pragma clang loop vectorize(()
> > /* expected-error {{invalid argument; expected 'enable' or 'disable'}}
> */ #pragma clang loop interleave(*)
> > -/* expected-error {{invalid argument; expected 'enable' or 'disable'}}
> */ #pragma clang loop unroll(=)
> > +/* expected-error {{invalid argument; expected 'full' or 'disable'}} */
> #pragma clang loop unroll(=)
> > /* expected-error {{invalid argument; expected a positive integer
> value}} */ #pragma clang loop vectorize_width(^)
> > /* expected-error {{invalid argument; expected a positive integer
> value}} */ #pragma clang loop interleave_count(/)
> > /* expected-error {{invalid argument; expected a positive integer
> value}} */ #pragma clang loop unroll_count(==)
> > @@ -136,7 +136,7 @@
> > #pragma clang loop vectorize(disable)
> > /* expected-error {{duplicate directives 'interleave(disable)' and
> 'interleave(enable)'}} */ #pragma clang loop interleave(enable)
> > #pragma clang loop interleave(disable)
> > -/* expected-error {{duplicate directives 'unroll(disable)' and
> 'unroll(enable)'}} */ #pragma clang loop unroll(enable)
> > +/* expected-error {{duplicate directives 'unroll(disable)' and
> 'unroll(full)'}} */ #pragma clang loop unroll(full)
> > #pragma clang loop unroll(disable)
> > while (i-9 < Length) {
> > List[i] = i;
> > @@ -162,5 +162,12 @@
> > List[i] = i;
> > }
> >
> > +
> > +/* expected-error {{incompatible directives 'unroll(full)' and
> 'unroll_count(4)'}} */ #pragma clang loop unroll(full)
> > +#pragma clang loop unroll_count(4)
> > + while (i-11 < Length) {
> > + List[i] = i;
> > + }
> > +
> > #pragma clang loop interleave(enable)
> > /* expected-error {{expected statement}} */ }
> > Index: test/Parser/pragma-unroll.cpp
> > ===================================================================
> > --- test/Parser/pragma-unroll.cpp (revision 213580)
> > +++ test/Parser/pragma-unroll.cpp (working copy)
> > @@ -21,26 +21,8 @@
> > List[i] = i;
> > }
> >
> > -#pragma unroll
> > -#pragma unroll(8)
> > - while (i - 3 < Length) {
> > - List[i] = i;
> > - }
> > -
> > -#pragma clang loop unroll(enable)
> > -#pragma unroll(8)
> > - while (i - 4 < Length) {
> > - List[i] = i;
> > - }
> > -
> > -#pragma unroll
> > -#pragma clang loop unroll_count(4)
> > - while (i - 5 < Length) {
> > - List[i] = i;
> > - }
> > -
> > /* expected-error {{expected ')'}} */ #pragma unroll(4
> > -/* expected-error {{missing argument to '#pragma unroll'; expected a
> positive integer value}} */ #pragma unroll()
> > +/* expected-error {{missing argument to '#pragma unroll'}} */ #pragma
> unroll()
> > /* expected-warning {{extra tokens at end of '#pragma unroll'}} */
> #pragma unroll 1 2
> > while (i-6 < Length) {
> > List[i] = i;
> > @@ -67,6 +49,18 @@
> > List[i] = i;
> > }
> >
> > +/* expected-error {{incompatible directives 'unroll(full)' and '#pragma
> unroll(4)'}} */ #pragma unroll(4)
> > +#pragma clang loop unroll(full)
> > + while (i-11 < Length) {
> > + List[i] = i;
> > + }
> > +
> > +/* expected-error {{incompatible directives '#pragma unroll' and
> '#pragma unroll(4)'}} */ #pragma unroll(4)
> > +#pragma unroll
> > + while (i-11 < Length) {
> > + List[i] = i;
> > + }
> > +
> > /* expected-error {{duplicate directives '#pragma unroll' and '#pragma
> unroll'}} */ #pragma unroll
> > #pragma unroll
> > while (i-14 < Length) {
> > @@ -73,8 +67,8 @@
> > List[i] = i;
> > }
> >
> > -/* expected-error {{duplicate directives 'unroll(enable)' and '#pragma
> unroll'}} */ #pragma unroll
> > -#pragma clang loop unroll(enable)
> > +/* expected-error {{duplicate directives 'unroll(full)' and '#pragma
> unroll'}} */ #pragma unroll
> > +#pragma clang loop unroll(full)
> > while (i-15 < Length) {
> > List[i] = i;
> > }
> >
>
> ~Aaron
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140723/8ce5cc4a/attachment.html>
More information about the cfe-commits
mailing list