kito-cheng updated this revision to Diff 349785.
kito-cheng added a comment.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Reupload.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103228

Files:
  clang/include/clang/Basic/CMakeLists.txt
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/CMakeLists.txt
  clang/lib/Sema/SemaRISCV.cpp
  clang/utils/TableGen/RISCVVEmitter.cpp
  clang/utils/TableGen/TableGen.cpp
  clang/utils/TableGen/TableGenBackends.h
  llvm/docs/CommandGuide/tblgen.rst

Index: llvm/docs/CommandGuide/tblgen.rst
===================================================================
--- llvm/docs/CommandGuide/tblgen.rst
+++ llvm/docs/CommandGuide/tblgen.rst
@@ -348,6 +348,14 @@
 
   Generate ``riscv_vector_builtin_cg.inc`` for Clang.
 
+.. option:: -gen-riscv-vector-intrinsic-info
+
+  Generate ``riscv_vector_intrinsic_info.inc`` for Clang.
+
+.. option:: -gen-riscv-vector-intrinsic-overload-info
+
+  Generate ``riscv_vector_intrinsic_overload_info.inc`` for Clang.
+
 .. option:: -gen-attr-docs
 
   Generate attribute documentation.
Index: clang/utils/TableGen/TableGenBackends.h
===================================================================
--- clang/utils/TableGen/TableGenBackends.h
+++ clang/utils/TableGen/TableGenBackends.h
@@ -109,6 +109,9 @@
 void EmitRVVHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
 void EmitRVVBuiltins(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
 void EmitRVVBuiltinCG(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitRVVIntrinsicInfo(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitRVVIntrinsicOverloadInfo(llvm::RecordKeeper &Records,
+                                  llvm::raw_ostream &OS);
 
 void EmitCdeHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
 void EmitCdeBuiltinDef(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
Index: clang/utils/TableGen/TableGen.cpp
===================================================================
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -86,6 +86,8 @@
   GenRISCVVectorHeader,
   GenRISCVVectorBuiltins,
   GenRISCVVectorBuiltinCG,
+  GenRISCVVectorIntrinsicInfo,
+  GenRISCVVectorIntrinsicOverloadInfo,
   GenAttrDocs,
   GenDiagDocs,
   GenOptDocs,
@@ -237,6 +239,13 @@
                    "Generate riscv_vector_builtins.inc for clang"),
         clEnumValN(GenRISCVVectorBuiltinCG, "gen-riscv-vector-builtin-codegen",
                    "Generate riscv_vector_builtin_cg.inc for clang"),
+        clEnumValN(GenRISCVVectorIntrinsicInfo,
+                   "gen-riscv-vector-intrinsic-info",
+                   "Generate riscv_vector_intrinsic_info.inc for clang."),
+        clEnumValN(
+            GenRISCVVectorIntrinsicOverloadInfo,
+            "gen-riscv-vector-intrinsic-overload-info",
+            "Generate riscv_vector_intrinsic_overload_info.inc for clang."),
         clEnumValN(GenAttrDocs, "gen-attr-docs",
                    "Generate attribute documentation"),
         clEnumValN(GenDiagDocs, "gen-diag-docs",
@@ -446,6 +455,12 @@
   case GenRISCVVectorBuiltinCG:
     EmitRVVBuiltinCG(Records, OS);
     break;
+  case GenRISCVVectorIntrinsicInfo:
+    EmitRVVIntrinsicInfo(Records, OS);
+    break;
+  case GenRISCVVectorIntrinsicOverloadInfo:
+    EmitRVVIntrinsicOverloadInfo(Records, OS);
+    break;
   case GenAttrDocs:
     EmitClangAttrDocs(Records, OS);
     break;
Index: clang/utils/TableGen/RISCVVEmitter.cpp
===================================================================
--- clang/utils/TableGen/RISCVVEmitter.cpp
+++ clang/utils/TableGen/RISCVVEmitter.cpp
@@ -194,12 +194,6 @@
   // Emit the code block for switch body in EmitRISCVBuiltinExpr, it should
   // init the RVVIntrinsic ID and IntrinsicTypes.
   void emitCodeGenSwitchBody(raw_ostream &o) const;
-
-  // Emit the macros for mapping C/C++ intrinsic function to builtin functions.
-  void emitIntrinsicMacro(raw_ostream &o) const;
-
-  // Emit the mangled function definition.
-  void emitMangledFuncDef(raw_ostream &o) const;
 };
 
 class RVVEmitter {
@@ -222,6 +216,12 @@
   /// Emit all the information needed to map builtin -> LLVM IR intrinsic.
   void createCodeGen(raw_ostream &o);
 
+  /// Emit all the intrinsic info for `#pragma riscv vector intrinsic`.
+  void createIntrinsicInfo(raw_ostream &o);
+
+  /// Emit all the intrinsic overload info for `#pragma riscv vector intrinsic`.
+  void createIntrinsicOverloadInfo(raw_ostream &o);
+
   std::string getSuffixStr(char Type, int Log2LMUL, StringRef Prototypes);
 
 private:
@@ -235,15 +235,6 @@
                                   ArrayRef<std::string> PrototypeSeq);
   Optional<RVVTypePtr> computeType(BasicType BT, int Log2LMUL, StringRef Proto);
 
-  /// Emit Acrh predecessor definitions and body, assume the element of Defs are
-  /// sorted by extension.
-  void emitArchMacroAndBody(
-      std::vector<std::unique_ptr<RVVIntrinsic>> &Defs, raw_ostream &o,
-      std::function<void(raw_ostream &, const RVVIntrinsic &)>);
-
-  // Emit the architecture preprocessor definitions. Return true when emits
-  // non-empty string.
-  bool emitExtDefStr(uint8_t Extensions, raw_ostream &o);
   // Slice Prototypes string into sub prototype string and process each sub
   // prototype string individually in the Handler.
   void parsePrototypes(StringRef Prototypes,
@@ -836,36 +827,6 @@
   OS << "  break;\n";
 }
 
-void RVVIntrinsic::emitIntrinsicMacro(raw_ostream &OS) const {
-  OS << "#define " << getName() << "(";
-  if (!InputTypes.empty()) {
-    ListSeparator LS;
-    for (unsigned i = 0, e = InputTypes.size(); i != e; ++i)
-      OS << LS << "op" << i;
-  }
-  OS << ") \\\n";
-  OS << "__builtin_rvv_" << getName() << "(";
-  if (!InputTypes.empty()) {
-    ListSeparator LS;
-    for (unsigned i = 0, e = InputTypes.size(); i != e; ++i)
-      OS << LS << "(" << InputTypes[i]->getTypeStr() << ")(op" << i << ")";
-  }
-  OS << ")\n";
-}
-
-void RVVIntrinsic::emitMangledFuncDef(raw_ostream &OS) const {
-  OS << "__attribute__((clang_builtin_alias(";
-  OS << "__builtin_rvv_" << getName() << ")))\n";
-  OS << OutputType->getTypeStr() << " " << getMangledName() << "(";
-  // Emit function arguments
-  if (!InputTypes.empty()) {
-    ListSeparator LS;
-    for (unsigned i = 0; i < InputTypes.size(); ++i)
-      OS << LS << InputTypes[i]->getTypeStr() << " op" << i;
-  }
-  OS << ");\n\n";
-}
-
 //===----------------------------------------------------------------------===//
 // RVVEmitter implementation
 //===----------------------------------------------------------------------===//
@@ -897,6 +858,7 @@
   OS << "#ifdef __cplusplus\n";
   OS << "extern \"C\" {\n";
   OS << "#endif\n\n";
+  OS << "#pragma riscv intrinsic vector\n\n";
 
   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
   createRVVIntrinsics(Defs);
@@ -960,24 +922,8 @@
                      return A->getRISCVExtensions() < B->getRISCVExtensions();
                    });
 
-  // Print intrinsic functions with macro
-  emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) {
-    Inst.emitIntrinsicMacro(OS);
-  });
-
   OS << "#define __riscv_v_intrinsic_overloading 1\n";
 
