From c8e3924b3b8aacbcd089530e5fe8c1b463177780 Mon Sep 17 00:00:00 2001 From: David Green Date: Wed, 1 Aug 2018 14:36:12 +0000 Subject: [UnrollAndJam] Add unroll_and_jam pragma handling This adds support for the unroll_and_jam pragma, to go with the recently added unroll and jam pass. The name of the pragma is the same as is used in the Intel compiler, and most of the code works the same as for unroll. #pragma clang loop unroll_and_jam has been separated into a different patch. This part adds #pragma unroll_and_jam with an optional count, and #pragma no_unroll_and_jam to disable the transform. Differential Revision: https://reviews.llvm.org/D47267 llvm-svn: 338566 --- clang/lib/Parse/ParsePragma.cpp | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'clang/lib/Parse/ParsePragma.cpp') diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 07f48e0779d..fb862c706f9 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -352,6 +352,13 @@ void Parser::initializePragmaHandlers() { NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll")); PP.AddPragmaHandler(NoUnrollHintHandler.get()); + UnrollAndJamHintHandler.reset(new PragmaUnrollHintHandler("unroll_and_jam")); + PP.AddPragmaHandler(UnrollAndJamHintHandler.get()); + + NoUnrollAndJamHintHandler.reset( + new PragmaUnrollHintHandler("nounroll_and_jam")); + PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get()); + FPHandler.reset(new PragmaFPHandler()); PP.AddPragmaHandler("clang", FPHandler.get()); @@ -451,6 +458,12 @@ void Parser::resetPragmaHandlers() { PP.RemovePragmaHandler(NoUnrollHintHandler.get()); NoUnrollHintHandler.reset(); + PP.RemovePragmaHandler(UnrollAndJamHintHandler.get()); + UnrollAndJamHintHandler.reset(); + + PP.RemovePragmaHandler(NoUnrollAndJamHintHandler.get()); + NoUnrollAndJamHintHandler.reset(); + PP.RemovePragmaHandler("clang", FPHandler.get()); FPHandler.reset(); @@ -955,6 +968,8 @@ static std::string PragmaLoopHintString(Token PragmaName, Token Option) { if (PragmaName.getIdentifierInfo()->getName() == "loop") { PragmaString = "clang loop "; PragmaString += Option.getIdentifierInfo()->getName(); + } else if (PragmaName.getIdentifierInfo()->getName() == "unroll_and_jam") { + PragmaString = "unroll_and_jam"; } else { assert(PragmaName.getIdentifierInfo()->getName() == "unroll" && "Unexpected pragma name"); @@ -986,7 +1001,10 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { // without an argument. bool PragmaUnroll = PragmaNameInfo->getName() == "unroll"; bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll"; - if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) { + bool PragmaUnrollAndJam = PragmaNameInfo->getName() == "unroll_and_jam"; + bool PragmaNoUnrollAndJam = PragmaNameInfo->getName() == "nounroll_and_jam"; + if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll || PragmaUnrollAndJam || + PragmaNoUnrollAndJam)) { ConsumeAnnotationToken(); Hint.Range = Info->PragmaName.getLocation(); return true; @@ -999,24 +1017,28 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { // If no option is specified the argument is assumed to be a constant expr. bool OptionUnroll = false; + bool OptionUnrollAndJam = false; bool OptionDistribute = false; bool StateOption = false; if (OptionInfo) { // Pragma Unroll does not specify an option. OptionUnroll = OptionInfo->isStr("unroll"); + OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam"); OptionDistribute = OptionInfo->isStr("distribute"); StateOption = llvm::StringSwitch(OptionInfo->getName()) .Case("vectorize", true) .Case("interleave", true) .Default(false) || - OptionUnroll || OptionDistribute; + OptionUnroll || OptionUnrollAndJam || OptionDistribute; } - bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute; + bool AssumeSafetyArg = + !OptionUnroll && !OptionUnrollAndJam && !OptionDistribute; // Verify loop hint has an argument. if (Toks[0].is(tok::eof)) { ConsumeAnnotationToken(); Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument) - << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll + << /*StateArgument=*/StateOption + << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam) << /*AssumeSafetyKeyword=*/AssumeSafetyArg; return false; } @@ -1027,15 +1049,15 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { SourceLocation StateLoc = Toks[0].getLocation(); IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo(); - bool Valid = StateInfo && - llvm::StringSwitch(StateInfo->getName()) - .Cases("enable", "disable", true) - .Case("full", OptionUnroll) - .Case("assume_safety", AssumeSafetyArg) - .Default(false); + bool Valid = + StateInfo && llvm::StringSwitch(StateInfo->getName()) + .Cases("enable", "disable", true) + .Case("full", OptionUnroll || OptionUnrollAndJam) + .Case("assume_safety", AssumeSafetyArg) + .Default(false); if (!Valid) { Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword) - << /*FullKeyword=*/OptionUnroll + << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam) << /*AssumeSafetyKeyword=*/AssumeSafetyArg; return false; } @@ -2844,6 +2866,10 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP, /// #pragma unroll unroll-hint-value /// #pragma unroll '(' unroll-hint-value ')' /// #pragma nounroll +/// #pragma unroll_and_jam +/// #pragma unroll_and_jam unroll-hint-value +/// #pragma unroll_and_jam '(' unroll-hint-value ')' +/// #pragma nounroll_and_jam /// /// unroll-hint-value: /// constant-expression @@ -2868,9 +2894,10 @@ void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP, // nounroll or unroll pragma without an argument. Info->PragmaName = PragmaName; Info->Option.startToken(); - } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") { + } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll" || + PragmaName.getIdentifierInfo()->getName() == "nounroll_and_jam") { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) - << "nounroll"; + << PragmaName.getIdentifierInfo()->getName(); return; } else { // Unroll pragma with an argument: "#pragma unroll N" or -- cgit v1.2.3