[llvm-branch-commits] [clang] c28e32d - [RISCV] Lazily add RVV C intrinsics.
Hsiangkai Wang via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Oct 10 05:35:04 PDT 2021
Author: Hsiangkai Wang
Date: 2021-10-10T20:22:30+08:00
New Revision: c28e32d20fd4a334e49f64a041cbefe7cd1e8ce3
URL: https://github.com/llvm/llvm-project/commit/c28e32d20fd4a334e49f64a041cbefe7cd1e8ce3
DIFF: https://github.com/llvm/llvm-project/commit/c28e32d20fd4a334e49f64a041cbefe7cd1e8ce3.diff
LOG: [RISCV] Lazily add RVV C intrinsics.
Leverage the method OpenCL uses that adds C intrinsics when the lookup
failed. There is no need to define C intrinsics in the header file any
more. It could help to avoid the large header file to speed up the
compilation of RVV source code. Besides that, only the C intrinsics used
by the users will be added into the declaration table.
Added:
Modified:
clang/include/clang/Basic/CMakeLists.txt
clang/lib/Sema/SemaLookup.cpp
clang/utils/TableGen/RISCVVEmitter.cpp
clang/utils/TableGen/TableGen.cpp
clang/utils/TableGen/TableGenBackends.h
llvm/docs/CommandGuide/tblgen.rst
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 8cd891385a483..b930842ae8cfd 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -90,3 +90,6 @@ clang_tablegen(riscv_vector_builtins.inc -gen-riscv-vector-builtins
clang_tablegen(riscv_vector_builtin_cg.inc -gen-riscv-vector-builtin-codegen
SOURCE riscv_vector.td
TARGET ClangRISCVVectorBuiltinCG)
+clang_tablegen(riscv_vector_builtin_sema.inc -gen-riscv-vector-builtin-sema
+ SOURCE riscv_vector.td
+ TARGET ClangRISCVVectorBuiltinSema)
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index db6a01543d76a..28515f461545a 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -23,6 +23,8 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/Preprocessor.h"
@@ -48,6 +50,7 @@
#include <vector>
#include "OpenCLBuiltins.inc"
+#include "clang/Basic/riscv_vector_builtin_sema.inc"
using namespace clang;
using namespace sema;
@@ -895,6 +898,68 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR,
LR.resolveKind();
}
+static bool InsertRVVBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR,
+ IdentifierInfo *II,
+ const TargetInfo &TI,
+ Preprocessor &PP) {
+ bool HasF = TI.hasFeature("f");
+ bool HasD = TI.hasFeature("d");
+ bool HasZfh = TI.hasFeature("experimental-zfh");
+ bool HasZvamo = TI.hasFeature("experimental-zvamo");
+ unsigned Features = 0;
+ if (HasF)
+ Features |= RISCVFeature_F;
+ if (HasD)
+ Features |= RISCVFeature_D;
+ if (HasZfh)
+ Features |= RISCVFeature_ZFH;
+ if (HasZvamo)
+ Features |= RISCVFeature_ZVAMO;
+
+ const RVVIntrinsicInfo *Intrinsic = std::find_if(
+ std::begin(RVVIntrinsicInfos), std::end(RVVIntrinsicInfos),
+ [II](const RVVIntrinsicInfo &RVVII) {
+ return std::strcmp(RVVII.TargetName, II->getName().data()) == 0;
+ });
+ if (Intrinsic != std::end(RVVIntrinsicInfos)) {
+ if ((Intrinsic->RequireFeatures & Features) != Intrinsic->RequireFeatures)
+ return false;
+ if (NamedDecl *FD =
+ S.LazilyCreateBuiltin(II, Intrinsic->TargetBuiltinID, S.TUScope,
+ LR.isForRedeclaration(), LR.getNameLoc())) {
+ LR.addDecl(FD);
+ return true;
+ }
+ }
+
+ bool Found = false;
+ std::for_each(
+ std::begin(RVVIntrinsicOverloadInfos),
+ std::end(RVVIntrinsicOverloadInfos),
+ [&S, &LR, II, &PP, &Found,
+ Features](const RVVIntrinsicOverloadInfo &RVVII) {
+ if (std::strcmp(RVVII.OverloadName, II->getName().data()) == 0) {
+ if ((RVVII.RequireFeatures & Features) != RVVII.RequireFeatures)
+ return;
+ if (NamedDecl *FD = S.LazilyCreateBuiltin(
+ II, RVVII.TargetBuiltinID, S.TUScope, LR.isForRedeclaration(),
+ LR.getNameLoc())) {
+ auto &IntrinsicII = PP.getIdentifierTable().get(RVVII.TargetName);
+ FD->addAttr(OverloadableAttr::CreateImplicit(S.Context));
+ FD->addAttr(
+ BuiltinAliasAttr::CreateImplicit(S.Context, &IntrinsicII));
+ LR.addDecl(FD);
+ Found = true;
+ }
+ }
+ });
+
+ if (Found)
+ LR.resolveKind();
+
+ return Found;
+}
+
/// Lookup a builtin function, when name lookup would otherwise
/// fail.
bool Sema::LookupBuiltin(LookupResult &R) {
@@ -927,6 +992,12 @@ bool Sema::LookupBuiltin(LookupResult &R) {
}
}
+ const TargetInfo &TI = Context.getTargetInfo();
+ if (TI.getTriple().isRISCV() && TI.hasFeature("experimental-v")) {
+ if (InsertRVVBuiltinDeclarationsFromTable(*this, R, II, TI, PP))
+ return true;
+ }
+
// If this is a builtin on this (or all) targets, create the decl.
if (unsigned BuiltinID = II->getBuiltinID()) {
// In C++ and OpenCL (spec v1.2 s6.9.f), we don't have any predefined
diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp
index 467a8b2f52ac6..ee3a33cfde595 100644
--- a/clang/utils/TableGen/RISCVVEmitter.cpp
+++ b/clang/utils/TableGen/RISCVVEmitter.cpp
@@ -194,12 +194,6 @@ class RVVIntrinsic {
// 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,9 @@ class RVVEmitter {
/// Emit all the information needed to map builtin -> LLVM IR intrinsic.
void createCodeGen(raw_ostream &o);
+ /// Emit all the information needed by SemaLookup.cpp.
+ void createSema(raw_ostream &o);
+
std::string getSuffixStr(char Type, int Log2LMUL, StringRef Prototypes);
private:
@@ -235,15 +232,6 @@ class RVVEmitter {
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 +824,6 @@ void RVVIntrinsic::emitCodeGenSwitchBody(raw_ostream &OS) const {
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
//===----------------------------------------------------------------------===//
@@ -960,24 +918,8 @@ void RVVEmitter::createHeader(raw_ostream &OS) {
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 +1111,65 @@ Optional<RVVTypePtr> RVVEmitter::computeType(BasicType BT, int Log2LMUL,
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 << "RISCVFeature_F";
if (Extents & RISCVExtension::D)
- OS << LS << "defined(__riscv_d)";
+ OS << LS << "RISCVFeature_D";
if (Extents & RISCVExtension::Zfh)
- OS << LS << "defined(__riscv_zfh)";
+ OS << LS << "RISCVFeature_ZFH";
if (Extents & RISCVExtension::Zvamo)
- OS << LS << "defined(__riscv_zvamo)";
- OS << "\n";
- return true;
+ OS << LS << "RISCVFeature_ZVAMO";
+}
+
+void RVVEmitter::createSema(raw_ostream &OS) {
+ OS << "enum RISCVFeatures {\n";
+ OS << " RISCVFeature_F = 1 << 1,\n";
+ OS << " RISCVFeature_D = 1 << 2,\n";
+ OS << " RISCVFeature_ZFH = 1 << 3,\n";
+ OS << " RISCVFeature_ZVAMO = 1 << 4,\n";
+ OS << "};\n\n";
+
+ OS << "struct RVVIntrinsicInfo {\n";
+ OS << " const char *TargetName;\n";
+ OS << " unsigned TargetBuiltinID;\n";
+ OS << " unsigned RequireFeatures;\n";
+ OS << "};\n\n";
+
+ OS << "struct RVVIntrinsicOverloadInfo {\n";
+ OS << " const char *TargetName;\n";
+ OS << " const char *OverloadName;\n";
+ OS << " unsigned TargetBuiltinID;\n";
+ OS << " unsigned RequireFeatures;\n";
+ OS << "};\n\n";
+
+ std::vector<std::unique_ptr<RVVIntrinsic>> Defs;
+ createRVVIntrinsics(Defs);
+ OS << "static const RVVIntrinsicInfo RVVIntrinsicInfos[] = {\n";
+ for (auto &Def : Defs) {
+ OS << " {\"" << Def->getName() << "\", ";
+ OS << "RISCV::BI__builtin_rvv_" << Def->getName() << ", ";
+ emitFeatureCheckStr(Def->getRISCVExtensions(), OS);
+ OS << "},\n";
+ }
+ OS << "};\n\n";
+
+ OS << "static const RVVIntrinsicOverloadInfo RVVIntrinsicOverloadInfos[] = {\n";
+ 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";
+ }
+ OS << "};\n\n";
}
namespace clang {
@@ -1219,4 +1185,8 @@ void EmitRVVBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
RVVEmitter(Records).createCodeGen(OS);
}
+void EmitRVVBuiltinSema(RecordKeeper &Records, raw_ostream &OS) {
+ RVVEmitter(Records).createSema(OS);
+}
+
} // End namespace clang
diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp
index 55d62fa9f9bdc..a3fd5a07d0fb6 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -86,6 +86,7 @@ enum ActionType {
GenRISCVVectorHeader,
GenRISCVVectorBuiltins,
GenRISCVVectorBuiltinCG,
+ GenRISCVVectorBuiltinSema,
GenAttrDocs,
GenDiagDocs,
GenOptDocs,
@@ -237,6 +238,8 @@ cl::opt<ActionType> Action(
"Generate riscv_vector_builtins.inc for clang"),
clEnumValN(GenRISCVVectorBuiltinCG, "gen-riscv-vector-builtin-codegen",
"Generate riscv_vector_builtin_cg.inc for clang"),
+ clEnumValN(GenRISCVVectorBuiltinSema, "gen-riscv-vector-builtin-sema",
+ "Generate riscv_vector_builtin_sema.inc for clang"),
clEnumValN(GenAttrDocs, "gen-attr-docs",
"Generate attribute documentation"),
clEnumValN(GenDiagDocs, "gen-diag-docs",
@@ -446,6 +449,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenRISCVVectorBuiltinCG:
EmitRVVBuiltinCG(Records, OS);
break;
+ case GenRISCVVectorBuiltinSema:
+ EmitRVVBuiltinSema(Records, OS);
+ break;
case GenAttrDocs:
EmitClangAttrDocs(Records, OS);
break;
diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h
index 6930f242681f2..3696fb294510a 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -109,6 +109,7 @@ void EmitMveBuiltinAliases(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
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 EmitRVVBuiltinSema(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);
diff --git a/llvm/docs/CommandGuide/tblgen.rst b/llvm/docs/CommandGuide/tblgen.rst
index a7c254901392a..eac9cce471610 100644
--- a/llvm/docs/CommandGuide/tblgen.rst
+++ b/llvm/docs/CommandGuide/tblgen.rst
@@ -348,6 +348,10 @@ clang-tblgen Options
Generate ``riscv_vector_builtin_cg.inc`` for Clang.
+.. option:: -gen-riscv-vector-builtin-sema
+
+ Generate ``riscv_vector_builtin_sema.inc`` for Clang.
+
.. option:: -gen-attr-docs
Generate attribute documentation.
More information about the llvm-branch-commits
mailing list