-  // Print Overloaded APIs
-  OS << "#define __rvv_overloaded static inline "
-        "__attribute__((__always_inline__, __nodebug__, __overloadable__))\n";
-
-  emitArchMacroAndBody(Defs, OS, [](raw_ostream &OS, const RVVIntrinsic &Inst) {
-    if (!Inst.isMask() && !Inst.hasNoMaskedOverloaded())
-      return;
-    OS << "__rvv_overloaded ";
-    Inst.emitMangledFuncDef(OS);
-  });
-
   OS << "\n#ifdef __cplusplus\n";
   OS << "}\n";
   OS << "#endif // __riscv_vector\n";
@@ -1169,41 +1115,46 @@
   return llvm::None;
 }
 
-void RVVEmitter::emitArchMacroAndBody(
-    std::vector<std::unique_ptr<RVVIntrinsic>> &Defs, raw_ostream &OS,
-    std::function<void(raw_ostream &, const RVVIntrinsic &)> PrintBody) {
-  uint8_t PrevExt = (*Defs.begin())->getRISCVExtensions();
-  bool NeedEndif = emitExtDefStr(PrevExt, OS);
-  for (auto &Def : Defs) {
-    uint8_t CurExt = Def->getRISCVExtensions();
-    if (CurExt != PrevExt) {
-      if (NeedEndif)
-        OS << "#endif\n\n";
-      NeedEndif = emitExtDefStr(CurExt, OS);
-      PrevExt = CurExt;
-    }
-    if (Def->hasAutoDef())
-      PrintBody(OS, *Def);
+static void emitFeatureCheckStr(uint8_t Extents, raw_ostream &OS) {
+  if (Extents == RISCVExtension::Basic) {
+    OS << 0;
+    return;
   }
-  if (NeedEndif)
-    OS << "#endif\n\n";
-}
 
-bool RVVEmitter::emitExtDefStr(uint8_t Extents, raw_ostream &OS) {
-  if (Extents == RISCVExtension::Basic)
-    return false;
-  OS << "#if ";
-  ListSeparator LS(" && ");
+  ListSeparator LS("|");
   if (Extents & RISCVExtension::F)
-    OS << LS << "defined(__riscv_f)";
+    OS << LS << "Feature_F";
   if (Extents & RISCVExtension::D)
-    OS << LS << "defined(__riscv_d)";
+    OS << LS << "Feature_D";
   if (Extents & RISCVExtension::Zfh)
-    OS << LS << "defined(__riscv_zfh)";
+    OS << LS << "Feature_ZFH";
   if (Extents & RISCVExtension::Zvamo)
-    OS << LS << "defined(__riscv_zvamo)";
-  OS << "\n";
-  return true;
+    OS << LS << "Feature_ZVAMO";
+}
+
+void RVVEmitter::createIntrinsicInfo(raw_ostream &OS) {
+  std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
+  createRVVIntrinsics(Defs);
+  for (auto &Def : Defs) {
+    OS << "  {\"" << Def->getName() << "\", ";
+    OS << "RISCV::BI__builtin_rvv_" << Def->getName() << ", ";
+    emitFeatureCheckStr(Def->getRISCVExtensions(), OS);
+    OS << "},\n";
+  }
+}
+
+void RVVEmitter::createIntrinsicOverloadInfo(raw_ostream &OS) {
+  std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
+  createRVVIntrinsics(Defs);
+  for (auto &Def : Defs) {
+    if (!Def->isMask() && !Def->hasNoMaskedOverloaded())
+      continue;
+    OS << "  {\"__builtin_rvv_" << Def->getName() << "\", ";
+    OS << "\"" << Def->getMangledName() << "\", ";
+    OS << "RISCV::BI__builtin_rvv_" << Def->getName() << ", ";
+    emitFeatureCheckStr(Def->getRISCVExtensions(), OS);
+    OS << "},\n";
+  }
 }
 
 namespace clang {
@@ -1219,4 +1170,12 @@
   RVVEmitter(Records).createCodeGen(OS);
 }
 
+void EmitRVVIntrinsicInfo(RecordKeeper &Records, raw_ostream &OS) {
+  RVVEmitter(Records).createIntrinsicInfo(OS);
+}
+
+void EmitRVVIntrinsicOverloadInfo(RecordKeeper &Records, raw_ostream &OS) {
+  RVVEmitter(Records).createIntrinsicOverloadInfo(OS);
+}
+
 } // End namespace clang
Index: clang/lib/Sema/SemaRISCV.cpp
===================================================================
--- /dev/null
+++ clang/lib/Sema/SemaRISCV.cpp
@@ -0,0 +1,86 @@
+//===--- SemaRISCV.cpp - Semantic Analysis for RISC-V pragmas -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements semantic analysis for RISC-V pragmas.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Sema/Sema.h"
+using namespace clang;
+
+enum Features {
+  Feature_F = 1 << 0,
+  Feature_D = 1 << 1,
+  Feature_ZFH = 1 << 2,
+  Feature_ZVAMO = 1 << 3,
+};
+
+struct RVVIntrinsicInfo {
+  const char *TargetName;
+  unsigned TargetBuiltinID;
+  unsigned RequireFeatures;
+};
+
+struct RVVIntrinsicOverloadInfo {
+  const char *TargetName;
+  const char *OverloadName;
+  unsigned TargetBuiltinID;
+  unsigned RequireFeatures;
+};
+
+static const RVVIntrinsicInfo RVVIntrinsicInfos[] = {
+#include "clang/Basic/riscv_vector_intrinsic_info.inc"
+};
+
+static const RVVIntrinsicOverloadInfo RVVIntrinsicOverloadInfos[] = {
+#include "clang/Basic/riscv_vector_intrinsic_overload_info.inc"
+};
+
+void Sema::ActOnPragmaRISCVIntrinsic(SourceLocation Loc) {
+  auto &TI = Context.getTargetInfo();
+  bool HasF = TI.hasFeature("f");
+  bool HasD = TI.hasFeature("d");
+  bool HasZvamo = TI.hasFeature("experimental-zvamo");
+  bool HasZfh = TI.hasFeature("experimental-zfh");
+  unsigned Features = 0;
+  if (HasF)
+    Features |= Feature_F;
+  if (HasD)
+    Features |= Feature_D;
+  if (HasZfh)
+    Features |= Feature_ZFH;
+  if (HasZvamo)
+    Features |= Feature_ZVAMO;
+
+  for (auto InstrInfo : RVVIntrinsicInfos) {
+    // Check feature requirement.
+    if ((InstrInfo.RequireFeatures & Features) != InstrInfo.RequireFeatures)
+      continue;
+
+    PP.getIdentifierTable()
+        .get(InstrInfo.TargetName)
+        .setBuiltinID(InstrInfo.TargetBuiltinID);
+  }
+
+  for (auto InstrInfo : RVVIntrinsicOverloadInfos) {
+    // Check feature requirement.
+    if ((InstrInfo.RequireFeatures & Features) != InstrInfo.RequireFeatures)
+      continue;
+
+    auto &OverloadII = PP.getIdentifierTable().get(InstrInfo.OverloadName);
+    auto &II = PP.getIdentifierTable().get(InstrInfo.TargetName);
+    auto *FuncDecl = LazilyCreateBuiltin(&OverloadII, InstrInfo.TargetBuiltinID,
+                                         getCurScope(), false, Loc);
+    FuncDecl->addAttr(OverloadableAttr::CreateImplicit(Context));
+    FuncDecl->addAttr(BuiltinAliasAttr::CreateImplicit(Context, &II));
+  }
+}
Index: clang/lib/Sema/CMakeLists.txt
===================================================================
--- clang/lib/Sema/CMakeLists.txt
+++ clang/lib/Sema/CMakeLists.txt
@@ -51,6 +51,7 @@
   SemaOpenMP.cpp
   SemaOverload.cpp
   SemaPseudoObject.cpp
+  SemaRISCV.cpp
   SemaStmt.cpp
   SemaStmtAsm.cpp
   SemaStmtAttr.cpp
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -294,6 +294,15 @@
                     Token &FirstToken) override;
 };
 
