[PATCH] D69088: [Lex] #pragma clang transform

2020-06-18 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.
Herald added a subscriber: sstefan1.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2020-05-06 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#2023114 , @kbarton wrote:

> @Meinersbur I missed the RFC and discussion on the cfe-dev mailing list. 
> Could you post a link here so that it's included in the history?


See the collection of links in a previous comment: 
https://reviews.llvm.org/D69088#1715025

In particular, you seem to look for this: 
https://lists.llvm.org/pipermail/cfe-dev/2018-May/058141.html . However, there 
was no response to that RFC.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2020-05-06 Thread Kit Barton via Phabricator via cfe-commits
kbarton added a comment.

@Meinersbur I missed the RFC and discussion on the cfe-dev mailing list. Could 
you post a link here so that it's included in the history?

I don't have any opposition to this, and it seems that you have addressed all 
the comments from reviewers. So, unless there was something that came up from 
the RFC discussion (which I doubt, since you just pinged the patch), I think 
this is good to land. However, I'm not really in a position to approve the 
patch since the implementation is well out of my domain of expertise.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2020-05-04 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2020-04-14 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2020-04-07 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2020-03-31 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-12-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1772141 , @rjmccall wrote:

> This is a major new language feature, and code review is probably not the 
> right venue for reviewing it; there should be a thread on cfe-dev.  My 
> apologies if that's already been discussed and I missed it.


For some reason Phabricator did not send me an email when you submitted your 
comment such that I missed it. I only noticed it with @greened comment. My 
apologies.

I will write send an RFC to the mailing-list.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-12-17 Thread David Greene via Phabricator via cfe-commits
greened added a comment.

In D69088#1772141 , @rjmccall wrote:

> This is a major new language feature, and code review is probably not the 
> right venue for reviewing it; there should be a thread on cfe-dev.  My 
> apologies if that's already been discussed and I missed it.


I agree.  I know the original RFC didn't get many responses but perhaps 
discussion will pick up given that patches now exist.  The discussion should 
happen on both cfe-dev and llvm-dev because it affects both.

In particular I'd like to understand the motivation for this.  Is it for 
experimental purposes, to aid in compiler tuning, to allow the user to override 
compiler decisions and/or something else?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-12-05 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

This is a major new language feature, and code review is probably not the right 
venue for reviewing it; there should be a thread on cfe-dev.  My apologies if 
that's already been discussed and I missed it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-12-02 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-11-19 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur updated this revision to Diff 230094.
Meinersbur added a comment.

- Address @ABataev's review


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Parse/Parser.h
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/test/Parser/pragma-no-transform.cpp

Index: clang/test/Parser/pragma-no-transform.cpp
===
--- /dev/null
+++ clang/test/Parser/pragma-no-transform.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++11 -fno-experimental-transform-pragma -Wall -verify %s
+
+void pragma_transform(int *List, int Length) {
+/* expected-warning@+1 {{unknown pragma ignored}} */
+#pragma clang transform unroll partial(4)
+  for (int i = 0; i < Length; i+=1)
+  List[i] = i;
+}
+
Index: clang/lib/Parse/ParsePragma.cpp
===
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -262,6 +262,12 @@
   ParsedAttributes AttributesForPragmaAttribute;
 };
 
+struct PragmaTransformHandler : public PragmaHandler {
+  PragmaTransformHandler() : PragmaHandler("transform") {}
+  void HandlePragma(Preprocessor , PragmaIntroducer Introducer,
+Token ) override;
+};
+
 }  // end namespace
 
 void Parser::initializePragmaHandlers() {
@@ -382,6 +388,11 @@
   AttributePragmaHandler =
   std::make_unique(AttrFactory);
   PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
+
+  if (getLangOpts().ExperimentalTransformPragma) {
+TransformHandler = std::make_unique();
+PP.AddPragmaHandler("clang", TransformHandler.get());
+  }
 }
 
 void Parser::resetPragmaHandlers() {
@@ -487,6 +498,11 @@
 
   PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
   AttributePragmaHandler.reset();
+
+  if (getLangOpts().ExperimentalTransformPragma) {
+PP.RemovePragmaHandler("clang", TransformHandler.get());
+TransformHandler.reset();
+  }
 }
 
 /// Handle the annotation token produced for #pragma unused(...)
