kito-cheng created this revision.
Herald added subscribers: vkmr, frasercrmck, dexonsmith, evandro, luismarques, 
apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, 
brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, 
niosHD, sabuasal, simoncook, johnrusso, rbar, asb, mgorny.
kito-cheng requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

This patch is *NOT* ready to commite yet, it's PoC of the pragma approache to
reduce the size of `riscv_vector.h` and speed up the including effort.

Syntax for the new pragma:

  #pragma riscv intrinsic <extension name>

And we only support for vector now:

  #pragma riscv intrinsic vector

Size of `riscv_vector.h`:

  |      size |     LoC |

------------------------------

Before | 4,434,725 |  69,749 |
After  |     5,463 |     159 |

testcase:

  vint32m1_t test_vadd_vv_vfloat32m1_t(vint32m1_t op1, vint32m1_t op2, size_t 
vl) {
    return vadd(op1, op2, vl);
  }

Release build:

  Before: 0m0.417s
  After:  0m0.090s

Debug build:

  Before: 0m8.016s
  After:  0m2.295s

- Measure by time command.

LLVM regression on our 48 core server:

Release build:
 Before : Testing Time: 203.81s
 After  : Testing Time: 181.13s
Debug build:
 Before : Testing Time: 675.18s
 After  : Testing Time: 647.20s


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103228

Files:
  clang/include/clang/Basic/Builtins.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Basic/riscv_vector.td
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Basic/Builtins.cpp
  clang/lib/Basic/Targets/RISCV.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/CMakeLists.txt
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaRISCV.cpp
  clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c
  clang/test/CodeGen/RISCV/rvv_errors.c
  clang/utils/TableGen/RISCVVEmitter.cpp

Index: clang/utils/TableGen/RISCVVEmitter.cpp
===================================================================
--- clang/utils/TableGen/RISCVVEmitter.cpp
+++ clang/utils/TableGen/RISCVVEmitter.cpp
@@ -197,9 +197,6 @@
 
   // 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 {
@@ -836,36 +833,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 +864,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);
@@ -953,53 +921,47 @@
   }
   OS << "#endif\n\n";
 
-  // The same extension include in the same arch guard marco.
-  std::stable_sort(Defs.begin(), Defs.end(),
-                   [](const std::unique_ptr<RVVIntrinsic> &A,
-                      const std::unique_ptr<RVVIntrinsic> &B) {
-                     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";
   OS << "#endif // __RISCV_VECTOR_H\n";
 }
 
+struct OverloadTable {
+  SmallVector<StringRef, 16> Target;
+  bool HasSideEffects;
+};
+
 void RVVEmitter::createBuiltins(raw_ostream &OS) {
   std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
   createRVVIntrinsics(Defs);
 
   OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n";
-  OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, "
+  OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS, OVERLOAD) TARGET_BUILTIN(ID, "
+        "TYPE, "
+        "ATTRS, \"experimental-v\")\n";
+  OS << "#endif\n";
+  OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_OVERLOAD_BUILTIN)\n";
+  OS << "#define RISCVV_OVERLOAD_BUILTIN(ID, TYPE, ATTRS, OVERLOAD_LIST) "
+        "TARGET_BUILTIN(ID, TYPE, "
         "ATTRS, \"experimental-v\")\n";
   OS << "#endif\n";
   for (auto &Def : Defs) {
-    OS << "RISCVV_BUILTIN(__builtin_rvv_" << Def->getName() << ",\""
-       << Def->getBuiltinTypeStr() << "\", ";
+    OS << "RISCVV_BUILTIN(" << Def->getName() << ",\""
+       << Def->getBuiltinTypeStr() << "\", \"";
     if (!Def->hasSideEffects())
-      OS << "\"n\")\n";
+      OS << "n";
+
+    OS << "\", ";
+    if (!Def->isMask() && !Def->hasNoMaskedOverloaded())
+      OS << "nullptr";
     else
-      OS << "\"\")\n";
+      OS << "\"" << Def->getMangledName() << "\"";
+    OS << ")\n";
   }
+
   OS << "#undef RISCVV_BUILTIN\n";
 }
 
@@ -1022,7 +984,7 @@
       PrevDef->emitCodeGenSwitchBody(OS);
     }
     PrevDef = Def.get();
-    OS << "case RISCV::BI__builtin_rvv_" << Def->getName() << ":\n";
+    OS << "case RISCV::BI" << Def->getName() << ":\n";
   }
   Defs.back()->emitCodeGenSwitchBody(OS);
   OS << "\n";