+struct PragmaRISCVHandler : public PragmaHandler {
+  PragmaRISCVHandler(Sema &S) : PragmaHandler("riscv"), Actions(S) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
+                    Token &FirstToken) override;
+
+private:
+  Sema &Actions;
+};
+
 void markAsReinjectedForRelexing(llvm::MutableArrayRef<clang::Token> Toks) {
   for (auto &T : Toks)
     T.setFlag(clang::Token::IsReinjected);
@@ -431,6 +440,11 @@
 
   MaxTokensTotalPragmaHandler = std::make_unique<PragmaMaxTokensTotalHandler>();
   PP.AddPragmaHandler("clang", MaxTokensTotalPragmaHandler.get());
+
+  if (getTargetInfo().getTriple().isRISCV()) {
+    RISCVPragmaHandler = std::make_unique<PragmaRISCVHandler>(Actions);
+    PP.AddPragmaHandler(RISCVPragmaHandler.get());
+  }
 }
 
 void Parser::resetPragmaHandlers() {
@@ -549,6 +563,11 @@
 
   PP.RemovePragmaHandler("clang", MaxTokensTotalPragmaHandler.get());
   MaxTokensTotalPragmaHandler.reset();
+
+  if (getTargetInfo().getTriple().isRISCV()) {
+    PP.RemovePragmaHandler(RISCVPragmaHandler.get());
+    RISCVPragmaHandler.reset();
+  }
 }
 
 /// Handle the annotation token produced for #pragma unused(...)