@@ -3008,6 +3024,65 @@
   /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
 }
 
+/// Handle
+///   #pragma clang transform ...
+void PragmaTransformHandler::HandlePragma(Preprocessor ,
+  PragmaIntroducer Introducer,
+  Token ) {
+  // "clang" token is not passed
+  // "transform" is FirstTok
+  // Everything up until tok::eod (or tok::eof) is wrapped between
+  // tok::annot_pragma_transform and tok::annot_pragma_transform_end, and
+  // pushed-back into the token stream. The tok::eod/eof is consumed as well:
+  //
+  // Token stream before:
+  //   FirstTok:"transform" |  [clauses..] eod   ...
+  //
+  // Token stream after :
+  //"transform"[clauses..] eod | ...
+  // After pushing the annotation tokens:
+  //
+  // | annot_pragma_transform  [clauses..] annot_pragma_transform_end ...
+  //
+  // The symbol | is before the next token returned by PP.Lex()
+  SmallVector PragmaToks;
+
+  Token StartTok;
+  StartTok.startToken();
+  StartTok.setKind(tok::annot_pragma_transform);
+  StartTok.setLocation(FirstTok.getLocation());
+  PragmaToks.push_back(StartTok);
+
+  SourceLocation EodLoc = FirstTok.getLocation();
+  while (true) {
+Token Tok;
+PP.Lex(Tok);
+assert(!Tok.isAnnotation() &&
+   "It should not be possible to nest annotations");
+
+if (Tok.is(tok::eod) || Tok.is(tok::eof)) {
+  EodLoc = Tok.getLocation();
+  break;
+}
+
+PragmaToks.push_back(Tok);
+  }
+
+  Token EndTok;
+  EndTok.startToken();
+  EndTok.setKind(tok::annot_pragma_transform_end);
+  EndTok.setLocation(EodLoc);
+  PragmaToks.push_back(EndTok);
+
+  // Copy tokens for the preprocessor to own and free.
+  auto Toks = std::make_unique(PragmaToks.size());
+  std::copy(PragmaToks.begin(), PragmaToks.end(), Toks.get());
+
+  // Handle in parser
+  PP.EnterTokenStream(std::move(Toks), PragmaToks.size(),
+  /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
+}
+
 /// Handle the Microsoft \#pragma intrinsic extension.
 ///
 /// The syntax is:
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -3229,6 +3229,11 @@
 
   Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers);
   Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj);
+
+  // Enable or disable support for #pragma clang transform.
+  Opts.ExperimentalTransformPragma =
+  Args.hasFlag(options::OPT_fexperimental_transform_pragma,
+   

[PATCH] D69088: [Lex] #pragma clang transform

2019-11-19 Thread Alexey Bataev via Phabricator via cfe-commits
ABataev added inline comments.



Comment at: clang/lib/Parse/ParsePragma.cpp:3062
+// TODO: Handle nested pragmas as in r325369.
+assert(!Tok.isAnnotation());
+assert(Tok.isNot(tok::annot_pragma_transform));

Add a message in this assert.



Comment at: clang/lib/Parse/ParsePragma.cpp:3063-3067
+assert(Tok.isNot(tok::annot_pragma_transform));
+assert(Tok.isNot(tok::annot_pragma_transform_end));
+assert(Tok.isNot(tok::annot_pragma_openmp));
+assert(Tok.isNot(tok::annot_pragma_openmp_end));
+assert(Tok.isNot(tok::annot_pragma_loop_hint));

These asserts are covered by the very first one `assert(!Tok.isAnnotation());`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-11-19 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-11-01 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur updated this revision to Diff 227561.
Meinersbur added a comment.

- Implement -f(no-)experimental-transform-pragma


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Parse/Parser.h
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/test/Parser/pragma-no-transform.cpp

Index: clang/test/Parser/pragma-no-transform.cpp
===
--- /dev/null
+++ clang/test/Parser/pragma-no-transform.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++11 -fno-experimental-transform-pragma -Wall -verify %s
+
+void pragma_transform(int *List, int Length) {
+/* expected-warning@+1 {{unknown pragma ignored}} */
+#pragma clang transform unroll partial(4)
+  for (int i = 0; i < Length; i+=1)
+  List[i] = i;
+}
+
Index: clang/lib/Parse/ParsePragma.cpp
===
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -247,6 +247,12 @@
   void HandlePragma(Preprocessor , PragmaIntroducer Introducer,
 Token ) override;
 
+struct PragmaTransformHandler : public PragmaHandler {
+  PragmaTransformHandler() : PragmaHandler("transform") {}
+  void HandlePragma(Preprocessor , PragmaIntroducer Introducer,
+Token ) override;
+};
+
 private:
   Sema 
 };
@@ -382,6 +388,11 @@
   AttributePragmaHandler =
   std::make_unique(AttrFactory);
   PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
+
+  if (getLangOpts().ExperimentalTransformPragma) {
+TransformHandler = std::make_unique();
+PP.AddPragmaHandler("clang", TransformHandler.get());
+  }
 }
 
 void Parser::resetPragmaHandlers() {
@@ -487,6 +498,11 @@
 
   PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
   AttributePragmaHandler.reset();
+
+  if (getLangOpts().ExperimentalTransformPragma) {
+PP.RemovePragmaHandler("clang", TransformHandler.get());
+TransformHandler.reset();
+  }
 }
 
 /// Handle the annotation token produced for #pragma unused(...)
@@ -3008,6 +3024,71 @@
   /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
 }
 
+/// Handle
+///   #pragma clang transform ...
+void PragmaTransformHandler::HandlePragma(Preprocessor ,
+  PragmaIntroducer Introducer,
+  Token ) {
+  // "clang" token is not passed
+  // "transform" is FirstTok
+  // Everything up until tok::eod (or tok::eof) is wrapped between
+  // tok::annot_pragma_transform and tok::annot_pragma_transform_end, and
+  // pushed-back into the token stream. The tok::eod/eof is consumed as well:
+  //
+  // Token stream before:
+  //   FirstTok:"transform" |  [clauses..] eod   ...
+  //
+  // Token stream after :
+  //"transform"[clauses..] eod | ...
+  // After pushing the annotation tokens:
+  //
+  // | annot_pragma_transform  [clauses..] annot_pragma_transform_end ...
+  //
+  // The symbol | is before the next token returned by PP.Lex()
+  SmallVector PragmaToks;
+
+  Token StartTok;
+  StartTok.startToken();
+  StartTok.setKind(tok::annot_pragma_transform);
+  StartTok.setLocation(FirstTok.getLocation());
+  PragmaToks.push_back(StartTok);
+
+  SourceLocation EodLoc = FirstTok.getLocation();
+  while (true) {
+Token Tok;
+PP.Lex(Tok);
+
+// TODO: Handle nested pragmas as in r325369.
+assert(!Tok.isAnnotation());
+assert(Tok.isNot(tok::annot_pragma_transform));
+assert(Tok.isNot(tok::annot_pragma_transform_end));
+assert(Tok.isNot(tok::annot_pragma_openmp));
+assert(Tok.isNot(tok::annot_pragma_openmp_end));
+assert(Tok.isNot(tok::annot_pragma_loop_hint));
+
+if (Tok.is(tok::eod) || Tok.is(tok::eof)) {
+  EodLoc = Tok.getLocation();
+  break;
+}
+
+PragmaToks.push_back(Tok);
+  }
+
+  Token EndTok;
+  EndTok.startToken();
+  EndTok.setKind(tok::annot_pragma_transform_end);
+  EndTok.setLocation(EodLoc);
+  PragmaToks.push_back(EndTok);
+
+  // Copy tokens for the preprocessor to own and free.
+  auto Toks = std::make_unique(PragmaToks.size());
+  std::copy(PragmaToks.begin(), PragmaToks.end(), Toks.get());
+
+  // Handle in parser
+  PP.EnterTokenStream(std::move(Toks), PragmaToks.size(),
+  /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
+}
+
 /// Handle the Microsoft \#pragma intrinsic extension.
 ///
 /// The syntax is:
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -3227,6 +3227,11 @@
 
   Opts.CompleteMemberPointers = 

[PATCH] D69088: [Lex] #pragma clang transform

2019-11-01 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur updated this revision to Diff 227550.
Meinersbur added a comment.

- Use PRAGMA_ANNOTATION
- Monorepo layout


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088

Files:
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParsePragma.cpp

Index: clang/lib/Parse/ParsePragma.cpp
===
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -225,6 +225,12 @@
 Token ) override;
 };
 
