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. _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits