From 9dca2f877e8f755866325d149e51dea5dbf870d3 Mon Sep 17 00:00:00 2001
From: Philippe Virouleau <philippe.virouleau@imag.fr>
Date: Wed, 6 Apr 2016 11:04:44 +0200
Subject: [PATCH] Added Sema for Operational Intensity

---
 include/clang/AST/OpenMPClause.h        | 56 +++++++++++++++++++++++++
 include/clang/AST/RecursiveASTVisitor.h |  7 ++++
 include/clang/Basic/OpenMPKinds.def     |  2 +
 include/clang/Sema/Sema.h               |  7 +++-
 lib/AST/StmtPrinter.cpp                 |  6 +++
 lib/AST/StmtProfile.cpp                 |  3 ++
 lib/Basic/OpenMPKinds.cpp               |  2 +
 lib/CodeGen/CGStmtOpenMP.cpp            |  4 +-
 lib/Parse/ParseOpenMP.cpp               |  1 +
 lib/Sema/SemaOpenMP.cpp                 | 21 ++++++++++
 lib/Sema/TreeTransform.h                | 23 ++++++++++
 lib/Serialization/ASTReaderStmt.cpp     |  8 ++++
 lib/Serialization/ASTWriterStmt.cpp     |  5 +++
 tools/libclang/CIndex.cpp               |  4 ++
 14 files changed, 146 insertions(+), 3 deletions(-)

diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 2a20fdb854e..3e05e9e2498 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -3685,6 +3685,62 @@ public:
   child_range children() { return child_range(&Priority, &Priority + 1); }
 };
 
+/// \brief This represents 'oi' (Operational Intensity) clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp task oi(1.5)
+/// \endcode
+/// In this example directive '#pragma omp teams' has clause 'priority' with
+/// single expression 'n'.
+///
+class OMPOperationalIntensityClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief OI number.
+  Stmt *OperationalIntensity;
+  /// \brief Set the OI number.
+  ///
+  /// \param E Operational Intensity number.
+  ///
+  void setOperationalIntensity(Expr *E) { OperationalIntensity = E; }
+
+public:
+  /// \brief Build 'oi' clause.
+  ///
+  /// \param E Expression associated with this clause.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPOperationalIntensityClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
+                                SourceLocation EndLoc)
+      : OMPClause(OMPC_oi, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        OperationalIntensity(E) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPOperationalIntensityClause()
+      : OMPClause(OMPC_oi, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), OperationalIntensity(nullptr) {}
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  /// \brief Return Operational Intensity number.
+  Expr *getOperationalIntensity() { return cast<Expr>(OperationalIntensity); }
+  /// \brief Return Operational Intensity number.
+  Expr *getOperationalIntensity() const { return cast<Expr>(OperationalIntensity); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_oi;
+  }
+
+  child_range children() { return child_range(&OperationalIntensity,
+                                              &OperationalIntensity + 1); }
+};
+
 /// \brief This represents 'affinity' clause in the '#pragma omp ...'
 /// directive.
 ///
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 99a08f67d79..3e31829c8ae 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -2915,6 +2915,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
   return true;
 }
 
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOperationalIntensityClause(
+    OMPOperationalIntensityClause *C) {
+  TRY_TO(TraverseStmt(C->getOperationalIntensity()));
+  return true;
+}
+
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause(
     OMPAffinityClause *C) {
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 6894e7cf0c4..124837e24a3 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -223,6 +223,7 @@ OPENMP_CLAUSE(map, OMPMapClause)
 OPENMP_CLAUSE(num_teams, OMPNumTeamsClause)
 OPENMP_CLAUSE(thread_limit, OMPThreadLimitClause)
 OPENMP_CLAUSE(priority, OMPPriorityClause)
+OPENMP_CLAUSE(oi, OMPOperationalIntensityClause)
 OPENMP_CLAUSE(grainsize, OMPGrainsizeClause)
 OPENMP_CLAUSE(nogroup, OMPNogroupClause)
 OPENMP_CLAUSE(num_tasks, OMPNumTasksClause)
@@ -404,6 +405,7 @@ OPENMP_TASK_CLAUSE(untied)
 OPENMP_TASK_CLAUSE(mergeable)
 OPENMP_TASK_CLAUSE(depend)
 OPENMP_TASK_CLAUSE(priority)
+OPENMP_TASK_CLAUSE(oi)
 OPENMP_TASK_CLAUSE(affinity)
 
 // Clauses allowed for OpenMP directive 'atomic'.
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index e713067733a..5342d35993f 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -8512,7 +8512,12 @@ public:
                                           SourceLocation StartLoc,
                                           SourceLocation LParenLoc,
                                           SourceLocation EndLoc);
-  /// \brief Called on well-formed 'priority' clause.
+  /// \brief Called on well-formed 'oi' clause.
+  OMPClause *ActOnOpenMPOperationalIntensityClause(Expr *OperationalIntensity,
+                                                   SourceLocation StartLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation EndLoc);
+  /// \brief Called on well-formed 'affinity' clause.
   OMPClause *ActOnOpenMPAffinityClause(Expr *Affinity, SourceLocation StartLoc,
                                        SourceLocation LParenLoc,
                                        SourceLocation EndLoc);
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 6057b227e23..3e5a83f7d30 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -753,6 +753,12 @@ void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
   OS << ")";
 }
 
+void OMPClausePrinter::VisitOMPOperationalIntensityClause(OMPOperationalIntensityClause *Node) {
+  OS << "oi(";
+  Node->getOperationalIntensity()->printPretty(OS, nullptr, Policy, 0);
+  OS << ")";
+}
+
 void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
   OS << "affinity(";
   Node->getAffinity()->printPretty(OS, nullptr, Policy, 0);
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 8a3daa128dd..d80469de1b4 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -513,6 +513,9 @@ void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) {
   if (C->getPriority())
     Profiler->VisitStmt(C->getPriority());
 }
