aboutsummaryrefslogtreecommitdiff
path: root/clang/utils
diff options
context:
space:
mode:
authorSam Tebbs <samuel.tebbs@arm.com>2023-12-18 09:32:34 +0000
committerGitHub <noreply@github.com>2023-12-18 09:32:34 +0000
commit945c645acb9670b7b866a4abd94bcc9b0ae5d87d (patch)
tree2bfea410c53eef535b40fa923f82ac28526ac090 /clang/utils
parentc7cdf3cd5d748901e1370f1bfe803685ca658fb6 (diff)
downloadllvm-945c645acb9670b7b866a4abd94bcc9b0ae5d87d.zip
llvm-945c645acb9670b7b866a4abd94bcc9b0ae5d87d.tar.gz
llvm-945c645acb9670b7b866a4abd94bcc9b0ae5d87d.tar.bz2
[AArch64][SME] Warn when using a streaming builtin from a non-streaming function (#75487)
This PR adds a warning that's emitted when a non-streaming or non-streaming-compatible builtin is called in an unsuitable function. Uses work by Kerry McLaughlin. This is a re-upload of #74064 and fixes a compile time increase.
Diffstat (limited to 'clang/utils')
-rw-r--r--clang/utils/TableGen/NeonEmitter.cpp28
-rw-r--r--clang/utils/TableGen/SveEmitter.cpp55
-rw-r--r--clang/utils/TableGen/TableGen.cpp12
-rw-r--r--clang/utils/TableGen/TableGenBackends.h2
4 files changed, 97 insertions, 0 deletions
diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp
index e5f79ba..5333401 100644
--- a/clang/utils/TableGen/NeonEmitter.cpp
+++ b/clang/utils/TableGen/NeonEmitter.cpp
@@ -550,6 +550,8 @@ class NeonEmitter {
void createIntrinsic(Record *R, SmallVectorImpl<Intrinsic *> &Out);
void genBuiltinsDef(raw_ostream &OS, SmallVectorImpl<Intrinsic *> &Defs);
+ void genStreamingSVECompatibleList(raw_ostream &OS,
+ SmallVectorImpl<Intrinsic *> &Defs);
void genOverloadTypeCheckCode(raw_ostream &OS,
SmallVectorImpl<Intrinsic *> &Defs);
void genIntrinsicRangeCheckCode(raw_ostream &OS,
@@ -2041,6 +2043,30 @@ void NeonEmitter::genBuiltinsDef(raw_ostream &OS,
OS << "#endif\n\n";
}
+void NeonEmitter::genStreamingSVECompatibleList(
+ raw_ostream &OS, SmallVectorImpl<Intrinsic *> &Defs) {
+ OS << "#ifdef GET_NEON_STREAMING_COMPAT_FLAG\n";
+
+ std::set<std::string> Emitted;
+ for (auto *Def : Defs) {
+ // If the def has a body (that is, it has Operation DAGs), it won't call
+ // __builtin_neon_* so we don't need to generate a definition for it.
+ if (Def->hasBody())
+ continue;
+
+ std::string Name = Def->getMangledName();
+ if (Emitted.find(Name) != Emitted.end())
+ continue;
+
+ // FIXME: We should make exceptions here for some NEON builtins that are
+ // permitted in streaming mode.
+ OS << "case NEON::BI__builtin_neon_" << Name
+ << ": BuiltinType = ArmNonStreaming; break;\n";
+ Emitted.insert(Name);
+ }
+ OS << "#endif\n\n";
+}
+
/// Generate the ARM and AArch64 overloaded type checking code for
/// SemaChecking.cpp, checking for unique builtin declarations.
void NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS,
@@ -2224,6 +2250,8 @@ void NeonEmitter::runHeader(raw_ostream &OS) {
// Generate ARM overloaded type checking code for SemaChecking.cpp
genOverloadTypeCheckCode(OS, Defs);
+ genStreamingSVECompatibleList(OS, Defs);
+
// Generate ARM range checking code for shift/lane immediates.
genIntrinsicRangeCheckCode(OS, Defs);
}
diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index 9361b99..a59b709 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -379,6 +379,9 @@ public:
/// Emit all the information needed to map builtin -> LLVM IR intrinsic.
void createSMECodeGenMap(raw_ostream &o);
+ /// Create a table for a builtin's requirement for PSTATE.SM.
+ void createStreamingAttrs(raw_ostream &o, ACLEKind Kind);
+
/// Emit all the range checks for the immediates.
void createSMERangeChecks(raw_ostream &o);
@@ -1702,6 +1705,51 @@ void SVEEmitter::createSMERangeChecks(raw_ostream &OS) {
OS << "#endif\n\n";
}
+void SVEEmitter::createStreamingAttrs(raw_ostream &OS, ACLEKind Kind) {
+ std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
+ SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
+ for (auto *R : RV)
+ createIntrinsic(R, Defs);
+
+ StringRef ExtensionKind;
+ switch (Kind) {
+ case ACLEKind::SME:
+ ExtensionKind = "SME";
+ break;
+ case ACLEKind::SVE:
+ ExtensionKind = "SVE";
+ break;
+ }
+
+ OS << "#ifdef GET_" << ExtensionKind << "_STREAMING_ATTRS\n";
+
+ llvm::StringMap<std::set<std::string>> StreamingMap;
+
+ uint64_t IsStreamingFlag = getEnumValueForFlag("IsStreaming");
+ uint64_t IsStreamingCompatibleFlag =
+ getEnumValueForFlag("IsStreamingCompatible");
+ for (auto &Def : Defs) {
+ if (Def->isFlagSet(IsStreamingFlag))
+ StreamingMap["ArmStreaming"].insert(Def->getMangledName());
+ else if (Def->isFlagSet(IsStreamingCompatibleFlag))
+ StreamingMap["ArmStreamingCompatible"].insert(Def->getMangledName());
+ else
+ StreamingMap["ArmNonStreaming"].insert(Def->getMangledName());
+ }
+
+ for (auto BuiltinType : StreamingMap.keys()) {
+ for (auto Name : StreamingMap[BuiltinType]) {
+ OS << "case " << ExtensionKind << "::BI__builtin_"
+ << ExtensionKind.lower() << "_";
+ OS << Name << ":\n";
+ }
+ OS << " BuiltinType = " << BuiltinType << ";\n";
+ OS << " break;\n";
+ }
+
+ OS << "#endif\n\n";
+}
+
namespace clang {
void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createHeader(OS);
@@ -1723,6 +1771,10 @@ void EmitSveTypeFlags(RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createTypeFlags(OS);
}
+void EmitSveStreamingAttrs(RecordKeeper &Records, raw_ostream &OS) {
+ SVEEmitter(Records).createStreamingAttrs(OS, ACLEKind::SVE);
+}
+
void EmitSmeHeader(RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createSMEHeader(OS);
}
@@ -1739,4 +1791,7 @@ void EmitSmeRangeChecks(RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createSMERangeChecks(OS);
}
+void EmitSmeStreamingAttrs(RecordKeeper &Records, raw_ostream &OS) {
+ SVEEmitter(Records).createStreamingAttrs(OS, ACLEKind::SME);
+}
} // End namespace clang
diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp
index 3ad46b9..9043d90 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -86,10 +86,12 @@ enum ActionType {
GenArmSveBuiltinCG,
GenArmSveTypeFlags,
GenArmSveRangeChecks,
+ GenArmSveStreamingAttrs,
GenArmSmeHeader,
GenArmSmeBuiltins,
GenArmSmeBuiltinCG,
GenArmSmeRangeChecks,
+ GenArmSmeStreamingAttrs,
GenArmCdeHeader,
GenArmCdeBuiltinDef,
GenArmCdeBuiltinSema,
@@ -246,6 +248,8 @@ cl::opt<ActionType> Action(
"Generate arm_sve_typeflags.inc for clang"),
clEnumValN(GenArmSveRangeChecks, "gen-arm-sve-sema-rangechecks",
"Generate arm_sve_sema_rangechecks.inc for clang"),
+ clEnumValN(GenArmSveStreamingAttrs, "gen-arm-sve-streaming-attrs",
+ "Generate arm_sve_streaming_attrs.inc for clang"),
clEnumValN(GenArmSmeHeader, "gen-arm-sme-header",
"Generate arm_sme.h for clang"),
clEnumValN(GenArmSmeBuiltins, "gen-arm-sme-builtins",
@@ -254,6 +258,8 @@ cl::opt<ActionType> Action(
"Generate arm_sme_builtin_cg_map.inc for clang"),
clEnumValN(GenArmSmeRangeChecks, "gen-arm-sme-sema-rangechecks",
"Generate arm_sme_sema_rangechecks.inc for clang"),
+ clEnumValN(GenArmSmeStreamingAttrs, "gen-arm-sme-streaming-attrs",
+ "Generate arm_sme_streaming_attrs.inc for clang"),
clEnumValN(GenArmMveHeader, "gen-arm-mve-header",
"Generate arm_mve.h for clang"),
clEnumValN(GenArmMveBuiltinDef, "gen-arm-mve-builtin-def",
@@ -494,6 +500,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenArmSveRangeChecks:
EmitSveRangeChecks(Records, OS);
break;
+ case GenArmSveStreamingAttrs:
+ EmitSveStreamingAttrs(Records, OS);
+ break;
case GenArmSmeHeader:
EmitSmeHeader(Records, OS);
break;
@@ -506,6 +515,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenArmSmeRangeChecks:
EmitSmeRangeChecks(Records, OS);
break;
+ case GenArmSmeStreamingAttrs:
+ EmitSmeStreamingAttrs(Records, OS);
+ break;
case GenArmCdeHeader:
EmitCdeHeader(Records, OS);
break;
diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h
index ef25561..6ec5177 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -105,11 +105,13 @@ void EmitSveBuiltins(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitSveBuiltinCG(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitSveTypeFlags(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitSveRangeChecks(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitSveStreamingAttrs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitSmeHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitSmeBuiltins(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitSmeBuiltinCG(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitSmeRangeChecks(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitSmeStreamingAttrs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitMveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitMveBuiltinDef(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);