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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits