r210667 - Add loop unroll pragma support

Eli Bendersky eliben at google.com
Thu Jun 12 08:57:33 PDT 2014


On Thu, Jun 12, 2014 at 8:35 AM, Eli Bendersky <eliben at google.com> wrote:

> Looking into it...
>
>
> On Wed, Jun 11, 2014 at 8:40 PM, Craig Topper <craig.topper at gmail.com>
> wrote:
>
>> I seem to be getting this build failure after this commit with -Werror
>> enabled
>>
>> lib/Sema/SemaStmtAttr.cpp:132:59: error: missing field 'EnabledIsSet'
>> initializer [-Werror,-Wmissing-field-initializers]
>>
>>     {LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth},
>>
>>                                                           ^
>>
>> lib/Sema/SemaStmtAttr.cpp:133:61: error: missing field 'EnabledIsSet'
>> initializer [-Werror,-Wmissing-field-initializers]
>>
>>     {LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount},
>>
>>                                                             ^
>>
>> lib/Sema/SemaStmtAttr.cpp:134:53: error: missing field 'EnabledIsSet'
>> initializer [-Werror,-Wmissing-field-initializers]
>>
>>     {LoopHintAttr::Unroll, LoopHintAttr::UnrollCount}
>>
> Fixed in r210791.

Out of curiosity - our standard makefiles/ninja don't seem to turn this
warning on (-Wmissing-field-initializers); is this a build you configure
specially?
Also, how do you manage to build all of clang with -Werror? I always get a
bunch of warnings with gcc 4.8.2, e.g. -Wstrict-aliasing on APValue.h

Eli


























