Loading clang/docs/ReleaseNotes.rst +7 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,13 @@ interleaving, and unrolling to be enabled or disabled. Vector width as well as interleave and unrolling count can be manually specified. See language extensions for details. Clang now supports the `#pragma unroll` directive to specify loop unrolling optimization hints. Placed just prior to the desired loop, `#pragma unroll` directs the loop unroller to attempt to fully unroll the loop. The pragma may also be specified with a positive integer parameter indicating the desired unroll count: `#pragma unroll _value_`. The unroll count parameter can be optionally enclosed in parentheses. C Language Changes in Clang --------------------------- Loading clang/include/clang/Basic/Attr.td +38 −6 Original line number Diff line number Diff line Loading @@ -1779,7 +1779,7 @@ def LoopHint : Attr { /// unroll: unroll loop if 'value != 0'. /// unroll_count: unrolls loop 'value' times. let Spellings = [Pragma<"clang", "loop">]; let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">]; /// State of the loop optimization specified by the spelling. let Args = [EnumArgument<"Option", "OptionType", Loading Loading @@ -1809,15 +1809,47 @@ def LoopHint : Attr { } void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { OS << getOptionName(option) << "("; unsigned SpellingIndex = getSpellingListIndex(); if (SpellingIndex == Pragma_unroll) { // String "unroll" of "#pragma unroll" is already emitted as the // pragma name. if (option == UnrollCount) OS << getValueString(); OS << "\n"; return; } assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); OS << getOptionName(option) << getValueString() << "\n"; } // Return a string containing the loop hint argument including the // enclosing parentheses. std::string getValueString() const { std::string ValueName; if (option == VectorizeWidth || option == InterleaveCount || option == UnrollCount) OS << value; ValueName = std::to_string(value); else if (value) ValueName = "enable"; else OS << getValueName(value); OS << ")\n"; ValueName = "disable"; return "(" + ValueName + ")"; } // Return a string suitable for identifying this attribute in diagnostics. std::string getDiagnosticName() const { unsigned SpellingIndex = getSpellingListIndex(); if (SpellingIndex == Pragma_unroll && option == Unroll) return "#pragma unroll"; else if (SpellingIndex == Pragma_unroll && option == UnrollCount) { return "#pragma unroll" + getValueString(); } else { assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); return std::string(getOptionName(option)) + getValueString(); } } }]; let Documentation = [LoopHintDocs]; let Documentation = [LoopHintDocs, UnrollHintDocs]; } clang/include/clang/Basic/AttrDocs.td +42 −0 Original line number Diff line number Diff line Loading @@ -1045,3 +1045,45 @@ as interleave and unrolling count can be manually specified. See for details. }]; } def UnrollHintDocs : Documentation { let Category = DocCatStmt; let Content = [{ Loop unrolling optimization hints can be specified with ``#pragma unroll``. The pragma is placed immediately before a for, while, do-while, or c++11 range-based for loop. Specifying ``#pragma unroll`` without a parameter directs the loop unroller to attempt to fully unroll the loop if the trip count is known at compile time: .. code-block:: c++ #pragma unroll for (...) { ... } Specifying the optional parameter, ``#pragma unroll _value_``, directs the unroller to unroll the loop ``_value_`` times. The parameter may optionally be enclosed in parentheses: .. code-block:: c++ #pragma unroll 16 for (...) { ... } #pragma unroll(16) for (...) { ... } ``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to ``#pragma clang loop unroll(enable)`` 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. }]; } clang/include/clang/Basic/DiagnosticGroups.td +4 −0 Original line number Diff line number Diff line Loading @@ -709,3 +709,7 @@ def BackendOptimizationFailure : DiagGroup<"pass-failed">; // Instrumentation based profiling warnings. def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">; def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">; // A warning group for warnings about code that clang accepts when // compiling CUDA C/C++ but which is not compatible with the CUDA spec. def CudaCompat : DiagGroup<"cuda-compat">; clang/include/clang/Basic/DiagnosticParseKinds.td +8 −4 Original line number Diff line number Diff line Loading @@ -813,6 +813,9 @@ def warn_pragma_expected_punc : Warning< "expected ')' or ',' in '#pragma %0'">, InGroup<IgnoredPragmas>; def warn_pragma_expected_non_wide_string : Warning< "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">; // - #pragma options def warn_pragma_options_expected_align : Warning< "expected 'align' following '#pragma options' - ignored">, Loading Loading @@ -860,8 +863,6 @@ def err_pragma_pointers_to_members_unknown_kind : Error< "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1" "'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">; // - #pragma clang optimize on/off def err_pragma_optimize_missing_argument : Error< "missing argument to '#pragma clang optimize'; expected 'on' or 'off'">; def err_pragma_optimize_invalid_argument : Error< "unexpected argument '%0' to '#pragma clang optimize'; " "expected 'on' or 'off'">; Loading Loading @@ -917,8 +918,11 @@ def err_omp_expected_identifier_for_critical : Error< def err_pragma_loop_invalid_option : Error< "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, " "vectorize_width, interleave, interleave_count, unroll, or unroll_count">; def err_pragma_loop_missing_argument : Error< "missing argument to loop pragma %0">; // Pragma unroll support. def warn_pragma_unroll_cuda_value_in_parens : Warning< "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">, InGroup<CudaCompat>; } // end of Parse Issue category. let CategoryName = "Modules Issue" in { Loading Loading
clang/docs/ReleaseNotes.rst +7 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,13 @@ interleaving, and unrolling to be enabled or disabled. Vector width as well as interleave and unrolling count can be manually specified. See language extensions for details. Clang now supports the `#pragma unroll` directive to specify loop unrolling optimization hints. Placed just prior to the desired loop, `#pragma unroll` directs the loop unroller to attempt to fully unroll the loop. The pragma may also be specified with a positive integer parameter indicating the desired unroll count: `#pragma unroll _value_`. The unroll count parameter can be optionally enclosed in parentheses. C Language Changes in Clang --------------------------- Loading
clang/include/clang/Basic/Attr.td +38 −6 Original line number Diff line number Diff line Loading @@ -1779,7 +1779,7 @@ def LoopHint : Attr { /// unroll: unroll loop if 'value != 0'. /// unroll_count: unrolls loop 'value' times. let Spellings = [Pragma<"clang", "loop">]; let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">]; /// State of the loop optimization specified by the spelling. let Args = [EnumArgument<"Option", "OptionType", Loading Loading @@ -1809,15 +1809,47 @@ def LoopHint : Attr { } void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { OS << getOptionName(option) << "("; unsigned SpellingIndex = getSpellingListIndex(); if (SpellingIndex == Pragma_unroll) { // String "unroll" of "#pragma unroll" is already emitted as the // pragma name. if (option == UnrollCount) OS << getValueString(); OS << "\n"; return; } assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); OS << getOptionName(option) << getValueString() << "\n"; } // Return a string containing the loop hint argument including the // enclosing parentheses. std::string getValueString() const { std::string ValueName; if (option == VectorizeWidth || option == InterleaveCount || option == UnrollCount) OS << value; ValueName = std::to_string(value); else if (value) ValueName = "enable"; else OS << getValueName(value); OS << ")\n"; ValueName = "disable"; return "(" + ValueName + ")"; } // Return a string suitable for identifying this attribute in diagnostics. std::string getDiagnosticName() const { unsigned SpellingIndex = getSpellingListIndex(); if (SpellingIndex == Pragma_unroll && option == Unroll) return "#pragma unroll"; else if (SpellingIndex == Pragma_unroll && option == UnrollCount) { return "#pragma unroll" + getValueString(); } else { assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); return std::string(getOptionName(option)) + getValueString(); } } }]; let Documentation = [LoopHintDocs]; let Documentation = [LoopHintDocs, UnrollHintDocs]; }
clang/include/clang/Basic/AttrDocs.td +42 −0 Original line number Diff line number Diff line Loading @@ -1045,3 +1045,45 @@ as interleave and unrolling count can be manually specified. See for details. }]; } def UnrollHintDocs : Documentation { let Category = DocCatStmt; let Content = [{ Loop unrolling optimization hints can be specified with ``#pragma unroll``. The pragma is placed immediately before a for, while, do-while, or c++11 range-based for loop. Specifying ``#pragma unroll`` without a parameter directs the loop unroller to attempt to fully unroll the loop if the trip count is known at compile time: .. code-block:: c++ #pragma unroll for (...) { ... } Specifying the optional parameter, ``#pragma unroll _value_``, directs the unroller to unroll the loop ``_value_`` times. The parameter may optionally be enclosed in parentheses: .. code-block:: c++ #pragma unroll 16 for (...) { ... } #pragma unroll(16) for (...) { ... } ``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to ``#pragma clang loop unroll(enable)`` 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. }]; }
clang/include/clang/Basic/DiagnosticGroups.td +4 −0 Original line number Diff line number Diff line Loading @@ -709,3 +709,7 @@ def BackendOptimizationFailure : DiagGroup<"pass-failed">; // Instrumentation based profiling warnings. def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">; def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">; // A warning group for warnings about code that clang accepts when // compiling CUDA C/C++ but which is not compatible with the CUDA spec. def CudaCompat : DiagGroup<"cuda-compat">;
clang/include/clang/Basic/DiagnosticParseKinds.td +8 −4 Original line number Diff line number Diff line Loading @@ -813,6 +813,9 @@ def warn_pragma_expected_punc : Warning< "expected ')' or ',' in '#pragma %0'">, InGroup<IgnoredPragmas>; def warn_pragma_expected_non_wide_string : Warning< "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">; // - #pragma options def warn_pragma_options_expected_align : Warning< "expected 'align' following '#pragma options' - ignored">, Loading Loading @@ -860,8 +863,6 @@ def err_pragma_pointers_to_members_unknown_kind : Error< "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1" "'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">; // - #pragma clang optimize on/off def err_pragma_optimize_missing_argument : Error< "missing argument to '#pragma clang optimize'; expected 'on' or 'off'">; def err_pragma_optimize_invalid_argument : Error< "unexpected argument '%0' to '#pragma clang optimize'; " "expected 'on' or 'off'">; Loading Loading @@ -917,8 +918,11 @@ def err_omp_expected_identifier_for_critical : Error< def err_pragma_loop_invalid_option : Error< "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, " "vectorize_width, interleave, interleave_count, unroll, or unroll_count">; def err_pragma_loop_missing_argument : Error< "missing argument to loop pragma %0">; // Pragma unroll support. def warn_pragma_unroll_cuda_value_in_parens : Warning< "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">, InGroup<CudaCompat>; } // end of Parse Issue category. let CategoryName = "Modules Issue" in { Loading