Index: clang/test/CodeGen/RISCV/rvv_errors.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv_errors.c
+++ clang/test/CodeGen/RISCV/rvv_errors.c
@@ -1,10 +1,11 @@
 // RUN: %clang_cc1 %s -triple=riscv64 -target-feature +experimental-v -fsyntax-only -verify
 
+#pragma riscv intrinsic vector
 void test() {
-  __builtin_rvv_vsetvli(1, 7, 0); // expected-error {{argument value 7 is outside the valid range [0, 3]}}
-  __builtin_rvv_vsetvlimax(-1, 0); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}}
-  __builtin_rvv_vsetvli(1, 0, 4); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
-  __builtin_rvv_vsetvlimax(0, 4); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
-  __builtin_rvv_vsetvli(1, 0, 8); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
-  __builtin_rvv_vsetvlimax(0, -1); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
+  vsetvli(1, 7, 0); // expected-error {{argument value 7 is outside the valid range [0, 3]}}
+  vsetvlimax(-1, 0); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}}
+  vsetvli(1, 0, 4); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
+  vsetvlimax(0, 4); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
+  vsetvli(1, 0, 8); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
+  vsetvlimax(0, -1); // expected-error {{LMUL argument must be in the range [0,3] or [5,7]}}
 }
Index: clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c
===================================================================
--- clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c
+++ clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c
@@ -10,7 +10,7 @@
 static inline __attribute__((__always_inline__, __nodebug__))
 
 __rvv_generic
-__attribute__((clang_builtin_alias(__builtin_rvv_vadd_vv_i8m1)))
+__attribute__((clang_builtin_alias(vadd_vv_i8m1)))
 vint8m1_t vadd_generic (vint8m1_t op0, vint8m1_t op1, size_t op2);
 
 // CHECK-LABEL: @test(
Index: clang/lib/Sema/SemaRISCV.cpp
===================================================================
--- /dev/null
+++ clang/lib/Sema/SemaRISCV.cpp
@@ -0,0 +1,34 @@
+//===--- 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/Parse/Parser.h"
+#include "clang/Sema/Sema.h"
+using namespace clang;
+
+void Sema::ActOnPragmaRISCVIntrinsic() {
+  PP.getBuiltinInfo().initializeTargetBuiltins(
+      PP.getIdentifierTable(), PP.getLangOpts(), Builtin::RISCV_VECTOR_KIND);
+  Builtin::RegisterOverloadBuiltinFunc F = [](Sema &S, const Builtin::Info &BI,
+                                              unsigned ID) {
+    auto &OverloadII = S.PP.getIdentifierTable().get(BI.Overload);
+    auto &II = S.PP.getIdentifierTable().get(BI.Name);
+    SourceLocation Loc;
+    auto *FDecl =
+        S.LazilyCreateBuiltin(&OverloadII, ID, S.getCurScope(), false, Loc);
+    FDecl->addAttr(OverloadableAttr::CreateImplicit(S.Context));
+    FDecl->addAttr(BuiltinAliasAttr::CreateImplicit(S.Context, &II));
+  };
+
+  PP.getBuiltinInfo().initializeTargetOverloadBuiltins(
+      *this, F, PP.getLangOpts(), Builtin::RISCV_VECTOR_KIND);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -3472,10 +3472,10 @@
     return true;
 
   switch (BuiltinID) {
-  case RISCV::BI__builtin_rvv_vsetvli:
+  case RISCV::BIvsetvli:
     return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3) ||
            CheckRISCVLMUL(TheCall, 2);
-  case RISCV::BI__builtin_rvv_vsetvlimax:
+  case RISCV::BIvsetvlimax:
     return SemaBuiltinConstantArgRange(TheCall, 0, 0, 3) ||
            CheckRISCVLMUL(TheCall, 1);
   }
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
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/Basic/PragmaKinds.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
@@ -294,6 +295,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 +441,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 +564,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 +3459,41 @@
         << "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;
+  }
+#if 0
+  // Generate the annotated pragma token.
+  auto TokenArray = std::make_unique<Token[]>(1);
+  TokenArray[0].startToken();
+  TokenArray[0].setKind(tok::annot_pragma_riscv);
+  TokenArray[0].setLocation(FirstToken.getLocation());
+  TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
+
+  PP.EnterTokenStream(std::move(TokenArray), 1,
+                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
+#endif
+
+  Actions.ActOnPragmaRISCVIntrinsic();
+}
+
 // #pragma optimize("gsty", on|off)
 void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
                                            PragmaIntroducer Introducer,