+void OMPClauseProfiler::VisitOMPOperationalIntensityClause(const OMPOperationalIntensityClause *C) {
+  Profiler->VisitStmt(C->getOperationalIntensity());
+}
 void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) {
   Profiler->VisitStmt(C->getAffinity());
 }
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index 3bf9f113c89..be6c95e7626 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -162,6 +162,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_nogroup:
@@ -312,6 +313,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_nogroup:
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 678de8369aa..07ee10c6e18 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1234,8 +1234,6 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
   CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
 
   if (const auto *InitClause = S.getSingleClause<OMPInitClause>()) {
-    llvm::errs() << "Got an init : " <<
-      getOpenMPSimpleClauseTypeName(OMPC_init, InitClause->getInitKind()) << "\n";
     CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
     CGF.CGM.getOpenMPRuntime().emitBeginInitClause(
         CGF, InitClause->getInitKind());
@@ -1245,6 +1243,7 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
                                               CapturedVars, IfCond);
 
   if (const auto *InitClause = S.getSingleClause<OMPInitClause>()) {
+    (void)InitClause;
     CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
     CGF.CGM.getOpenMPRuntime().emitEndInitClause(CGF);
   }
@@ -3249,6 +3248,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_nogroup:
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index f81938486ba..1eb25cc7210 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -1085,6 +1085,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_num_tasks:
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 315d830c684..ee1bfcab14c 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -7243,6 +7243,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
   case OMPC_priority:
     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_oi:
+    Res = ActOnOpenMPOperationalIntensityClause(Expr, StartLoc, LParenLoc, EndLoc);
+    break;
   case OMPC_affinity:
     Res = ActOnOpenMPAffinityClause(Expr, StartLoc, LParenLoc, EndLoc);
     break;
@@ -7573,6 +7576,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_nogroup:
@@ -7748,6 +7752,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_nogroup:
@@ -7938,6 +7943,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_num_tasks:
@@ -8101,6 +8107,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
   case OMPC_num_teams:
   case OMPC_thread_limit:
   case OMPC_priority:
+  case OMPC_oi:
   case OMPC_affinity:
   case OMPC_grainsize:
   case OMPC_nogroup:
@@ -11333,6 +11340,20 @@ OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
   return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
 }
 
+OMPClause *Sema::ActOnOpenMPOperationalIntensityClause(Expr *OperationalIntensity,
+                                                       SourceLocation StartLoc,
+                                                       SourceLocation LParenLoc,
+                                                       SourceLocation EndLoc) {
+  Expr *ValExpr = OperationalIntensity;
+
+  // FIXME The operational intensity is a float, check that
+  //if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_oi,
+                                 //[>StrictlyPositive=<]false))
+    //return nullptr;
+
+  return new (Context) OMPOperationalIntensityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+}
+
 OMPClause *Sema::ActOnOpenMPAffinityClause(Expr *Affinity,
                                            SourceLocation StartLoc,
                                            SourceLocation LParenLoc,
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 47f856cd032..990c669ee3c 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1726,6 +1726,19 @@ public:
                                                EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'oi' clause.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPOperationalIntensityClause(Expr *OperationalIntensity,
+                                                  SourceLocation StartLoc,
+                                                  SourceLocation LParenLoc,
+                                                  SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPOperationalIntensityClause(OperationalIntensity,
+                                                           StartLoc, LParenLoc,
+                                                           EndLoc);
+  }
+
   /// \brief Build a new OpenMP 'affinity' clause.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -8097,6 +8110,16 @@ TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
       E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPOperationalIntensityClause(OMPOperationalIntensityClause *C) {
+  ExprResult E = getDerived().TransformExpr(C->getOperationalIntensity());
+  if (E.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPOperationalIntensityClause(
+      E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
 template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 9778f75251f..65e01131ec0 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1902,6 +1902,9 @@ OMPClause *OMPClauseReader::readClause() {
   case OMPC_priority:
     C = new (Context) OMPPriorityClause();
     break;
+  case OMPC_oi:
+    C = new (Context) OMPOperationalIntensityClause();
+    break;
   case OMPC_affinity:
     C = new (Context) OMPAffinityClause();
     break;
@@ -2345,6 +2348,11 @@ void OMPClauseReader::VisitOMPPriorityClause(OMPPriorityClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
 }
 
+void OMPClauseReader::VisitOMPOperationalIntensityClause(OMPOperationalIntensityClause *C) {
+  C->setOperationalIntensity(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
 void OMPClauseReader::VisitOMPAffinityClause(OMPAffinityClause *C) {
   C->setAffinity(Reader->Reader.ReadSubExpr());
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index fa2eeeea301..260842ef7d8 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -2083,6 +2083,11 @@ void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) {
   Record.AddSourceLocation(C->getLParenLoc());
 }
 
+void OMPClauseWriter::VisitOMPOperationalIntensityClause(OMPOperationalIntensityClause *C) {
+  Record.AddStmt(C->getOperationalIntensity());
+  Record.AddSourceLocation(C->getLParenLoc());
+}
+
 void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) {
   Record.AddStmt(C->getAffinity());
   Record.AddSourceLocation(C->getLParenLoc());
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 654fab21298..00319bfd836 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2139,6 +2139,10 @@ void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
   Visitor->AddStmt(C->getPriority());
 }
 
+void OMPClauseEnqueue::VisitOMPOperationalIntensityClause(const OMPOperationalIntensityClause *C) {
+  Visitor->AddStmt(C->getOperationalIntensity());
+}
+
 void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
   Visitor->AddStmt(C->getAffinity());
 }
-- 
GitLab