+struct PragmaTransformHandler : public PragmaHandler {
+  PragmaTransformHandler() : PragmaHandler("transform") {}
+  void HandlePragma(Preprocessor , PragmaIntroducer Introducer,
+Token ) override;
+};
+
 struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
   PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
 };
@@ -376,6 +382,9 @@
   std::make_unique("nounroll_and_jam");
   PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get());
 
+  TransformHandler = std::make_unique();
+  PP.AddPragmaHandler("clang", TransformHandler.get());
+
   FPHandler = std::make_unique();
   PP.AddPragmaHandler("clang", FPHandler.get());
 
@@ -482,6 +491,9 @@
   PP.RemovePragmaHandler(NoUnrollAndJamHintHandler.get());
   NoUnrollAndJamHintHandler.reset();
 
+  PP.RemovePragmaHandler("clang", TransformHandler.get());
+  TransformHandler.reset();
+
   PP.RemovePragmaHandler("clang", FPHandler.get());
   FPHandler.reset();
 
@@ -3008,6 +3020,71 @@
   /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
 }
 
+/// Handle
+///   #pragma clang transform ...
+void PragmaTransformHandler::HandlePragma(Preprocessor ,
+  PragmaIntroducer Introducer,
+  Token ) {
+  // "clang" token is not passed
+  // "transform" is FirstTok
+  // Everything up until tok::eod (or tok::eof) is wrapped between
+  // tok::annot_pragma_transform and tok::annot_pragma_transform_end, and
+  // pushed-back into the token stream. The tok::eod/eof is consumed as well:
+  //
+  // Token stream before:
+  //   FirstTok:"transform" |  [clauses..] eod   ...
+  //
+  // Token stream after :
+  //"transform"[clauses..] eod | ...
+  // After pushing the annotation tokens:
+  //
+  // | annot_pragma_transform  [clauses..] annot_pragma_transform_end ...
+  //
+  // The symbol | is before the next token returned by PP.Lex()
+  SmallVector PragmaToks;
+
+  Token StartTok;
+  StartTok.startToken();
+  StartTok.setKind(tok::annot_pragma_transform);
+  StartTok.setLocation(FirstTok.getLocation());
+  PragmaToks.push_back(StartTok);
+
+  SourceLocation EodLoc = FirstTok.getLocation();
+  while (true) {
+Token Tok;
+PP.Lex(Tok);
+
+// TODO: Handle nested pragmas as in r325369.
+assert(!Tok.isAnnotation());
+assert(Tok.isNot(tok::annot_pragma_transform));
+assert(Tok.isNot(tok::annot_pragma_transform_end));
+assert(Tok.isNot(tok::annot_pragma_openmp));
+assert(Tok.isNot(tok::annot_pragma_openmp_end));
+assert(Tok.isNot(tok::annot_pragma_loop_hint));
+
+if (Tok.is(tok::eod) || Tok.is(tok::eof)) {
+  EodLoc = Tok.getLocation();
+  break;
+}
+
+PragmaToks.push_back(Tok);
+  }
+
+  Token EndTok;
+  EndTok.startToken();
+  EndTok.setKind(tok::annot_pragma_transform_end);
+  EndTok.setLocation(EodLoc);
+  PragmaToks.push_back(EndTok);
+
+  // Copy tokens for the preprocessor to own and free.
+  auto Toks = std::make_unique(PragmaToks.size());
+  std::copy(PragmaToks.begin(), PragmaToks.end(), Toks.get());
+
+  // Handle in parser
+  PP.EnterTokenStream(std::move(Toks), PragmaToks.size(),
+  /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
+}
+
 /// Handle the Microsoft \#pragma intrinsic extension.
 ///
 /// The syntax is:
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -195,6 +195,7 @@
   std::unique_ptr NoUnrollHintHandler;
   std::unique_ptr UnrollAndJamHintHandler;
   std::unique_ptr NoUnrollAndJamHintHandler;
+  std::unique_ptr TransformHandler;
   std::unique_ptr FPHandler;
   std::unique_ptr STDCFENVHandler;
   std::unique_ptr STDCCXLIMITHandler;
Index: clang/include/clang/Basic/TokenKinds.def
===
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -830,6 +830,11 @@
 PRAGMA_ANNOTATION(pragma_openmp)
 PRAGMA_ANNOTATION(pragma_openmp_end)
 
+// Annotations for code transformation pragmas
+// #pragma clang transform ...
+PRAGMA_ANNOTATION(pragma_transform)
+PRAGMA_ANNOTATION(pragma_transform_end)
+
 // Annotations for loop pragma directives #pragma clang loop ...
 // 

[PATCH] D69088: [Lex] #pragma clang transform

2019-10-18 Thread Hideki Saito via Phabricator via cfe-commits
hsaito added a comment.

In D69088#1715210 , @Meinersbur wrote:

> I'd rather just enable them with a command-line switch, such as 
> `-fexperimental-transform`.


This direction works for me. `-fexperimental-transform-pragma` might be better, 
though.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-18 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1715038 , @hsaito wrote:

> If there is a precedence, just follow that. Else, how to spell an 
> experimental clang pragma would be a good discussion topic by itself. If I 
> need to provide a discussion starter, I'd say how about 
> transform_experimental instead of transform. All I ask is somehow make it 
> easier for programmers to know it is experimental so that they won't use it 
> w/o first reading about the current state of support. I don't have a strong 
> opinion about how to do so.


The precedences I have found are `-fexperimental-pass-manager`, 
`-fexperimental-isel`, `std::experimental` and `clang-cl /openmp:experimental`, 
Modules  and a 
couple of features only mentioning "experimental" in their commit log.

I dislike changing the syntax syntax as it means that we will at one point 
break already written code or have to maintain two spellings. I'd rather just 
enable them with a command-line switch, such as `-fexperimental-transform`.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-18 Thread Hideki Saito via Phabricator via cfe-commits
hsaito added a comment.

In D69088#1714575 , @Meinersbur wrote:

> In D69088#1714020 , @hsaito wrote:
>
> > Personally, I like the intent. I don't foresee a clear (enough) path to get 
> > there. This leads to hesitation of adding a new non-experimental pragma and 
> > present it to programmers. If you call it experimental, it's easier for me 
> > to swallow.
>
>
> Is there anything more to do than mentioning as being it experimental in the 
> (no-patch-available-yet) docs?


If there is a precedence, just follow that. Else, how to spell an experimental 
clang pragma would be a good discussion topic by itself. If I need to provide a 
discussion starter, I'd say how about transform_experimental instead of 
transform. All I ask is somehow make it easier for programmers to know it is 
experimental so that they won't use it w/o first reading about the current 
state of support. I don't have a strong opinion about how to do so.

If others with stakes in loop optimizations foresee a clear enough path to get 
there, I won't insist this being experimental, but I would like to understand 
the path.

Thanks,
Hideki


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-18 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1713623 , @hsaito wrote:

> @Meinersbur, if I remember correctly, there was an RFC discussion on this 
> topic, right? If yes, would you post the pointer to that? I need a refresher 
> on what has been discussed/settled in the past.


My publications on this topic would also be useful here, available on arXiv. 
Here is an overview, also including previous discussions:

Loop optimization directives:

- A Proposal for Loop-Transformation Pragmas  
(IWOMP'19)
- User-Directed Loop-Transformations in Clang 
 (LLVM-HPC'18)
- Design and Use of Loop-Transformation Pragmas 
 (IWOMP'19)
- RFC: Extending #pragma clang loop 
 (cfe-dev)
- Prototype implementation using `#pragma clang loop` and attributes 
 (GitHub)

Loop attributes metadata:

- RFC: Extending loop metadata 
 (llvm-dev)
- D57978 : Metadata for follow-up 
transformations

Applying loop optimizations:

- Loop Optimization Framework  (LCPC'18)
- Loop Transformations in LLVM  (LLVM 
DevMtg'18)
- Prototype implementation for applying transformations using Polly 
 (GitHub)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-18 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1714020 , @hsaito wrote:

> Personally, I like the intent. I don't foresee a clear (enough) path to get 
> there. This leads to hesitation of adding a new non-experimental pragma and 
> present it to programmers. If you call it experimental, it's easier for me to 
> swallow.


Is there anything more to do than mentioning as being it experimental in the 
(no-patch-available-yet) docs?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Hideki Saito via Phabricator via cfe-commits
hsaito added a comment.

In D69088#1714019 , @Meinersbur wrote:

> In D69088#1713933 , @hsaito wrote:
>
> > Have we established general consensus for the desire to have the flexible 
> > enough loop optimization pass ordering to accomplish the outcome of the new 
> > directive, and shared vision for the path to get there? If we are making 
> > this a general clang directive, I'd like to see the vision to get there w/o 
> > depending on polly. If this is already discussed and settled, pointer to 
> > that is appreciated so that I can learn.
>
>
> Response to the RFCs was meager. However, I got positive feedback at various 
> conferences, including last year's DevMtg where my version for loop 
> transformations was a technical talk .


Personally, I like the intent. I don't foresee a clear (enough) path to get 
there. This leads to hesitation of adding a new non-experimental pragma and 
present it to programmers. If you call it experimental, it's easier for me to 
swallow.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1713933 , @hsaito wrote:

> Have we established general consensus for the desire to have the flexible 
> enough loop optimization pass ordering to accomplish the outcome of the new 
> directive, and shared vision for the path to get there? If we are making this 
> a general clang directive, I'd like to see the vision to get there w/o 
> depending on polly. If this is already discussed and settled, pointer to that 
> is appreciated so that I can learn.


Response to the RFCs was meager. However, I got positive feedback at various 
conferences, including last year's DevMtg where my version for loop 
transformations was a technical talk .


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1713915 , @ABataev wrote:

> Just do not allow this form with respect_order clause.


What exactly would be the rules what is allowed and what isn't?

We can just not allow not mixing `#pragma clang loop` and `#pragma clang 
transform`.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Hideki Saito via Phabricator via cfe-commits
hsaito added a comment.

Have we established general consensus for the desire to have the flexible 
enough loop optimization pass ordering to accomplish the outcome of the new 
directive, and shared vision for the path to get there? If we are making this a 
general clang directive, I'd like to see the vision to get there w/o depending 
on polly. If this is already discussed and settled, pointer to that is 
appreciated so that I can learn.

Thanks,
Hideki


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Alexey Bataev via Phabricator via cfe-commits
ABataev added a comment.

In D69088#1713901 , @Meinersbur wrote:

> In D69088#1713831 , @tyler.nowicki 
> wrote:
>
> > That approach would avoid the inevitable conflicts of having both loop and 
> > transform pragmas on the same loop.
>
>
> I fear it will give us far worse ambiguities. Consider:
>
>   #pragma clang loop unroll(enable) respect_order unrollandjam(enable) 
> unroll_count(4) 
>
>
> How often does it unroll?


Just do not allow this form with respect_order clause.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1713831 , @tyler.nowicki 
wrote:

> That approach would avoid the inevitable conflicts of having both loop and 
> transform pragmas on the same loop.


I fear it will give us far worse ambiguities. Consider:

  #pragma clang loop unroll(enable) respect_order unrollandjam(enable) 
unroll_count(4) 

How often does it unroll?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1713831 , @tyler.nowicki 
wrote:

> In D69088#1713648 , @Meinersbur 
> wrote:
>
> > In D69088#1713623 , @hsaito wrote:
> >
> > > @Meinersbur, if I remember correctly, there was an RFC discussion on this 
> > > topic, right? If yes, would you post the pointer to that? I need a 
> > > refresher on what has been discussed/settled in the past.
> >
> >
> > https://lists.llvm.org/pipermail/cfe-dev/2018-May/058141.html
>
>
> Sorry if this is answered in the patches but what happens if a loop has both 
> #pragma clang loop and transform defined before it? I guess it probably 
> shouldn't work.


Yes, the plan was to make it an hard error. I unfortunately forgot to add that 
to D69091 , thanks for reminding me. In the 
current implementation the #pragma clang loop would be applied first, but it's 
not intentional.

> Perhaps instead you could create a new option to indicate that the order 
> should be respected.
> 
> #pragma clang loop respect_order  <- optionally with (true) or (false)
> 
> That approach would avoid the inevitable conflicts of having both loop and 
> transform pragmas on the same loop.

There is also a syntax difference:

  #pragma clang loop vectorize_width(4)

compared to

  #pragma clang transform vectorize width(4)

which in a similar form is also how it is done in OpenMP:

  #pragma omp simd simdlen(4)

IMHO, a `respect_order` option is problematic, not only because it influences 
parsing while being parsed. It also makes the preferable behavior clunkier to 
use.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Tyler Nowicki via Phabricator via cfe-commits
tyler.nowicki added a comment.

In D69088#1713648 , @Meinersbur wrote:

> In D69088#1713623 , @hsaito wrote:
>
> > @Meinersbur, if I remember correctly, there was an RFC discussion on this 
> > topic, right? If yes, would you post the pointer to that? I need a 
> > refresher on what has been discussed/settled in the past.
>
>
> https://lists.llvm.org/pipermail/cfe-dev/2018-May/058141.html


Sorry if this is answered in the patches but what happens if a loop has both 
#pragma clang loop and transform defined before it? I guess it probably 
shouldn't work.

Perhaps instead you could create a new option to indicate that the order should 
be respected.

#pragma clang loop respect_order  <- optionally with (true) or (false)

That approach would avoid the inevitable conflicts of having both loop and 
transform pragmas on the same loop.

(Sorry if you received this twice)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Tyler Nowicki via cfe-commits
Sorry if this is answered in the patches but what happens if a loop has
both #pragma clang loop and transform defined before it? I guess it
probably shouldn't work.

Perhaps instead you could create a new option to indicate that the order
should be respected.

#pragma clang loop respect_order  <- optionally with (true) or (false)

That approach would avoid the inevitable conflicts of having both loop and
transform pragmas on the same loop.


On Thu, Oct 17, 2019 at 5:27 PM Michael Kruse via Phabricator <
revi...@reviews.llvm.org> wrote:

> Meinersbur added a comment.
>
> In D69088#1713623 , @hsaito
> wrote:
>
> > @Meinersbur, if I remember correctly, there was an RFC discussion on
> this topic, right? If yes, would you post the pointer to that? I need a
> refresher on what has been discussed/settled in the past.
>
>
> https://lists.llvm.org/pipermail/cfe-dev/2018-May/058141.html
>
>
> Repository:
>   rC Clang
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D69088/new/
>
> https://reviews.llvm.org/D69088
>
>
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1713623 , @hsaito wrote:

> @Meinersbur, if I remember correctly, there was an RFC discussion on this 
> topic, right? If yes, would you post the pointer to that? I need a refresher 
> on what has been discussed/settled in the past.


https://lists.llvm.org/pipermail/cfe-dev/2018-May/058141.html


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur added a comment.

In D69088#1713147 , @ABataev wrote:

> Why not try to improve the existing #pragma clang loop rather than add a new 
> pragma with almost the same behavior?


The behavior and syntax is different. #pragma clang loop ignores the order, i.e.

  #pragma clang loop unroll(enable)
  #pragma clang loop distribute(enable)

and

  #pragma clang loop distribute(enable)
  #pragma clang loop unroll(enable)

and

  #pragma clang loop unroll(enable) distribute(enable)

are the same. Changing that would be a breaking change.

Syntactically, every option is it's own transformation, e.g.

  #pragma clang loop unroll(enable) distribute(enable) unroll_count(2)

could be interpreted as 3 transformations (LoopUnroll even exists twice in the 
pass pipeline). I prefer OpenMP's directive-with-clauses syntax, which we need 
to implement anyway for the OpenMP loop transformations.

In the future, I would also like to add non-loop transformation, such that the 
`loop` namespace l


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Hideki Saito via Phabricator via cfe-commits
hsaito added a comment.

@Meinersbur, if I remember correctly, there was an RFC discussion on this 
topic, right? If yes, would you post the pointer to that? I need a refresher on 
what has been discussed/settled in the past.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Alexey Bataev via Phabricator via cfe-commits
ABataev added a comment.

Why not try to improve the existing #pragma clang loop rather than add a new 
pragma with almost the same behavior?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69088/new/

https://reviews.llvm.org/D69088



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69088: [Lex] #pragma clang transform

2019-10-17 Thread Michael Kruse via Phabricator via cfe-commits
Meinersbur created this revision.
Meinersbur added reviewers: hfinkel, kbarton, SjoerdMeijer, aaron.ballman, 
ABataev, fhahn, hsaito, hans, greened, dmgreen, reames, Ayal, asavonic, rtrieu, 
dorit, rsmith, tyler.nowicki.
Herald added a reviewer: bollu.
Herald added a reviewer: jdoerfert.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is a series of patches that adds a new pragma for loop transformations. I 
hope for feedback before the LLVM DevMtg where this will be the topic of my 
talk . The talk will 
give an overview about how to add such an extension that touches all of clang's 
layers and would hate to give wrong advice.

The syntax is:

  #pragma clang transform distribute
  #pragma clang transform unroll/unrollandjam [full/partial(n)]
  #pragma clang transform vectorize [width(n)]
  #pragma clang transform interleave [factor(n)]

The selection is currently limited to the passes LLVM currently supports. I am 
working on more transformations that currently are only picked-up by Polly. The 
biggest difference to #pragma clang loop it allows to specify in which order 
the transformations are applied, which is ignored by clang's current LoopHint 
attribute. It is also designed a bit more carefully, e.g. vectorize and 
interleave are unambiguously different transformations and no question whether 
setting an optimization option also enables the transformations.

In the longer term, we plan to add more features such as:

- More transformations (tiling, fusion, interchange, array packing, reversal, 
wavefronting, peeling, splitting, space-filling curves, unswitching, 
collapsing, strip/strip-mining, blocking, )
- More options
- Assigning identifiers to code such that they can be referenced by 
transformations. (e.g. tile a loop nest, vectorize the second-to-innermost loop 
and parallelize the outermost).
- Non-loop transformations (code motion, versioning, ...)
- OpenMP compatibility

Regarding the latter item, we are adding loop transformation to the OpenMP 
specification. The next technical report presented at SC'19 will feature a 
tiling transformation. As such, this patch is inspired by clang's OpenMP 
implementation to make an integration later easier. It's not OpenMP though, in 
that for instance the OpenMP construct will apply tiling regardless of semantic 
equivalence while `#pragma clang transform` takes the classical compiler-hint 
approach in that it (by default) still does a correctness check, only 
influencing the profitability heuristic.

A previous prototype that was closer to how `#pragma clang loop` is implemented 
using attributes instead of adding an additional kind of AST nodes. This showed 
its limitations in that it did not allow all use-cases (such as #pragma without 
a following statement) and its argument format can only store an array of 
in-source identifiers and expressions. The prototype also used the `'#pragma 
clang loop` syntax, but it proved difficult to disambiguate whether the 
transformations are ordered or not.

The patch is split into multiple reviews:

- [this patch] The lexer part adds annotation begin- and end-tokens to the 
token stream, as OpenMP does.
- The parser part parses the tokens between the annotation tokens and calls 
`ActOn...` methods of Sema which are empty in this patch.
- The sema part also adds the AST nodes kinds: the Stmt representing the 
#pragma, the clauses and `Transform`. The latter represents the semantic 
analysis result similar to an ImplicitCast. Moreover, the AnalysisTransform 
component constructs a loop nest tree to which transformations are applied to 
such that Sema can warn about inconsistencies, e.g. there is no inner or 
ambiguous loops for unrollandjam.
- The codegen part uses the same AnalysisTransform to determine which loop 
metadata nodes to emit.
- Other parts not yet ready for a review: serialization, index, completion, 
libclang, ASTMatcher, tooling

Thanks in advance for the review!


Repository:
  rC Clang

https://reviews.llvm.org/D69088

Files:
  include/clang/Basic/TokenKinds.def
  include/clang/Parse/Parser.h
  lib/Parse/ParsePragma.cpp

Index: lib/Parse/ParsePragma.cpp
===
--- lib/Parse/ParsePragma.cpp
+++ lib/Parse/ParsePragma.cpp
@@ -225,6 +225,12 @@
 Token ) override;
 };
 
+struct PragmaTransformHandler : public PragmaHandler {
+  PragmaTransformHandler() : PragmaHandler("transform") {}
+  void HandlePragma(Preprocessor , PragmaIntroducer Introducer,
+Token ) override;
+};
+
 struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
   PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
 };
@@ -376,6 +382,9 @@
   std::make_unique("nounroll_and_jam");
   PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get());
 
+  TransformHandler = std::make_unique();
+  PP.AddPragmaHandler("clang",