diff options
| author | Mark Heffernan <meheff@google.com> | 2014-07-24 18:09:38 +0000 |
|---|---|---|
| committer | Mark Heffernan <meheff@google.com> | 2014-07-24 18:09:38 +0000 |
| commit | c888e41c0c003889cedffe56b97b23ab4fcb5689 (patch) | |
| tree | b4206d3dcc26feb28e874fb42f72c5fa2d71ed77 /clang/lib | |
| parent | 29a20055965510c7e2a99f7f3b01872a31327d1d (diff) | |
| download | bcm5719-llvm-c888e41c0c003889cedffe56b97b23ab4fcb5689.tar.gz bcm5719-llvm-c888e41c0c003889cedffe56b97b23ab4fcb5689.zip | |
Add support for #pragma nounroll.
llvm-svn: 213885
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 31 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmtAttr.cpp | 14 |
2 files changed, 33 insertions, 12 deletions
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 5fb999d749c..20b87d92b78 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -227,6 +227,9 @@ void Parser::initializePragmaHandlers() { UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll")); PP.AddPragmaHandler(UnrollHintHandler.get()); + + NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll")); + PP.AddPragmaHandler(NoUnrollHintHandler.get()); } void Parser::resetPragmaHandlers() { @@ -290,6 +293,9 @@ void Parser::resetPragmaHandlers() { PP.RemovePragmaHandler(UnrollHintHandler.get()); UnrollHintHandler.reset(); + + PP.RemovePragmaHandler(NoUnrollHintHandler.get()); + NoUnrollHintHandler.reset(); } /// \brief Handle the annotation token produced for #pragma unused(...) @@ -1908,29 +1914,36 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP, /// #pragma unroll /// #pragma unroll unroll-hint-value /// #pragma unroll '(' unroll-hint-value ')' +/// #pragma nounroll /// /// unroll-hint-value: /// constant-expression /// -/// Loop unrolling hints are specified with '#pragma unroll'. '#pragma unroll' -/// can take a numeric argument optionally contained in parentheses. With no -/// argument the directive instructs llvm to try to unroll the loop -/// completely. A positive integer argument can be specified to indicate the -/// number of times the loop should be unrolled. To maximize compatibility with -/// other compilers the unroll count argument can be specified with or without -/// parentheses. +/// Loop unrolling hints can be specified with '#pragma unroll' or +/// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally +/// contained in parentheses. With no argument the directive instructs llvm to +/// try to unroll the loop completely. A positive integer argument can be +/// specified to indicate the number of times the loop should be unrolled. To +/// maximize compatibility with other compilers the unroll count argument can be +/// specified with or without parentheses. Specifying, '#pragma nounroll' +/// disables unrolling of the loop. void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) { - // Incoming token is "unroll" of "#pragma unroll". + // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for + // "#pragma nounroll". Token PragmaName = Tok; PP.Lex(Tok); auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; if (Tok.is(tok::eod)) { - // Unroll pragma without an argument. + // 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) + << "nounroll"; + return; } else { // Unroll pragma with an argument: "#pragma unroll N" or // "#pragma unroll(N)". diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 603581d117b..86c487b4cd9 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -58,9 +58,11 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, St->getStmtClass() != Stmt::ForStmtClass && St->getStmtClass() != Stmt::CXXForRangeStmtClass && St->getStmtClass() != Stmt::WhileStmtClass) { - const char *Pragma = PragmaNameLoc->Ident->getName() == "unroll" - ? "#pragma unroll" - : "#pragma clang loop"; + const char *Pragma = + llvm::StringSwitch<const char *>(PragmaNameLoc->Ident->getName()) + .Case("unroll", "#pragma unroll") + .Case("nounroll", "#pragma nounroll") + .Default("#pragma clang loop"); S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop) << Pragma; return nullptr; } @@ -70,6 +72,9 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, if (PragmaNameLoc->Ident->getName() == "unroll") { Option = ValueLoc ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll; Spelling = LoopHintAttr::Pragma_unroll; + } else if (PragmaNameLoc->Ident->getName() == "nounroll") { + Option = LoopHintAttr::Unroll; + Spelling = LoopHintAttr::Pragma_nounroll; } else { Option = llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName()) .Case("vectorize", LoopHintAttr::Vectorize) @@ -86,6 +91,9 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, if (Option == LoopHintAttr::Unroll && Spelling == LoopHintAttr::Pragma_unroll) { ValueInt = 1; + } else if (Option == LoopHintAttr::Unroll && + Spelling == LoopHintAttr::Pragma_nounroll) { + ValueInt = 0; } else if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) { |