@@ -3439,6 +3458,30 @@
         << "intrinsic";
 }
 
+// #pragma riscv intrinsic vector
+void PragmaRISCVHandler::HandlePragma(Preprocessor &PP,
+                                      PragmaIntroducer Introducer,
+                                      Token &FirstToken) {
+  Token Tok;
+  PP.Lex(Tok);
+  IdentifierInfo *II = Tok.getIdentifierInfo();
+  if (!II || (!II->isStr("intrinsic"))) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
+        << PP.getSpelling(Tok) << "riscv" << /*Expected=*/true << "'intrinsic'";
+    return;
+  }
+
+  PP.Lex(Tok);
+  II = Tok.getIdentifierInfo();
+  if (!II || (!II->isStr("vector"))) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
+        << PP.getSpelling(Tok) << "riscv" << /*Expected=*/true << "'vector'";
+    return;
+  }
+
+  Actions.ActOnPragmaRISCVIntrinsic(FirstToken.getLocation());
+}
+
 // #pragma optimize("gsty", on|off)
 void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
                                            PragmaIntroducer Introducer,
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -10028,6 +10028,9 @@
   void ActOnPragmaFPExceptions(SourceLocation Loc,
                                LangOptions::FPExceptionModeKind);
 
+  /// Called on well formed '\#pragma riscv intrinsic'.
+  void ActOnPragmaRISCVIntrinsic(SourceLocation Loc);
+
   /// Called to set constant rounding mode for floating point operations.
   void setRoundingMode(SourceLocation Loc, llvm::RoundingMode);
 
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -211,6 +211,7 @@
   std::unique_ptr<PragmaHandler> AttributePragmaHandler;
   std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
   std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
