r214376 - Revert r214333, "Add a state variable to the loop hint attribute."
NAKAMURA Takumi
geek4civic at gmail.com
Wed Jul 30 18:52:33 PDT 2014
Author: chapuni
Date: Wed Jul 30 20:52:33 2014
New Revision: 214376
URL: http://llvm.org/viewvc/llvm-project?rev=214376&view=rev
Log:
Revert r214333, "Add a state variable to the loop hint attribute."
It brought undefined behavior.
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/LoopHint.h
cfe/trunk/lib/CodeGen/CGStmt.cpp
cfe/trunk/lib/Parse/ParsePragma.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Sema/SemaStmtAttr.cpp
cfe/trunk/test/Parser/pragma-loop.cpp
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Jul 30 20:52:33 2014
@@ -1784,18 +1784,12 @@ def Unaligned : IgnoredAttr {
}
def LoopHint : Attr {
- /// #pragma clang loop <option> directive
- /// vectorize: vectorizes loop operations if State == Enable.
- /// vectorize_width: vectorize loop operations with width 'Value'.
- /// interleave: interleave multiple loop iterations if State == Enable.
- /// interleave_count: interleaves 'Value' loop interations.
- /// unroll: fully unroll loop if State == Enable.
- /// unroll_count: unrolls loop 'Value' times.
-
- /// #pragma unroll <argument> directive
- /// <no arg>: fully unrolls loop.
- /// boolean: fully unrolls loop if State == Enable.
- /// expression: unrolls loop 'Value' times.
+ /// vectorize: vectorizes loop operations if 'value != 0'.
+ /// vectorize_width: vectorize loop operations with width 'value'.
+ /// interleave: interleave multiple loop iterations if 'value != 0'.
+ /// interleave_count: interleaves 'value' loop interations.
+ /// unroll: fully unroll loop if 'value != 0'.
+ /// unroll_count: unrolls loop 'value' times.
let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">,
Pragma<"", "nounroll">];
@@ -1806,9 +1800,6 @@ def LoopHint : Attr {
"unroll", "unroll_count"],
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
"Unroll", "UnrollCount"]>,
- EnumArgument<"State", "LoopHintState",
- ["default", "enable", "disable"],
- ["Default", "Enable", "Disable"]>,
DefaultIntArgument<"Value", 1>];
let AdditionalMembers = [{
@@ -1850,9 +1841,9 @@ def LoopHint : Attr {
if (option == VectorizeWidth || option == InterleaveCount ||
option == UnrollCount)
OS << value;
- else if (state == Default)
+ else if (value < 0)
return "";
- else if (state == Enable)
+ else if (value > 0)
OS << (option == Unroll ? "full" : "enable");
else
OS << "disable";
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Jul 30 20:52:33 2014
@@ -917,16 +917,10 @@ def err_omp_immediate_directive : Error<
def err_omp_expected_identifier_for_critical : Error<
"expected identifier specifying the name of the 'omp critical' directive">;
-// Pragma support.
-def err_pragma_invalid_keyword : Error<
- "%select{invalid|missing}0 argument; expected '%select{enable|full}1' or 'disable'">;
-
// Pragma loop support.
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_numeric_value : Error<
- "invalid argument; expected a positive integer value">;
// Pragma unroll support.
def warn_pragma_unroll_cuda_value_in_parens : Warning<
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jul 30 20:52:33 2014
@@ -541,6 +541,8 @@ def note_surrounding_namespace_starts_he
"surrounding namespace with visibility attribute starts here">;
def err_pragma_loop_invalid_value : Error<
"invalid argument; expected a positive integer value">;
+def err_pragma_loop_invalid_keyword : Error<
+ "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<
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Jul 30 20:52:33 2014
@@ -525,7 +525,7 @@ private:
/// \brief Handle the annotation token produced for
/// #pragma clang loop and #pragma unroll.
- bool HandlePragmaLoopHint(LoopHint &Hint);
+ LoopHint HandlePragmaLoopHint();
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
Modified: cfe/trunk/include/clang/Sema/LoopHint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/LoopHint.h?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/LoopHint.h (original)
+++ cfe/trunk/include/clang/Sema/LoopHint.h Wed Jul 30 20:52:33 2014
@@ -29,15 +29,11 @@ struct LoopHint {
// "#pragma unroll" and "#pragma nounroll" cases, this is identical to
// PragmaNameLoc.
IdentifierLoc *OptionLoc;
- // Identifier for the hint state argument. If null, then the state is
- // default value such as for "#pragma unroll".
- IdentifierLoc *StateLoc;
+ // Identifier for the hint argument. If null, then the hint has no argument
+ // such as for "#pragma unroll".
+ IdentifierLoc *ValueLoc;
// Expression for the hint argument if it exists, null otherwise.
Expr *ValueExpr;
-
- LoopHint()
- : PragmaNameLoc(nullptr), OptionLoc(nullptr), StateLoc(nullptr),
- ValueExpr(nullptr) {}
};
} // end namespace clang
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Jul 30 20:52:33 2014
@@ -588,7 +588,6 @@ void CodeGenFunction::EmitCondBrHints(ll
continue;
LoopHintAttr::OptionType Option = LH->getOption();
- LoopHintAttr::LoopHintState State = LH->getState();
int ValueInt = LH->getValue();
const char *MetadataName;
@@ -603,8 +602,8 @@ void CodeGenFunction::EmitCondBrHints(ll
break;
case LoopHintAttr::Unroll:
// With the unroll loop hint, a non-zero value indicates full unrolling.
- MetadataName = State == LoopHintAttr::Disable ? "llvm.loop.unroll.disable"
- : "llvm.loop.unroll.full";
+ MetadataName =
+ ValueInt == 0 ? "llvm.loop.unroll.disable" : "llvm.loop.unroll.full";
break;
case LoopHintAttr::UnrollCount:
MetadataName = "llvm.loop.unroll.count";
@@ -615,7 +614,7 @@ void CodeGenFunction::EmitCondBrHints(ll
switch (Option) {
case LoopHintAttr::Vectorize:
case LoopHintAttr::Interleave:
- if (State != LoopHintAttr::Disable) {
+ 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");
Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Wed Jul 30 20:52:33 2014
@@ -722,65 +722,38 @@ struct PragmaLoopHintInfo {
bool HasValue;
};
-bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
+LoopHint Parser::HandlePragmaLoopHint() {
assert(Tok.is(tok::annot_pragma_loop_hint));
PragmaLoopHintInfo *Info =
static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
- ConsumeToken(); // The annotation token.
- IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
- Hint.PragmaNameLoc = IdentifierLoc::create(
- Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
-
- IdentifierInfo *OptionInfo = Info->Option.getIdentifierInfo();
- Hint.OptionLoc = IdentifierLoc::create(
- Actions.Context, Info->Option.getLocation(), OptionInfo);
-
- // Return a valid hint if pragma unroll or nounroll were specified
- // without an argument.
- bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
- bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
- if (!Info->HasValue && (PragmaUnroll || PragmaNoUnroll)) {
- Hint.Range = Info->PragmaName.getLocation();
- return true;
- }
-
- // If no option is specified the argument is assumed to be numeric.
- bool StateOption = false;
- if (OptionInfo)
- StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
- .Case("vectorize", true)
- .Case("interleave", true)
- .Case("unroll", true)
- .Default(false);
-
- // Validate the argument.
- if (StateOption) {
- bool OptionUnroll = OptionInfo->isStr("unroll");
- SourceLocation StateLoc = Info->Value.getLocation();
- IdentifierInfo *StateInfo = Info->Value.getIdentifierInfo();
- if (!StateInfo || ((OptionUnroll ? !StateInfo->isStr("full")
- : !StateInfo->isStr("enable")) &&
- !StateInfo->isStr("disable"))) {
- Diag(StateLoc, diag::err_pragma_invalid_keyword)
- << /*MissingArgument=*/false << /*FullKeyword=*/OptionUnroll;
- return false;
- }
- Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
- } else {
+ LoopHint Hint;
+ Hint.PragmaNameLoc =
+ IdentifierLoc::create(Actions.Context, Info->PragmaName.getLocation(),
+ Info->PragmaName.getIdentifierInfo());
+ Hint.OptionLoc =
+ IdentifierLoc::create(Actions.Context, Info->Option.getLocation(),
+ Info->Option.getIdentifierInfo());
+ if (Info->HasValue) {
+ Hint.Range =
+ SourceRange(Info->Option.getLocation(), Info->Value.getLocation());
+ Hint.ValueLoc =
+ IdentifierLoc::create(Actions.Context, Info->Value.getLocation(),
+ Info->Value.getIdentifierInfo());
+
// FIXME: We should allow non-type template parameters for the loop hint
// value. See bug report #19610
if (Info->Value.is(tok::numeric_constant))
Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get();
- else {
- Diag(Info->Value.getLocation(), diag::err_pragma_loop_numeric_value);
- return false;
- }
+ else
+ Hint.ValueExpr = nullptr;
+ } else {
+ Hint.Range = SourceRange(Info->PragmaName.getLocation());
+ Hint.ValueLoc = nullptr;
+ Hint.ValueExpr = nullptr;
}
- Hint.Range =
- SourceRange(Info->PragmaName.getLocation(), Info->Value.getLocation());
- return true;
+ return Hint;
}
// #pragma GCC visibility comes in two variants:
@@ -1782,10 +1755,12 @@ void PragmaOptimizeHandler::HandlePragma
}
/// \brief Parses loop or unroll pragma hint value and fills in Info.
-static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
- Token Option, bool ValueInParens,
+static bool ParseLoopHintValue(Preprocessor &PP, Token Tok, Token &PragmaName,
+ Token &Option, bool &ValueInParens,
PragmaLoopHintInfo &Info) {
+ ValueInParens = Tok.is(tok::l_paren);
if (ValueInParens) {
+ PP.Lex(Tok);
if (Tok.is(tok::r_paren)) {
// Nothing between the parentheses.
std::string PragmaString;
@@ -1809,15 +1784,13 @@ static bool ParseLoopHintValue(Preproces
// FIXME: Value should be stored and parsed as a constant expression.
Token Value = Tok;
- PP.Lex(Tok);
if (ValueInParens) {
- // Read ')'
+ PP.Lex(Tok);
if (Tok.isNot(tok::r_paren)) {
PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
return true;
}
- PP.Lex(Tok);
}
Info.PragmaName = PragmaName;
@@ -1899,19 +1872,17 @@ void PragmaLoopHintHandler::HandlePragma
<< /*MissingOption=*/false << OptionInfo;
return;
}
- PP.Lex(Tok);
- // Read '('
- if (Tok.isNot(tok::l_paren)) {
- PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
- return;
- }
+ auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
PP.Lex(Tok);
+ bool ValueInParens;
+ if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
+ return;
- auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
- if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
- *Info))
+ if (!ValueInParens) {
+ PP.Diag(Info->Value.getLocation(), diag::err_expected) << tok::l_paren;
return;
+ }
// Generate the loop hint token.
Token LoopHintTok;
@@ -1920,6 +1891,9 @@ void PragmaLoopHintHandler::HandlePragma
LoopHintTok.setLocation(PragmaName.getLocation());
LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
TokenList.push_back(LoopHintTok);
+
+ // Get next optimization option.
+ PP.Lex(Tok);
}
if (Tok.isNot(tok::eod)) {
@@ -1964,6 +1938,7 @@ void PragmaUnrollHintHandler::HandlePrag
if (Tok.is(tok::eod)) {
// nounroll or unroll pragma without an argument.
Info->PragmaName = PragmaName;
+ Info->Option = PragmaName;
Info->HasValue = false;
} else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
@@ -1972,12 +1947,9 @@ void PragmaUnrollHintHandler::HandlePrag
} else {
// Unroll pragma with an argument: "#pragma unroll N" or
// "#pragma unroll(N)".
- // Read '(' if it exists.
- bool ValueInParens = Tok.is(tok::l_paren);
- if (ValueInParens)
- PP.Lex(Tok);
-
- if (ParseLoopHintValue(PP, Tok, PragmaName, Token(), ValueInParens, *Info))
+ bool ValueInParens;
+ if (ParseLoopHintValue(PP, Tok, PragmaName, PragmaName, ValueInParens,
+ *Info))
return;
// In CUDA, the argument to '#pragma unroll' should not be contained in
@@ -1986,6 +1958,7 @@ void PragmaUnrollHintHandler::HandlePrag
PP.Diag(Info->Value.getLocation(),
diag::warn_pragma_unroll_cuda_value_in_parens);
+ PP.Lex(Tok);
if (Tok.isNot(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
<< "unroll";
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Jul 30 20:52:33 2014
@@ -1817,11 +1817,10 @@ StmtResult Parser::ParsePragmaLoopHint(S
// Get loop hints and consume annotated token.
while (Tok.is(tok::annot_pragma_loop_hint)) {
- LoopHint Hint;
- if (!HandlePragmaLoopHint(Hint))
- continue;
+ LoopHint Hint = HandlePragmaLoopHint();
+ ConsumeToken();
- ArgsUnion ArgHints[] = {Hint.PragmaNameLoc, Hint.OptionLoc, Hint.StateLoc,
+ ArgsUnion ArgHints[] = {Hint.PragmaNameLoc, Hint.OptionLoc, Hint.ValueLoc,
ArgsUnion(Hint.ValueExpr)};
TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr,
Hint.PragmaNameLoc->Loc, ArgHints, 4,
Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Wed Jul 30 20:52:33 2014
@@ -47,11 +47,13 @@ static Attr *handleLoopHintAttr(Sema &S,
SourceRange) {
IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0);
IdentifierLoc *OptionLoc = A.getArgAsIdent(1);
- IdentifierLoc *StateLoc = A.getArgAsIdent(2);
+ IdentifierInfo *OptionInfo = OptionLoc->Ident;
+ IdentifierLoc *ValueLoc = A.getArgAsIdent(2);
+ IdentifierInfo *ValueInfo = ValueLoc ? ValueLoc->Ident : nullptr;
Expr *ValueExpr = A.getArgAsExpr(3);
- bool PragmaUnroll = PragmaNameLoc->Ident->getName() == "unroll";
- bool PragmaNoUnroll = PragmaNameLoc->Ident->getName() == "nounroll";
+ assert(OptionInfo && "Attribute must have valid option info.");
+
if (St->getStmtClass() != Stmt::DoStmtClass &&
St->getStmtClass() != Stmt::ForStmtClass &&
St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
@@ -67,16 +69,13 @@ static Attr *handleLoopHintAttr(Sema &S,
LoopHintAttr::OptionType Option;
LoopHintAttr::Spelling Spelling;
- if (PragmaUnroll) {
- Option = ValueExpr ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll;
+ if (PragmaNameLoc->Ident->getName() == "unroll") {
+ Option = ValueLoc ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll;
Spelling = LoopHintAttr::Pragma_unroll;
- } else if (PragmaNoUnroll) {
+ } else if (PragmaNameLoc->Ident->getName() == "nounroll") {
Option = LoopHintAttr::Unroll;
Spelling = LoopHintAttr::Pragma_nounroll;
} else {
- assert(OptionLoc && OptionLoc->Ident &&
- "Attribute must have valid option info.");
- IdentifierInfo *OptionInfo = OptionLoc->Ident;
Option = llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName())
.Case("vectorize", LoopHintAttr::Vectorize)
.Case("vectorize_width", LoopHintAttr::VectorizeWidth)
@@ -88,10 +87,35 @@ static Attr *handleLoopHintAttr(Sema &S,
Spelling = LoopHintAttr::Pragma_clang_loop;
}
- int ValueInt = 1;
- LoopHintAttr::LoopHintState State = LoopHintAttr::Default;
- if (PragmaNoUnroll) {
- State = LoopHintAttr::Disable;
+ int ValueInt = -1;
+ if (Option == LoopHintAttr::Unroll &&
+ Spelling == LoopHintAttr::Pragma_unroll) {
+ if (ValueInfo)
+ ValueInt = (ValueInfo->isStr("disable") ? 0 : 1);
+ } else if (Option == LoopHintAttr::Unroll &&
+ Spelling == LoopHintAttr::Pragma_nounroll) {
+ ValueInt = 0;
+ } 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)
+ << TrueKeyword;
+ return nullptr;
+ }
+ if (ValueInfo->isStr("disable"))
+ ValueInt = 0;
+ else if (ValueInfo->getName() == TrueKeyword)
+ ValueInt = 1;
+ else {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
+ << TrueKeyword;
+ return nullptr;
+ }
} else if (Option == LoopHintAttr::VectorizeWidth ||
Option == LoopHintAttr::InterleaveCount ||
Option == LoopHintAttr::UnrollCount) {
@@ -100,39 +124,28 @@ static Attr *handleLoopHintAttr(Sema &S,
llvm::APSInt ValueAPS;
if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context) ||
(ValueInt = ValueAPS.getSExtValue()) < 1) {
- S.Diag(A.getLoc(), diag::err_pragma_loop_invalid_value);
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value);
return nullptr;
}
- } else if (Option == LoopHintAttr::Vectorize ||
- Option == LoopHintAttr::Interleave ||
- Option == LoopHintAttr::Unroll) {
- // Default state is assumed if StateLoc is not specified, such as with
- // '#pragma unroll'.
- if (StateLoc && StateLoc->Ident) {
- if (StateLoc->Ident->isStr("disable"))
- State = LoopHintAttr::Disable;
- else
- State = LoopHintAttr::Enable;
- }
- }
+ } else
+ llvm_unreachable("Unknown loop hint option");
- return LoopHintAttr::CreateImplicit(S.Context, Spelling, Option, State,
- ValueInt, A.getRange());
+ return LoopHintAttr::CreateImplicit(S.Context, Spelling, Option, ValueInt,
+ A.getRange());
}
-static void
-CheckForIncompatibleAttributes(Sema &S,
- const SmallVectorImpl<const Attr *> &Attrs) {
- // There are 3 categories of loop hints attributes: vectorize, interleave,
- // and unroll. Each comes in two variants: a state form and a numeric form.
- // The state form selectively defaults/enables/disables the transformation
- // for the loop (for unroll, default indicates full unrolling rather than
- // enabling the transformation). The numeric form form provides an integer
- // hint (for example, unroll count) to the transformer. The following array
- // accumulates the hints encountered while iterating through the attributes
- // to check for compatibility.
+static void CheckForIncompatibleAttributes(
+ Sema &S, const SmallVectorImpl<const Attr *> &Attrs) {
+ // 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 nonzero value indicates full unrolling rather than enabling
+ // the transformation). The numeric hint provides an integer hint (for
+ // example, unroll count) to the transformer. The following array accumulates
+ // the hints encountered while iterating through the attributes to check for
+ // compatibility.
struct {
- const LoopHintAttr *StateAttr;
+ const LoopHintAttr *EnableAttr;
const LoopHintAttr *NumericAttr;
} HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}};
@@ -166,8 +179,8 @@ CheckForIncompatibleAttributes(Sema &S,
if (Option == LoopHintAttr::Vectorize ||
Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {
// Enable|disable hint. For example, vectorize(enable).
- PrevAttr = CategoryState.StateAttr;
- CategoryState.StateAttr = LH;
+ PrevAttr = CategoryState.EnableAttr;
+ CategoryState.EnableAttr = LH;
} else {
// Numeric hint. For example, vectorize_width(8).
PrevAttr = CategoryState.NumericAttr;
@@ -182,15 +195,14 @@ CheckForIncompatibleAttributes(Sema &S,
<< /*Duplicate=*/true << PrevAttr->getDiagnosticName(Policy)
<< LH->getDiagnosticName(Policy);
- if (CategoryState.StateAttr && CategoryState.NumericAttr &&
- (Category == Unroll ||
- CategoryState.StateAttr->getState() == LoopHintAttr::Disable)) {
+ 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.StateAttr->getDiagnosticName(Policy)
+ << CategoryState.EnableAttr->getDiagnosticName(Policy)
<< CategoryState.NumericAttr->getDiagnosticName(Policy);
}
}
Modified: cfe/trunk/test/Parser/pragma-loop.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-loop.cpp?rev=214376&r1=214375&r2=214376&view=diff
==============================================================================
--- cfe/trunk/test/Parser/pragma-loop.cpp (original)
+++ cfe/trunk/test/Parser/pragma-loop.cpp Wed Jul 30 20:52:33 2014
@@ -83,9 +83,6 @@ void test(int *List, int Length) {
List[i] = i;
}
-/* expected-error {{expected ')'}} */ #pragma clang loop vectorize_width(1 +) 1
-/* expected-warning {{extra tokens at end of '#pragma clang loop'}} */ #pragma clang loop vectorize_width(1) +1
-
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(badvalue)
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(badvalue)
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(badvalue)
More information about the cfe-commits
mailing list