Index: clang/lib/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -228,9 +228,16 @@
 
 const Builtin::Info RISCVTargetInfo::BuiltinInfo[] = {
 #define BUILTIN(ID, TYPE, ATTRS)                                               \
-  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+  {#ID,           TYPE,    ATTRS,   nullptr,                                   \
+   ALL_LANGUAGES, nullptr, nullptr, Builtin::ALWAYS_KIND},
 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
-    {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+  {#ID,           TYPE,    ATTRS,   nullptr,                                   \
+   ALL_LANGUAGES, FEATURE, nullptr, Builtin::ALWAYS_KIND},
+#define RISCVV_BUILTIN(ID, TYPE, ATTRS, OVERLOAD)                              \
+  {#ID,           TYPE,                                                        \
+   ATTRS,         nullptr,                                                     \
+   ALL_LANGUAGES, "experimental-v",                                            \
+   OVERLOAD,      Builtin::RISCV_VECTOR_KIND},
 #include "clang/Basic/BuiltinsRISCV.def"
 };
 
Index: clang/lib/Basic/Builtins.cpp
===================================================================
--- clang/lib/Basic/Builtins.cpp
+++ clang/lib/Basic/Builtins.cpp
@@ -18,13 +18,15 @@
 using namespace clang;
 
 static const Builtin::Info BuiltinInfo[] = {
-  { "not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,nullptr},
+    {"not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,
+     nullptr, nullptr, Builtin::ALWAYS_KIND},
 #define BUILTIN(ID, TYPE, ATTRS)                                               \
-  { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
+  {#ID,           TYPE,    ATTRS,   nullptr,                                   \
+   ALL_LANGUAGES, nullptr, nullptr, Builtin::ALWAYS_KIND},
 #define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
-  { #ID, TYPE, ATTRS, nullptr, LANGS, nullptr },
+  {#ID, TYPE, ATTRS, nullptr, LANGS, nullptr, nullptr, Builtin::ALWAYS_KIND},
 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
-  { #ID, TYPE, ATTRS, HEADER, LANGS, nullptr },
+  {#ID, TYPE, ATTRS, HEADER, LANGS, nullptr, nullptr, Builtin::ALWAYS_KIND},
 #include "clang/Basic/Builtins.def"
 };
 
@@ -56,7 +58,8 @@
 }
 
 bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo,
-                                          const LangOptions &LangOpts) {
+                                          const LangOptions &LangOpts,
+                                          BuiltinKind Kind) {
   bool BuiltinsUnsupported =
       (LangOpts.NoBuiltin || LangOpts.isNoBuiltinFunc(BuiltinInfo.Name)) &&
       strchr(BuiltinInfo.Attributes, 'f');
@@ -78,10 +81,11 @@
   bool CUDAUnsupported = !LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG;
   bool CPlusPlusUnsupported =
       !LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG;
+  bool SupportedKind = BuiltinInfo.Kind == Kind;
   return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported &&
          !OclC1Unsupported && !OclC2Unsupported && !OpenMPUnsupported &&
          !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported &&
-         !CPlusPlusUnsupported && !CUDAUnsupported;
+         !CPlusPlusUnsupported && !CUDAUnsupported && SupportedKind;
 }
 
 /// initializeBuiltins - Mark the identifiers for all the builtins with their
@@ -91,13 +95,13 @@
                                           const LangOptions& LangOpts) {
   // Step #1: mark all target-independent builtins with their ID's.
   for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
-    if (builtinIsSupported(BuiltinInfo[i], LangOpts)) {
+    if (builtinIsSupported(BuiltinInfo[i], LangOpts, Builtin::ALWAYS_KIND)) {
       Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
     }
 
   // Step #2: Register target-specific builtins.
   for (unsigned i = 0, e = TSRecords.size(); i != e; ++i)
-    if (builtinIsSupported(TSRecords[i], LangOpts))
+    if (builtinIsSupported(TSRecords[i], LangOpts, Builtin::ALWAYS_KIND))
       Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin);
 
   // Step #3: Register target-specific builtins for AuxTarget.
@@ -106,6 +110,23 @@
         .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size());
 }
 
+void Builtin::Context::initializeTargetBuiltins(IdentifierTable &Table,
+                                                const LangOptions &LangOpts,
+                                                BuiltinKind Kind) {
+  for (unsigned i = 0, e = TSRecords.size(); i != e; ++i)
+    if (builtinIsSupported(TSRecords[i], LangOpts, Kind))
+      Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin);
+}
+
+void Builtin::Context::initializeTargetOverloadBuiltins(
+    Sema &S, RegisterOverloadBuiltinFunc Func, const LangOptions &LangOpts,
+    BuiltinKind Kind) {
+  for (unsigned i = 0, e = TSRecords.size(); i != e; ++i) {
+    if (builtinIsSupported(TSRecords[i], LangOpts, Kind) &&
+        TSRecords[i].Overload)
+      Func(S, TSRecords[i], i + Builtin::FirstTSBuiltin);
+  }
+}
 unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const {
   const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V');
   if (!WidthPos)
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -10002,6 +10002,9 @@
   void ActOnPragmaFPExceptions(SourceLocation Loc,
                                LangOptions::FPExceptionModeKind);
 
+  /// Called on well formed '\#pragma riscv intrinsic'.
+  void ActOnPragmaRISCVIntrinsic();
+
   /// 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
@@ -210,6 +210,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/riscv_vector.td
===================================================================
--- clang/include/clang/Basic/riscv_vector.td
+++ clang/include/clang/Basic/riscv_vector.td
@@ -114,10 +114,10 @@
 // The name of the builtin is defined by the Name attribute (which defaults to
 // the name of the class) appended (separated with an underscore) the Suffix
 // attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
-// the builtin generated will be __builtin_rvv_foo_i32m1 and
-// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
+// the builtin generated will be foo_i32m1 and
+// foo_i64m1 (under LMUL=1). If Suffix contains more than one
 // type transformer (say "vv") each of the types is separated with an
-// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
+// underscore as in "foo_i32m1_i32m1".
 //
 // The C/C++ prototype of the builtin is defined by the Prototype attribute.
 // Prototype is a non-empty sequence of type transformers, the first of which
@@ -984,62 +984,62 @@
   // vsetvl is a macro because for it require constant integers in SEW and LMUL.
   let HeaderCode =
 [{
-#define vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5)
-#define vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6)
-#define vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7)
-#define vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0)
-#define vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1)
-#define vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2)
-#define vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3)
-
-#define vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6)
-#define vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7)
-#define vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0)
-#define vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1)
-#define vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2)
-#define vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3)
-
-#define vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7)
-#define vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0)
-#define vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1)
-#define vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2)
-#define vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3)
-
-#define vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0)
-#define vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1)
-#define vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2)
-#define vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3)
+#define vsetvl_e8mf8(avl) vsetvli((size_t)(avl), 0, 5)
+#define vsetvl_e8mf4(avl) vsetvli((size_t)(avl), 0, 6)
+#define vsetvl_e8mf2(avl) vsetvli((size_t)(avl), 0, 7)
+#define vsetvl_e8m1(avl) vsetvli((size_t)(avl), 0, 0)
+#define vsetvl_e8m2(avl) vsetvli((size_t)(avl), 0, 1)
+#define vsetvl_e8m4(avl) vsetvli((size_t)(avl), 0, 2)
+#define vsetvl_e8m8(avl) vsetvli((size_t)(avl), 0, 3)
+
+#define vsetvl_e16mf4(avl) vsetvli((size_t)(avl), 1, 6)
+#define vsetvl_e16mf2(avl) vsetvli((size_t)(avl), 1, 7)
+#define vsetvl_e16m1(avl) vsetvli((size_t)(avl), 1, 0)
+#define vsetvl_e16m2(avl) vsetvli((size_t)(avl), 1, 1)
+#define vsetvl_e16m4(avl) vsetvli((size_t)(avl), 1, 2)
+#define vsetvl_e16m8(avl) vsetvli((size_t)(avl), 1, 3)
+
+#define vsetvl_e32mf2(avl) vsetvli((size_t)(avl), 2, 7)
+#define vsetvl_e32m1(avl) vsetvli((size_t)(avl), 2, 0)
+#define vsetvl_e32m2(avl) vsetvli((size_t)(avl), 2, 1)
+#define vsetvl_e32m4(avl) vsetvli((size_t)(avl), 2, 2)
+#define vsetvl_e32m8(avl) vsetvli((size_t)(avl), 2, 3)
+
+#define vsetvl_e64m1(avl) vsetvli((size_t)(avl), 3, 0)
+#define vsetvl_e64m2(avl) vsetvli((size_t)(avl), 3, 1)
+#define vsetvl_e64m4(avl) vsetvli((size_t)(avl), 3, 2)
+#define vsetvl_e64m8(avl) vsetvli((size_t)(avl), 3, 3)
 
 }] in
   def vsetvli : RVVBuiltin<"", "zzKzKz", "i">;
 
   let HeaderCode =
 [{
-#define vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5)
-#define vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6)
-#define vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7)
-#define vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0)
-#define vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1)
-#define vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2)
-#define vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3)
-
-#define vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6)
-#define vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7)
-#define vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0)
-#define vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1)
-#define vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2)
-#define vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3)
-
-#define vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7)
-#define vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0)
-#define vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1)
-#define vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2)
-#define vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3)
-
-#define vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0)
-#define vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1)
-#define vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2)
-#define vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3)
+#define vsetvlmax_e8mf8() vsetvlimax(0, 5)
+#define vsetvlmax_e8mf4() vsetvlimax(0, 6)
+#define vsetvlmax_e8mf2() vsetvlimax(0, 7)
+#define vsetvlmax_e8m1() vsetvlimax(0, 0)
+#define vsetvlmax_e8m2() vsetvlimax(0, 1)
+#define vsetvlmax_e8m4() vsetvlimax(0, 2)
+#define vsetvlmax_e8m8() vsetvlimax(0, 3)
+
+#define vsetvlmax_e16mf4() vsetvlimax(1, 6)
+#define vsetvlmax_e16mf2() vsetvlimax(1, 7)
+#define vsetvlmax_e16m1() vsetvlimax(1, 0)
+#define vsetvlmax_e16m2() vsetvlimax(1, 1)
+#define vsetvlmax_e16m4() vsetvlimax(1, 2)
+#define vsetvlmax_e16m8() vsetvlimax(1, 3)
+
+#define vsetvlmax_e32mf2() vsetvlimax(2, 7)
+#define vsetvlmax_e32m1() vsetvlimax(2, 0)
+#define vsetvlmax_e32m2() vsetvlimax(2, 1)
+#define vsetvlmax_e32m4() vsetvlimax(2, 2)
+#define vsetvlmax_e32m8() vsetvlimax(2, 3)
+
+#define vsetvlmax_e64m1() vsetvlimax(3, 0)
+#define vsetvlmax_e64m2() vsetvlimax(3, 1)
+#define vsetvlmax_e64m4() vsetvlimax(3, 2)
+#define vsetvlmax_e64m8() vsetvlimax(3, 3)
 
 }] in
   def vsetvlimax : RVVBuiltin<"", "zKzKz", "i">;
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -875,6 +875,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/Builtins.h
===================================================================
--- clang/include/clang/Basic/Builtins.h
+++ clang/include/clang/Basic/Builtins.h
@@ -26,6 +26,7 @@
 class TargetInfo;
 class IdentifierTable;
 class LangOptions;
+class Sema;
 
 enum LanguageID {
   GNU_LANG = 0x1,     // builtin requires GNU mode.
@@ -51,12 +52,18 @@
   FirstTSBuiltin
 };
 
+enum BuiltinKind { ALWAYS_KIND, RISCV_VECTOR_KIND };
+
 struct Info {
   const char *Name, *Type, *Attributes, *HeaderName;
   LanguageID Langs;
   const char *Features;
+  const char *Overload;
+  BuiltinKind Kind;
 };
 
+typedef void (*RegisterOverloadBuiltinFunc)(Sema &S, const Info &, unsigned ID);
+
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -79,6 +86,13 @@
   /// such.
   void initializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts);
 
+  void initializeTargetBuiltins(IdentifierTable &Table,
+                                const LangOptions &LangOpts, BuiltinKind Kind);
+  void initializeTargetOverloadBuiltins(Sema &S,
+                                        RegisterOverloadBuiltinFunc Func,
+                                        const LangOptions &LangOpts,
+                                        BuiltinKind Kind);
+
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
   const char *getName(unsigned ID) const {
@@ -237,7 +251,7 @@
 
   /// Is this builtin supported according to the given language options?
   bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
-                          const LangOptions &LangOpts);
+                          const LangOptions &LangOpts, BuiltinKind Kind);
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to