>
>>>
>>> Modified: cfe/trunk/include/clang/Basic/Attr.td
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Basic/Attr.td (original)
>>> +++ cfe/trunk/include/clang/Basic/Attr.td Wed Jun 11 12:56:26 2014
>>> @@ -1766,6 +1766,8 @@ def LoopHint : Attr {
>>>    /// 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_count: unrolls loop 'value' times.
>>>
>>>    /// FIXME: Add Pragma spelling to tablegen and
>>>    /// use it here.
>>> @@ -1773,8 +1775,10 @@ def LoopHint : Attr {
>>>
>>>    /// State of the loop optimization specified by the spelling.
>>>    let Args = [EnumArgument<"Option", "OptionType",
>>> -                          ["vectorize", "vectorize_width",
>>> "interleave", "interleave_count"],
>>> -                          ["Vectorize", "VectorizeWidth", "Interleave",
>>> "InterleaveCount"]>,
>>> +                          ["vectorize", "vectorize_width",
>>> "interleave", "interleave_count",
>>> +                           "unroll", "unroll_count"],
>>> +                          ["Vectorize", "VectorizeWidth", "Interleave",
>>> "InterleaveCount",
>>> +                           "Unroll", "UnrollCount"]>,
>>>                DefaultIntArgument<"Value", 1>];
>>>
>>>    let AdditionalMembers = [{
>>> @@ -1784,6 +1788,8 @@ def LoopHint : Attr {
>>>      case VectorizeWidth: return "vectorize_width";
>>>      case Interleave: return "interleave";
>>>      case InterleaveCount: return "interleave_count";
>>> +    case Unroll: return "unroll";
>>> +    case UnrollCount: return "unroll_count";
>>>      }
>>>      llvm_unreachable("Unhandled LoopHint option.");
>>>    }
>>> @@ -1797,7 +1803,8 @@ def LoopHint : Attr {
>>>    // FIXME: Modify pretty printer to print this pragma.
>>>    void print(raw_ostream &OS, const PrintingPolicy &Policy) const {
>>>      OS << "#pragma clang loop " << getOptionName(option) << "(";
>>> -    if (option == VectorizeWidth || option == InterleaveCount)
>>> +    if (option == VectorizeWidth || option == InterleaveCount ||
>>> +        option == UnrollCount)
>>>        OS << value;
>>>      else
>>>        OS << getValueName(value);
>>>
>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
>>> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Jun 11
>>> 12:56:26 2014
>>> @@ -895,7 +895,8 @@ def err_omp_more_one_clause : Error<
>>>
>>>  // Pragma loop support.
>>>  def err_pragma_loop_invalid_option : Error<
>>> -  "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize,
>>> vectorize_width, interleave, or interleave_count">;
>>> +  "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
>>> +  "vectorize_width, interleave, interleave_count, unroll, or
>>> unroll_count">;
>>>  } // end of Parse Issue category.
>>>
>>>  let CategoryName = "Modules Issue" in {
>>>
>>> Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
>>> +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Jun 11 12:56:26 2014
>>> @@ -550,6 +550,12 @@ void CodeGenFunction::EmitCondBrHints(ll
>>>      case LoopHintAttr::InterleaveCount:
>>>        MetadataName = "llvm.vectorizer.unroll";
>>>        break;
>>> +    case LoopHintAttr::Unroll:
>>> +      MetadataName = "llvm.loopunroll.enable";
>>> +      break;
>>> +    case LoopHintAttr::UnrollCount:
>>> +      MetadataName = "llvm.loopunroll.count";
>>> +      break;
>>>      }
>>>
>>>      llvm::Value *Value;
>>> @@ -572,6 +578,14 @@ void CodeGenFunction::EmitCondBrHints(ll
>>>        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;
>>>      }
>>>
>>>      SmallVector<llvm::Value *, 2> OpValues;
>>>
>>> Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
>>> +++ cfe/trunk/lib/Parse/ParsePragma.cpp Wed Jun 11 12:56:26 2014
>>> @@ -1641,8 +1641,10 @@ void PragmaOptimizeHandler::HandlePragma
>>>  ///  loop-hint:
>>>  ///    'vectorize' '(' loop-hint-keyword ')'
>>>  ///    'interleave' '(' loop-hint-keyword ')'
>>> +///    'unroll' '(' loop-hint-keyword ')'
>>>  ///    'vectorize_width' '(' loop-hint-value ')'
>>>  ///    'interleave_count' '(' loop-hint-value ')'
>>> +///    'unroll_count' '(' loop-hint-value ')'
>>>  ///
>>>  ///  loop-hint-keyword:
>>>  ///    'enable'
>>> @@ -1661,6 +1663,13 @@ void PragmaOptimizeHandler::HandlePragma
>>>  /// possible and profitable, and 0 is invalid. The loop vectorizer
>>> currently
>>>  /// only works on inner loops.
>>>  ///
>>> +/// The unroll and unroll_count directives control the concatenation
>>> +/// unroller. Specifying unroll(enable) 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) {
>>> @@ -1679,9 +1688,15 @@ void PragmaLoopHintHandler::HandlePragma
>>>      Token Option = Tok;
>>>      IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
>>>
>>> -    if (!OptionInfo->isStr("vectorize") &&
>>> !OptionInfo->isStr("interleave") &&
>>> -        !OptionInfo->isStr("vectorize_width") &&
>>> -        !OptionInfo->isStr("interleave_count")) {
>>> +    bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
>>> +        .Case("vectorize", true)
>>> +        .Case("interleave", true)
>>> +        .Case("unroll", true)
>>> +        .Case("vectorize_width", true)
>>> +        .Case("interleave_count", true)
>>> +        .Case("unroll_count", true)
>>> +        .Default(false);
>>> +    if (!OptionValid) {
>>>        PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
>>>            << /*MissingOption=*/false << OptionInfo;
>>>        return;
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Wed Jun 11 12:56:26 2014
>>> @@ -67,10 +67,13 @@ static Attr *handleLoopHintAttr(Sema &S,
>>>            .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
>>>            .Case("interleave", LoopHintAttr::Interleave)
>>>            .Case("interleave_count", LoopHintAttr::InterleaveCount)
>>> +          .Case("unroll", LoopHintAttr::Unroll)
>>> +          .Case("unroll_count", LoopHintAttr::UnrollCount)
>>>            .Default(LoopHintAttr::Vectorize);
>>>
>>>    int ValueInt;
>>> -  if (Option == LoopHintAttr::Vectorize || Option ==
>>> LoopHintAttr::Interleave) {
>>> +  if (Option == LoopHintAttr::Vectorize || Option ==
>>> LoopHintAttr::Interleave ||
>>> +      Option == LoopHintAttr::Unroll) {
>>>      if (!ValueInfo) {
>>>        S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
>>>            << /*MissingKeyword=*/true << "";
>>> @@ -87,7 +90,8 @@ static Attr *handleLoopHintAttr(Sema &S,
>>>        return nullptr;
>>>      }
>>>    } else if (Option == LoopHintAttr::VectorizeWidth ||
>>> -             Option == LoopHintAttr::InterleaveCount) {
>>> +             Option == LoopHintAttr::InterleaveCount ||
>>> +             Option == LoopHintAttr::UnrollCount) {
>>>      // FIXME: We should support template parameters for the loop hint
>>> value.
>>>      // See bug report #19610.
>>>      llvm::APSInt ValueAPS;
>>> @@ -111,9 +115,24 @@ static Attr *handleLoopHintAttr(Sema &S,
>>>
>>>  static void
>>>  CheckForIncompatibleAttributes(Sema &S, SmallVectorImpl<const Attr *>
>>> &Attrs) {
>>> -  int PrevOptionValue[4] = {-1, -1, -1, -1};
>>> -  int OptionId[4] = {LoopHintAttr::Vectorize,
>>> LoopHintAttr::VectorizeWidth,
>>> -                     LoopHintAttr::Interleave,
>>> LoopHintAttr::InterleaveCount};
>>> +  // 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.
>>> +  struct {
>>> +    int EnableOptionId;
>>> +    int NumericOptionId;
>>> +    bool EnabledIsSet;
>>> +    bool ValueIsSet;
>>> +    bool Enabled;
>>> +    int Value;
>>> +  } Options[] = {
>>> +    {LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth},
>>> +    {LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount},
>>> +    {LoopHintAttr::Unroll, LoopHintAttr::UnrollCount}
>>> +  };
>>>
>>>    for (const auto *I : Attrs) {
>>>      const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
>>> @@ -122,76 +141,64 @@ CheckForIncompatibleAttributes(Sema &S,
>>>      if (!LH)
>>>        continue;
>>>
>>> -    int State, Value;
>>>      int Option = LH->getOption();
>>>      int ValueInt = LH->getValue();
>>>
>>> +    int Category;
>>>      switch (Option) {
>>>      case LoopHintAttr::Vectorize:
>>>      case LoopHintAttr::VectorizeWidth:
>>> -      State = 0;
>>> -      Value = 1;
>>> +      Category = 0;
>>>        break;
>>>      case LoopHintAttr::Interleave:
>>>      case LoopHintAttr::InterleaveCount:
>>> -      State = 2;
>>> -      Value = 3;
>>> +      Category = 1;
>>>        break;
>>> -    }
>>> +    case LoopHintAttr::Unroll:
>>> +    case LoopHintAttr::UnrollCount:
>>> +      Category = 2;
>>> +      break;
>>> +    };
>>>
>>> +    auto &CategoryState = Options[Category];
>>>      SourceLocation ValueLoc = LH->getRange().getEnd();
>>> -
>>> -    // Compatibility testing is split into two cases.
>>> -    // 1. if the current loop hint sets state (enable/disable) - check
>>> against
>>> -    // previous state and value.
>>> -    // 2. if the current loop hint sets a value - check against
>>> previous state
>>> -    // and value.
>>> -
>>> -    if (Option == State) {
>>> -      if (PrevOptionValue[State] != -1) {
>>> -        // Cannot specify state twice.
>>> -        int PrevValue = PrevOptionValue[State];
>>> +    if (Option == LoopHintAttr::Vectorize ||
>>> +        Option == LoopHintAttr::Interleave || Option ==
>>> LoopHintAttr::Unroll) {
>>> +      // Enable|disable hint.  For example, vectorize(enable).
>>> +      if (CategoryState.EnabledIsSet) {
>>> +        // Cannot specify enable/disable state twice.
>>>          S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
>>>              << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
>>> -            << LoopHintAttr::getValueName(PrevValue)
>>> +            << LoopHintAttr::getValueName(CategoryState.Enabled)
>>>              << LoopHintAttr::getOptionName(Option)
>>> -            << LoopHintAttr::getValueName(Value);
>>> -      }
>>> -
>>> -      if (PrevOptionValue[Value] != -1) {
>>> -        // Compare state with previous width/count.
>>> -        int PrevOption = OptionId[Value];
>>> -        int PrevValueInt = PrevOptionValue[Value];
>>> -        if ((ValueInt == 0 && PrevValueInt > 1) ||
>>> -            (ValueInt == 1 && PrevValueInt <= 1))
>>> -          S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
>>> -              << /*Duplicate=*/false <<
>>> LoopHintAttr::getOptionName(PrevOption)
>>> -              << PrevValueInt << LoopHintAttr::getOptionName(Option)
>>> -              << LoopHintAttr::getValueName(ValueInt);
>>> +            << LoopHintAttr::getValueName(ValueInt);
>>>        }
>>> +      CategoryState.EnabledIsSet = true;
>>> +      CategoryState.Enabled = ValueInt;
>>>      } else {
>>> -      if (PrevOptionValue[State] != -1) {
>>> -        // Compare width/count value with previous state.
>>> -        int PrevOption = OptionId[State];
>>> -        int PrevValueInt = PrevOptionValue[State];
>>> -        if ((ValueInt > 1 && PrevValueInt == 0) ||
>>> -            (ValueInt <= 1 && PrevValueInt == 1))
>>> -          S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
>>> -              << /*Duplicate=*/false <<
>>> LoopHintAttr::getOptionName(PrevOption)
>>> -              << LoopHintAttr::getValueName(PrevValueInt)
>>> -              << LoopHintAttr::getOptionName(Option) << ValueInt;
>>> -      }
>>> -
>>> -      if (PrevOptionValue[Value] != -1) {
>>> -        // Cannot specify a width/count twice.
>>> -        int PrevValueInt = PrevOptionValue[Value];
>>> +      // Numeric hint.  For example, unroll_count(8).
>>> +      if (CategoryState.ValueIsSet) {
>>> +        // Cannot specify numeric hint twice.
>>>          S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
>>>              << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
>>> -            << PrevValueInt << LoopHintAttr::getOptionName(Option) <<
>>> ValueInt;
>>> +            << CategoryState.Value <<
>>> LoopHintAttr::getOptionName(Option)
>>> +            << ValueInt;
>>>        }
>>> +      CategoryState.ValueIsSet = true;
>>> +      CategoryState.Value = ValueInt;
>>>      }
>>>
>>> -    PrevOptionValue[Option] = ValueInt;
>>> +    if (CategoryState.EnabledIsSet && !CategoryState.Enabled &&
>>> +        CategoryState.ValueIsSet) {
>>> +      // Disable hints are not compatible with numeric hints of the
>>> +      // same category.
>>> +      S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
>>> +          << /*Duplicate=*/false
>>> +          << LoopHintAttr::getOptionName(CategoryState.EnableOptionId)
>>> +          << LoopHintAttr::getValueName(CategoryState.Enabled)
>>> +          << LoopHintAttr::getOptionName(CategoryState.NumericOptionId)
>>> +          << CategoryState.Value;
>>> +    }
>>>    }
>>>  }
>>>
>>>
>>> Modified: cfe/trunk/test/CodeGen/pragma-loop.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGen/pragma-loop.cpp (original)
>>> +++ cfe/trunk/test/CodeGen/pragma-loop.cpp Wed Jun 11 12:56:26 2014
>>> @@ -8,6 +8,7 @@ void while_test(int *List, int Length) {
>>>  #pragma clang loop vectorize(enable)
>>>  #pragma clang loop interleave_count(4)
>>>  #pragma clang loop vectorize_width(4)
>>> +#pragma clang loop unroll(enable)
>>>    while (i < Length) {
>>>      // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
>>> ![[LOOP_1:.*]]
>>>      List[i] = i * 2;
>>> @@ -19,7 +20,7 @@ void while_test(int *List, int Length) {
>>>  void do_test(int *List, int Length) {
>>>    int i = 0;
>>>
>>> -#pragma clang loop vectorize_width(8) interleave_count(4)
>>> +#pragma clang loop vectorize_width(8) interleave_count(4)
>>> unroll(disable)
>>>    do {
>>>      // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
>>> ![[LOOP_2:.*]]
>>>      List[i] = i * 2;
>>> @@ -31,6 +32,7 @@ void do_test(int *List, int Length) {
>>>  void for_test(int *List, int Length) {
>>>  #pragma clang loop interleave(enable)
>>>  #pragma clang loop interleave_count(4)
>>> +#pragma clang loop unroll_count(8)
>>>    for (int i = 0; i < Length; i++) {
>>>      // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
>>> ![[LOOP_3:.*]]
>>>      List[i] = i * 2;
>>> @@ -51,7 +53,7 @@ void for_range_test() {
>>>
>>>  // Verify disable pragma clang loop directive generates correct metadata
>>>  void disable_test(int *List, int Length) {
>>> -#pragma clang loop vectorize(disable)
>>> +#pragma clang loop vectorize(disable) unroll(disable)
>>>    for (int i = 0; i < Length; i++) {
>>>      // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
>>> ![[LOOP_5:.*]]
>>>      List[i] = i * 2;
>>> @@ -60,10 +62,12 @@ void disable_test(int *List, int Length)
>>>
>>>  #define VECWIDTH 2
>>>  #define INTCOUNT 2
>>> +#define UNROLLCOUNT 8
>>>
>>>  // Verify defines are correctly resolved in pragma clang loop directive
>>>  void for_define_test(int *List, int Length, int Value) {
>>>  #pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
>>> +#pragma clang loop unroll_count(UNROLLCOUNT)
>>>    for (int i = 0; i < Length; i++) {
>>>      // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
>>> ![[LOOP_6:.*]]
>>>      List[i] = i * Value;
>>> @@ -74,7 +78,7 @@ void for_define_test(int *List, int Leng
>>>  template <typename A>
>>>  void for_template_test(A *List, int Length, A Value) {
>>>
>>> -#pragma clang loop vectorize_width(8) interleave_count(8)
>>> +#pragma clang loop vectorize_width(8) interleave_count(8)
>>> unroll_count(8)
>>>    for (int i = 0; i < Length; i++) {
>>>      // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
>>> ![[LOOP_7:.*]]
>>>      List[i] = i * Value;
>>> @@ -85,6 +89,7 @@ void for_template_test(A *List, int Leng
>>>  template <typename A>
>>>  void for_template_define_test(A *List, int Length, A Value) {
>>>  #pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
>>> +#pragma clang loop unroll_count(UNROLLCOUNT)
>>>    for (int i = 0; i < Length; i++) {
>>>      // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop
>>> ![[LOOP_8:.*]]
>>>      List[i] = i * Value;
>>> @@ -93,6 +98,7 @@ void for_template_define_test(A *List, i
>>>
>>>  #undef VECWIDTH
>>>  #undef INTCOUNT
>>> +#undef UNROLLCOUNT
>>>
>>>  // Use templates defined above. Test verifies metadata is generated
>>> correctly.
>>>  void template_test(double *List, int Length) {
>>> @@ -102,19 +108,22 @@ void template_test(double *List, int Len
>>>    for_template_define_test<double>(List, Length, Value);
>>>  }
>>>
>>> -// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata
>>> ![[WIDTH_4:.*]], metadata ![[UNROLL_4:.*]], metadata ![[ENABLE_1:.*]]}
>>> +// 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.loopunroll.enable", i1 true}
>>>  // CHECK: ![[WIDTH_4]] = metadata !{metadata !"llvm.vectorizer.width",
>>> i32 4}
>>> -// CHECK: ![[UNROLL_4]] = metadata !{metadata
>>> !"llvm.vectorizer.unroll", i32 4}
>>> -// CHECK: ![[ENABLE_1]] = metadata !{metadata
>>> !"llvm.vectorizer.enable", i1 true}
>>> -// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata
>>> ![[UNROLL_4:.*]], metadata ![[WIDTH_8:.*]]}
>>> +// CHECK: ![[INTERLEAVE_4]] = metadata !{metadata
>>> !"llvm.vectorizer.unroll", i32 4}
>>> +// CHECK: ![[INTENABLE_1]] = metadata !{metadata
>>> !"llvm.vectorizer.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.loopunroll.enable", i1 false}
>>>  // CHECK: ![[WIDTH_8]] = metadata !{metadata !"llvm.vectorizer.width",
>>> i32 8}
>>> -// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata
>>> ![[UNROLL_4:.*]], metadata ![[ENABLE_1:.*]]}
>>> -// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata
>>> ![[UNROLL_2:.*]], metadata ![[WIDTH_2:.*]]}
>>> -// CHECK: ![[UNROLL_2]] = metadata !{metadata
>>> !"llvm.vectorizer.unroll", i32 2}
>>> +// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata
>>> ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[ENABLE_1:.*]]}
>>> +// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loopunroll.count",
>>> i32 8}
>>> +// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata
>>> ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
>>> +// CHECK: ![[INTERLEAVE_2]] = metadata !{metadata
>>> !"llvm.vectorizer.unroll", i32 2}
>>>  // CHECK: ![[WIDTH_2]] = metadata !{metadata !"llvm.vectorizer.width",
>>> i32 2}
>>> -// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata
>>> ![[WIDTH_1:.*]]}
>>> +// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata
>>> ![[UNROLLENABLE_0:.*]], metadata ![[WIDTH_1:.*]]}
>>>  // CHECK: ![[WIDTH_1]] = metadata !{metadata !"llvm.vectorizer.width",
>>> i32 1}
>>> -// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata
>>> ![[UNROLL_2:.*]], metadata ![[WIDTH_2:.*]]}
>>> -// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata
>>> ![[UNROLL_8:.*]], metadata ![[WIDTH_8:.*]]}
>>> -// CHECK: ![[UNROLL_8]] = metadata !{metadata
>>> !"llvm.vectorizer.unroll", i32 8}
>>> -// CHECK: ![[LOOP_8]] = metadata !{metadata ![[LOOP_8]], metadata
>>> ![[UNROLL_2:.*]], metadata ![[WIDTH_2:.*]]}
>>> +// 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:.*]]}
>>> +// CHECK: ![[INTERLEAVE_8]] = metadata !{metadata
>>> !"llvm.vectorizer.unroll", i32 8}
>>> +// CHECK: ![[LOOP_8]] = metadata !{metadata ![[LOOP_8]], metadata
>>> ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
>>>
>>> Modified: cfe/trunk/test/PCH/pragma-loop.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/PCH/pragma-loop.cpp (original)
>>> +++ cfe/trunk/test/PCH/pragma-loop.cpp Wed Jun 11 12:56:26 2014
>>> @@ -4,10 +4,13 @@
>>>  // FIXME: A bug in ParsedAttributes causes the order of the attributes
>>> to be
>>>  // reversed. The checks are consequently in the reverse order below.
>>>
>>> +// CHECK: #pragma clang loop unroll_count(16)
>>>  // CHECK: #pragma clang loop interleave_count(8)
>>>  // CHECK: #pragma clang loop vectorize_width(4)
>>> +// 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 interleave(enable)
>>>  // CHECK: #pragma clang loop vectorize(disable)
>>>
>>> @@ -20,6 +23,7 @@ public:
>>>      int i = 0;
>>>  #pragma clang loop vectorize_width(4)
>>>  #pragma clang loop interleave_count(8)
>>> +#pragma clang loop unroll_count(16)
>>>      while (i < Length) {
>>>        List[i] = i;
>>>        i++;
>>> @@ -30,6 +34,7 @@ public:
>>>      int i = 0;
>>>  #pragma clang loop vectorize(enable)
>>>  #pragma clang loop interleave(disable)
>>> +#pragma clang loop unroll(disable)
>>>      while (i - 1 < Length) {
>>>        List[i] = i;
>>>        i++;
>>> @@ -40,6 +45,7 @@ public:
>>>      int i = 0;
>>>  #pragma clang loop vectorize(disable)
>>>  #pragma clang loop interleave(enable)
>>> +#pragma clang loop unroll(enable)
>>>      while (i - 3 < Length) {
>>>        List[i] = i;
>>>        i++;
>>>
>>> Modified: cfe/trunk/test/Parser/pragma-loop.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/Parser/pragma-loop.cpp (original)
>>> +++ cfe/trunk/test/Parser/pragma-loop.cpp Wed Jun 11 12:56:26 2014
>>> @@ -8,23 +8,26 @@ void test(int *List, int Length) {
>>>
>>>  #pragma clang loop vectorize(enable)
>>>  #pragma clang loop interleave(enable)
>>> +#pragma clang loop unroll(enable)
>>>    while (i + 1 < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>>  #pragma clang loop vectorize_width(4)
>>>  #pragma clang loop interleave_count(8)
>>> +#pragma clang loop unroll_count(16)
>>>    while (i < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>>  #pragma clang loop vectorize(disable)
>>>  #pragma clang loop interleave(disable)
>>> +#pragma clang loop unroll(disable)
>>>    while (i - 1 < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>> -#pragma clang loop vectorize_width(4) interleave_count(8)
>>> +#pragma clang loop vectorize_width(4) interleave_count(8)
>>> unroll_count(16)
>>>    while (i - 2 < Length) {
>>>      List[i] = i;
>>>    }
>>> @@ -35,19 +38,22 @@ void test(int *List, int Length) {
>>>    }
>>>
>>>    int VList[Length];
>>> -#pragma clang loop vectorize(disable) interleave(disable)
>>> +#pragma clang loop vectorize(disable) interleave(disable)
>>> unroll(disable)
>>>    for (int j : VList) {
>>>      VList[j] = List[j];
>>>    }
>>>
>>>  /* expected-error {{expected '('}} */ #pragma clang loop vectorize
>>>  /* expected-error {{expected '('}} */ #pragma clang loop interleave
>>> +/* expected-error {{expected '('}} */ #pragma clang loop unroll
>>>
>>>  /* 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
>>> vectorize_width(4
>>>  /* expected-error {{expected ')'}} */ #pragma clang loop
>>> interleave_count(4
>>> +/* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4
>>>
>>>  /* expected-error {{missing option}} */ #pragma clang loop
>>>  /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop
>>> badkeyword
>>> @@ -61,24 +67,28 @@ void test(int *List, int Length) {
>>>
>>>  /* expected-error {{invalid value 0; expected a positive integer
>>> value}} */ #pragma clang loop vectorize_width(0)
>>>  /* expected-error {{invalid value 0; expected a positive integer
>>> value}} */ #pragma clang loop interleave_count(0)
>>> +/* expected-error {{invalid value 0; expected a positive integer
>>> value}} */ #pragma clang loop unroll_count(0)
>>>    while (i-5 < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>>  /* expected-error {{invalid value -1294967296; expected a positive
>>> integer value}} */ #pragma clang loop vectorize_width(3000000000)
>>>  /* expected-error {{invalid value -1294967296; expected a positive
>>> integer value}} */ #pragma clang loop interleave_count(3000000000)
>>> +/* expected-error {{invalid value -1294967296; expected a positive
>>> integer value}} */ #pragma clang loop unroll_count(3000000000)
>>>    while (i-6 < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>>  /* expected-error {{missing value; expected a positive integer value}}
>>> */ #pragma clang loop vectorize_width(badvalue)
>>>  /* expected-error {{missing value; expected a positive integer value}}
>>> */ #pragma clang loop interleave_count(badvalue)
>>> +/* expected-error {{missing value; expected a positive integer value}}
>>> */ #pragma clang loop unroll_count(badvalue)
>>>    while (i-6 < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>>  /* expected-error {{invalid keyword 'badidentifier'; expected 'enable'
>>> or 'disable'}} */ #pragma clang loop vectorize(badidentifier)
>>>  /* expected-error {{invalid keyword 'badidentifier'; expected 'enable'
>>> or 'disable'}} */ #pragma clang loop interleave(badidentifier)
>>> +/* expected-error {{invalid keyword 'badidentifier'; expected 'enable'
>>> or 'disable'}} */ #pragma clang loop unroll(badidentifier)
>>>    while (i-7 < Length) {
>>>      List[i] = i;
>>>    }
>>> @@ -100,6 +110,8 @@ void test(int *List, int Length) {
>>>  #pragma clang loop vectorize(disable)
>>>  /* expected-error {{incompatible directives 'interleave(disable)' and
>>> 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4)
>>>  #pragma clang loop interleave(disable)
>>> +/* expected-error {{incompatible directives 'unroll(disable)' and
>>> 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
>>> +#pragma clang loop unroll(disable)
>>>    while (i-8 < Length) {
>>>      List[i] = i;
>>>    }
>>> @@ -108,14 +120,18 @@ void test(int *List, int Length) {
>>>  #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)
>>> +#pragma clang loop unroll(disable)
>>>    while (i-9 < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>> -/* expected-error {{incompatible directives 'vectorize_width(4)' and
>>> 'vectorize(disable)'}} */ #pragma clang loop vectorize(disable)
>>> +/* expected-error {{incompatible directives 'vectorize(disable)' and
>>> 'vectorize_width(4)'}} */ #pragma clang loop vectorize(disable)
>>>  #pragma clang loop vectorize_width(4)
>>> -/* expected-error {{incompatible directives 'interleave_count(4)' and
>>> 'interleave(disable)'}} */ #pragma clang loop interleave(disable)
>>> +/* expected-error {{incompatible directives 'interleave(disable)' and
>>> 'interleave_count(4)'}} */ #pragma clang loop interleave(disable)
>>>  #pragma clang loop interleave_count(4)
>>> +/* expected-error {{incompatible directives 'unroll(disable)' and
>>> 'unroll_count(4)'}} */ #pragma clang loop unroll(disable)
>>> +#pragma clang loop unroll_count(4)
>>>    while (i-10 < Length) {
>>>      List[i] = i;
>>>    }
>>> @@ -124,6 +140,8 @@ void test(int *List, int Length) {
>>>  #pragma clang loop vectorize_width(4)
>>>  /* expected-error {{duplicate directives 'interleave_count(4)' and
>>> 'interleave_count(8)'}} */ #pragma clang loop interleave_count(8)
>>>  #pragma clang loop interleave_count(4)
>>> +/* expected-error {{duplicate directives 'unroll_count(4)' and
>>> 'unroll_count(8)'}} */ #pragma clang loop unroll_count(8)
>>> +#pragma clang loop unroll_count(4)
>>>    while (i-11 < Length) {
>>>      List[i] = i;
>>>    }
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>>
>>
>>
>> --
>> ~Craig
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140612/b416c058/attachment.html>


More information about the cfe-commits mailing list