+  std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
 
   std::unique_ptr<CommentHandler> CommentSemaHandler;
 
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -878,6 +878,9 @@
 // Annotation for the attribute pragma directives - #pragma clang attribute ...
 PRAGMA_ANNOTATION(pragma_attribute)
 
+// Annotation for the riscv pragma directives - #pragma riscv intrinsic...
+PRAGMA_ANNOTATION(pragma_riscv)
+
 // Annotations for module import translated from #include etc.
 ANNOTATION(module_include)
 ANNOTATION(module_begin)
Index: clang/include/clang/Basic/CMakeLists.txt
===================================================================
--- clang/include/clang/Basic/CMakeLists.txt
+++ clang/include/clang/Basic/CMakeLists.txt
@@ -90,3 +90,9 @@
 clang_tablegen(riscv_vector_builtin_cg.inc -gen-riscv-vector-builtin-codegen
   SOURCE riscv_vector.td
   TARGET ClangRISCVVectorBuiltinCG)
+clang_tablegen(riscv_vector_intrinsic_info.inc -gen-riscv-vector-intrinsic-info
+  SOURCE riscv_vector.td
+  TARGET ClangRISCVVectorIntrinsicInfo)
+clang_tablegen(riscv_vector_intrinsic_overload_info.inc -gen-riscv-vector-intrinsic-overload-info
+  SOURCE riscv_vector.td
+  TARGET ClangRISCVVectorIntrinsicOverloadInfo)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to