[llvm] [mlir] [utils][TableGen] Clarify usage of ClauseVal, rename to EnumVal (PR #141761)
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Wed May 28 06:28:03 PDT 2025
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/141761
The class "ClauseVal" actually represents a definition of an enumeration value, and in itself it is not bound to any clause. Rename it to EnumVal and add a comment clarifying how it's translated into an actual enum definition in the generated source code.
There is no change in functionality.
>From 809e5129acf2fc1c49f355c3a5c858aeab5f9b5f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Wed, 21 May 2025 09:50:14 -0500
Subject: [PATCH] [utils][TableGen] Clarify usage of ClauseVal, rename to
EnumVal
The class "ClauseVal" actually represents a definition of an enumeration
value, and in itself it is not bound to any clause. Rename it to EnumVal
and add a comment clarifying how it's translated into an actual enum
definition in the generated source code.
There is no change in functionality.
---
.../llvm/Frontend/Directive/DirectiveBase.td | 22 +++++--
llvm/include/llvm/Frontend/OpenACC/ACC.td | 4 +-
llvm/include/llvm/Frontend/OpenMP/OMP.td | 64 +++++++++----------
llvm/include/llvm/TableGen/DirectiveEmitter.h | 4 +-
llvm/test/TableGen/directive1.td | 6 +-
.../utils/TableGen/Basic/DirectiveEmitter.cpp | 37 +++++------
mlir/test/mlir-tblgen/directive-common.td | 6 +-
mlir/tools/mlir-tblgen/DirectiveCommonGen.cpp | 8 +--
8 files changed, 83 insertions(+), 68 deletions(-)
diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
index 3e2744dea8d14..582da20083aee 100644
--- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
+++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
@@ -51,9 +51,23 @@ class DirectiveLanguage {
string flangClauseBaseClass = "";
}
-// Information about values accepted by enum-like clauses
-class ClauseVal<string n, int v, bit uv> {
- // Name of the clause value.
+// Some clauses take an argument from a predefined list of allowed keyword
+// values. For example, assume a clause "someclause" with an argument from
+// the list "foo", "bar", "baz". In the user source code this would look
+// like "someclause(foo)", whereas in the compiler the values would be
+// represented as
+// enum someclause.enumClauseValue {
+// Xyz_foo = v_foo,
+// Xyz_bar = v_bar,
+// Xyz_baz = v_baz,
+// }
+// The "Xyz_..." are the _record_ names of EnumVal's:
+// def Xyz_foo = EnumVal<"foo", v_foo>;
+// def Xyz_bar = EnumVal<"bar", v_bar>;
+// def Xyz_baz = EnumVal<"baz", v_baz>;
+//
+class EnumVal<string n, int v, bit uv> {
+ // Spelling of the value.
string name = n;
// Integer value of the clause.
@@ -90,7 +104,7 @@ class Clause<string c> {
string enumClauseValue = "";
// List of allowed clause values
- list<ClauseVal> allowedClauseValues = [];
+ list<EnumVal> allowedClauseValues = [];
// If set to true, value class is part of a list. Single class by default.
bit isValueList = false;
diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
index 46cba9f2400e1..b74cd6e5642ec 100644
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -86,8 +86,8 @@ def ACCC_Create : Clause<"create"> {
}
// 2.5.16
-def ACC_Default_none : ClauseVal<"none", 1, 1> { let isDefault = 1; }
-def ACC_Default_present : ClauseVal<"present", 0, 1> {}
+def ACC_Default_none : EnumVal<"none", 1, 1> { let isDefault = 1; }
+def ACC_Default_present : EnumVal<"present", 0, 1> {}
def ACCC_Default : Clause<"default"> {
let flangClass = "AccDefaultClause";
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 0af4b436649a3..cc9e038dc533c 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -77,9 +77,9 @@ def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
let flangClass = "OmpAtomicDefaultMemOrderClause";
}
-def OMP_BIND_parallel : ClauseVal<"parallel",1,1> {}
-def OMP_BIND_teams : ClauseVal<"teams",2,1> {}
-def OMP_BIND_thread : ClauseVal<"thread",3,1> { let isDefault = true; }
+def OMP_BIND_parallel : EnumVal<"parallel",1,1> {}
+def OMP_BIND_teams : EnumVal<"teams",2,1> {}
+def OMP_BIND_thread : EnumVal<"thread",3,1> { let isDefault = true; }
def OMPC_Bind : Clause<"bind"> {
let clangClass = "OMPBindClause";
let flangClass = "OmpBindClause";
@@ -91,11 +91,11 @@ def OMPC_Bind : Clause<"bind"> {
];
}
-def OMP_CANCELLATION_CONSTRUCT_Parallel : ClauseVal<"parallel", 1, 1> {}
-def OMP_CANCELLATION_CONSTRUCT_Loop : ClauseVal<"loop", 2, 1> {}
-def OMP_CANCELLATION_CONSTRUCT_Sections : ClauseVal<"sections", 3, 1> {}
-def OMP_CANCELLATION_CONSTRUCT_Taskgroup : ClauseVal<"taskgroup", 4, 1> {}
-def OMP_CANCELLATION_CONSTRUCT_None : ClauseVal<"none", 5, 0> {
+def OMP_CANCELLATION_CONSTRUCT_Parallel : EnumVal<"parallel", 1, 1> {}
+def OMP_CANCELLATION_CONSTRUCT_Loop : EnumVal<"loop", 2, 1> {}
+def OMP_CANCELLATION_CONSTRUCT_Sections : EnumVal<"sections", 3, 1> {}
+def OMP_CANCELLATION_CONSTRUCT_Taskgroup : EnumVal<"taskgroup", 4, 1> {}
+def OMP_CANCELLATION_CONSTRUCT_None : EnumVal<"none", 5, 0> {
let isDefault = 1;
}
def OMPC_CancellationConstructType : Clause<"cancellation_construct_type"> {
@@ -210,8 +210,8 @@ def OMPC_From : Clause<"from"> {
def OMPC_Full: Clause<"full"> {
let clangClass = "OMPFullClause";
}
-def OMP_GRAINSIZE_Strict : ClauseVal<"strict", 1, 1> {}
-def OMP_GRAINSIZE_Unknown : ClauseVal<"unknown", 2, 0> { let isDefault = 1; }
+def OMP_GRAINSIZE_Strict : EnumVal<"strict", 1, 1> {}
+def OMP_GRAINSIZE_Unknown : EnumVal<"unknown", 2, 0> { let isDefault = 1; }
def OMPC_GrainSize : Clause<"grainsize"> {
let clangClass = "OMPGrainsizeClause";
let flangClass = "OmpGrainsizeClause";
@@ -278,12 +278,12 @@ def OMPC_Map : Clause<"map"> {
def OMPC_Match : Clause<"match"> {
let flangClass = "OmpMatchClause";
}
-def OMP_MEMORY_ORDER_SeqCst : ClauseVal<"seq_cst", 1, 1> {}
-def OMP_MEMORY_ORDER_AcqRel : ClauseVal<"acq_rel", 2, 1> {}
-def OMP_MEMORY_ORDER_Acquire : ClauseVal<"acquire", 3, 1> {}
-def OMP_MEMORY_ORDER_Release : ClauseVal<"release", 4, 1> {}
-def OMP_MEMORY_ORDER_Relaxed : ClauseVal<"relaxed", 5, 1> {}
-def OMP_MEMORY_ORDER_Default : ClauseVal<"default", 6, 0> {
+def OMP_MEMORY_ORDER_SeqCst : EnumVal<"seq_cst", 1, 1> {}
+def OMP_MEMORY_ORDER_AcqRel : EnumVal<"acq_rel", 2, 1> {}
+def OMP_MEMORY_ORDER_Acquire : EnumVal<"acquire", 3, 1> {}
+def OMP_MEMORY_ORDER_Release : EnumVal<"release", 4, 1> {}
+def OMP_MEMORY_ORDER_Relaxed : EnumVal<"relaxed", 5, 1> {}
+def OMP_MEMORY_ORDER_Default : EnumVal<"default", 6, 0> {
let isDefault = 1;
}
def OMPC_MemoryOrder : Clause<"memory_order"> {
@@ -337,8 +337,8 @@ def OMPC_Novariants : Clause<"novariants"> {
def OMPC_NoWait : Clause<"nowait"> {
let clangClass = "OMPNowaitClause";
}
-def OMP_NUMTASKS_Strict : ClauseVal<"strict", 1, 1> {}
-def OMP_NUMTASKS_Unknown : ClauseVal<"unknown", 2, 0> { let isDefault = 1; }
+def OMP_NUMTASKS_Strict : EnumVal<"strict", 1, 1> {}
+def OMP_NUMTASKS_Unknown : EnumVal<"unknown", 2, 0> { let isDefault = 1; }
def OMPC_NumTasks : Clause<"num_tasks"> {
let clangClass = "OMPNumTasksClause";
let flangClass = "OmpNumTasksClause";
@@ -366,8 +366,8 @@ def OMPC_OMPX_DynCGroupMem : Clause<"ompx_dyn_cgroup_mem"> {
let clangClass = "OMPXDynCGroupMemClause";
let flangClass = "ScalarIntExpr";
}
-def OMP_ORDER_concurrent : ClauseVal<"concurrent",1,1> {}
-def OMP_ORDER_unknown : ClauseVal<"unknown",2,0> { let isDefault = 1; }
+def OMP_ORDER_concurrent : EnumVal<"concurrent",1,1> {}
+def OMP_ORDER_unknown : EnumVal<"unknown",2,0> { let isDefault = 1; }
def OMPC_Order : Clause<"order"> {
let clangClass = "OMPOrderClause";
let flangClass = "OmpOrderClause";
@@ -404,12 +404,12 @@ def OMPC_Private : Clause<"private"> {
let clangClass = "OMPPrivateClause";
let flangClass = "OmpObjectList";
}
-def OMP_PROC_BIND_master : ClauseVal<"master",2,1> {}
-def OMP_PROC_BIND_close : ClauseVal<"close",3,1> {}
-def OMP_PROC_BIND_spread : ClauseVal<"spread",4,1> {}
-def OMP_PROC_BIND_primary : ClauseVal<"primary",5,1> {}
-def OMP_PROC_BIND_default : ClauseVal<"default",6,0> {}
-def OMP_PROC_BIND_unknown : ClauseVal<"unknown",7,0> { let isDefault = true; }
+def OMP_PROC_BIND_master : EnumVal<"master",2,1> {}
+def OMP_PROC_BIND_close : EnumVal<"close",3,1> {}
+def OMP_PROC_BIND_spread : EnumVal<"spread",4,1> {}
+def OMP_PROC_BIND_primary : EnumVal<"primary",5,1> {}
+def OMP_PROC_BIND_default : EnumVal<"default",6,0> {}
+def OMP_PROC_BIND_unknown : EnumVal<"unknown",7,0> { let isDefault = true; }
def OMPC_ProcBind : Clause<"proc_bind"> {
let clangClass = "OMPProcBindClause";
let flangClass = "OmpProcBindClause";
@@ -443,12 +443,12 @@ def OMPC_SafeLen : Clause<"safelen"> {
let clangClass = "OMPSafelenClause";
let flangClass = "ScalarIntConstantExpr";
}
-def OMP_SCHEDULE_Static : ClauseVal<"static", 2, 1> {}
-def OMP_SCHEDULE_Dynamic : ClauseVal<"dynamic", 3, 1> {}
-def OMP_SCHEDULE_Guided : ClauseVal<"guided", 4, 1> {}
-def OMP_SCHEDULE_Auto : ClauseVal<"auto", 5, 1> {}
-def OMP_SCHEDULE_Runtime : ClauseVal<"runtime", 6, 1> {}
-def OMP_SCHEDULE_Default : ClauseVal<"default", 7, 0> { let isDefault = 1; }
+def OMP_SCHEDULE_Static : EnumVal<"static", 2, 1> {}
+def OMP_SCHEDULE_Dynamic : EnumVal<"dynamic", 3, 1> {}
+def OMP_SCHEDULE_Guided : EnumVal<"guided", 4, 1> {}
+def OMP_SCHEDULE_Auto : EnumVal<"auto", 5, 1> {}
+def OMP_SCHEDULE_Runtime : EnumVal<"runtime", 6, 1> {}
+def OMP_SCHEDULE_Default : EnumVal<"default", 7, 0> { let isDefault = 1; }
def OMPC_Schedule : Clause<"schedule"> {
let clangClass = "OMPScheduleClause";
let flangClass = "OmpScheduleClause";
diff --git a/llvm/include/llvm/TableGen/DirectiveEmitter.h b/llvm/include/llvm/TableGen/DirectiveEmitter.h
index 6defc8722d810..8615442ebff9f 100644
--- a/llvm/include/llvm/TableGen/DirectiveEmitter.h
+++ b/llvm/include/llvm/TableGen/DirectiveEmitter.h
@@ -308,9 +308,9 @@ class VersionedClause {
const Record *Def;
};
-class ClauseVal : public BaseRecord {
+class EnumVal : public BaseRecord {
public:
- ClauseVal(const Record *Def) : BaseRecord(Def) {}
+ EnumVal(const Record *Def) : BaseRecord(Def) {}
int getValue() const { return Def->getValueAsInt("value"); }
diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td
index 3b2b4ca1b7031..74091edfa2a66 100644
--- a/llvm/test/TableGen/directive1.td
+++ b/llvm/test/TableGen/directive1.td
@@ -14,9 +14,9 @@ def TestDirectiveLanguage : DirectiveLanguage {
let flangClauseBaseClass = "TdlClause";
}
-def TDLCV_vala : ClauseVal<"vala",1,1> {}
-def TDLCV_valb : ClauseVal<"valb",2,1> {}
-def TDLCV_valc : ClauseVal<"valc",3,0> { let isDefault = 1; }
+def TDLCV_vala : EnumVal<"vala",1,1> {}
+def TDLCV_valb : EnumVal<"valb",2,1> {}
+def TDLCV_valc : EnumVal<"valc",3,0> { let isDefault = 1; }
def TDLC_ClauseA : Clause<"clausea"> {
let enumClauseValue = "AKind";
diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
index 3d1795c5a6ff5..f459e7c98ebc1 100644
--- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
@@ -147,7 +147,7 @@ static void generateEnumBitmask(ArrayRef<const Record *> Records,
// Generate enums for values that clauses can take.
// Also generate function declarations for get<Enum>Name(StringRef Str).
-static void generateEnumClauseVal(ArrayRef<const Record *> Records,
+static void generateClauseEnumVal(ArrayRef<const Record *> Records,
raw_ostream &OS,
const DirectiveLanguage &DirLang,
std::string &EnumHelperFuncs) {
@@ -166,8 +166,8 @@ static void generateEnumClauseVal(ArrayRef<const Record *> Records,
OS << "\n";
OS << "enum class " << Enum << " {\n";
- for (const ClauseVal CVal : ClauseVals)
- OS << " " << CVal.getRecordName() << "=" << CVal.getValue() << ",\n";
+ for (const EnumVal Val : ClauseVals)
+ OS << " " << Val.getRecordName() << "=" << Val.getValue() << ",\n";
OS << "};\n";
if (DirLang.hasMakeEnumAvailableInNamespace()) {
@@ -306,9 +306,9 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
DirLang.getClausePrefix(),
DirLang.hasMakeEnumAvailableInNamespace());
- // Emit ClauseVal enumeration
+ // Emit ClauseVals enumeration
std::string EnumHelperFuncs;
- generateEnumClauseVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs);
+ generateClauseEnumVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs);
// Generic function signatures
OS << "\n";
@@ -412,9 +412,11 @@ static void generateGetKind(ArrayRef<const Record *> Records, raw_ostream &OS,
OS << "}\n";
}
-// Generate function implementation for get<ClauseVal>Kind(StringRef Str)
-static void generateGetKindClauseVal(const DirectiveLanguage &DirLang,
- raw_ostream &OS) {
+// Generate function implementations for
+// <enumClauseValue> get<enumClauseValue>(StringRef Str) and
+// StringRef get<enumClauseValue>Name(<enumClauseValue>)
+static void generateGetClauseVal(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
StringRef Lang = DirLang.getName();
std::string Qual = getQualifier(DirLang);
@@ -445,10 +447,9 @@ static void generateGetKindClauseVal(const DirectiveLanguage &DirLang,
OS << Qual << Enum << " " << Qual << "get" << Enum
<< "(llvm::StringRef Str) {\n";
OS << " return StringSwitch<" << Enum << ">(Str)\n";
- for (const auto &CV : ClauseVals) {
- ClauseVal CVal(CV);
- OS << " .Case(\"" << CVal.getFormattedName() << "\"," << CV->getName()
- << ")\n";
+ for (const EnumVal Val : ClauseVals) {
+ OS << " .Case(\"" << Val.getFormattedName() << "\","
+ << Val.getRecordName() << ")\n";
}
OS << " .Default(" << DefaultName << ");\n";
OS << "}\n";
@@ -457,10 +458,9 @@ static void generateGetKindClauseVal(const DirectiveLanguage &DirLang,
OS << "llvm::StringRef " << Qual << "get" << Lang << Enum << "Name(" << Qual
<< Enum << " x) {\n";
OS << " switch (x) {\n";
- for (const auto &CV : ClauseVals) {
- ClauseVal CVal(CV);
- OS << " case " << CV->getName() << ":\n";
- OS << " return \"" << CVal.getFormattedName() << "\";\n";
+ for (const EnumVal Val : ClauseVals) {
+ OS << " case " << Val.getRecordName() << ":\n";
+ OS << " return \"" << Val.getFormattedName() << "\";\n";
}
OS << " }\n"; // switch
OS << " llvm_unreachable(\"Invalid " << Lang << " " << Enum
@@ -1318,8 +1318,9 @@ void emitDirectivesBasicImpl(const DirectiveLanguage &DirLang,
// getClauseName(Clause Kind)
generateGetName(DirLang.getClauses(), OS, "Clause", DirLang, CPrefix);
- // get<ClauseVal>Kind(StringRef Str)
- generateGetKindClauseVal(DirLang, OS);
+ // <enumClauseValue> get<enumClauseValue>(StringRef Str) ; string -> value
+ // StringRef get<enumClauseValue>Name(<enumClauseValue>) ; value -> string
+ generateGetClauseVal(DirLang, OS);
// isAllowedClauseForDirective(Directive D, Clause C, unsigned Version)
generateIsAllowedClause(DirLang, OS);
diff --git a/mlir/test/mlir-tblgen/directive-common.td b/mlir/test/mlir-tblgen/directive-common.td
index 9429238a03f07..54e0d14ca83dd 100644
--- a/mlir/test/mlir-tblgen/directive-common.td
+++ b/mlir/test/mlir-tblgen/directive-common.td
@@ -7,9 +7,9 @@ def TestDirectiveLanguage : DirectiveLanguage {
let cppNamespace = "tdl";
}
-def TDLCV_vala : ClauseVal<"vala",1,1> {}
-def TDLCV_valb : ClauseVal<"valb",2,1> {}
-def TDLCV_valc : ClauseVal<"valc",3,0> { let isDefault = 1; }
+def TDLCV_vala : EnumVal<"vala",1,1> {}
+def TDLCV_valb : EnumVal<"valb",2,1> {}
+def TDLCV_valc : EnumVal<"valc",3,0> { let isDefault = 1; }
def TDLC_ClauseA : Clause<"clausea"> {
let flangClass = "TdlClauseA";
diff --git a/mlir/tools/mlir-tblgen/DirectiveCommonGen.cpp b/mlir/tools/mlir-tblgen/DirectiveCommonGen.cpp
index 602b3df3094af..09e1bdafe7bc9 100644
--- a/mlir/tools/mlir-tblgen/DirectiveCommonGen.cpp
+++ b/mlir/tools/mlir-tblgen/DirectiveCommonGen.cpp
@@ -21,7 +21,7 @@
#include "llvm/TableGen/Record.h"
using llvm::Clause;
-using llvm::ClauseVal;
+using llvm::EnumVal;
using llvm::raw_ostream;
using llvm::RecordKeeper;
@@ -63,11 +63,11 @@ static bool emitDecls(const RecordKeeper &records, llvm::StringRef dialect,
std::vector<std::string> cvDefs;
for (const auto &it : llvm::enumerate(clauseVals)) {
- const ClauseVal cval{it.value()};
- if (!cval.isUserVisible())
+ const EnumVal val{it.value()};
+ if (!val.isUserVisible())
continue;
- std::string name = cval.getFormattedName();
+ std::string name = val.getFormattedName();
std::string enumValName(name.length(), ' ');
llvm::transform(name, enumValName.begin(), llvm::toLower);
enumValName[0] = llvm::toUpper(enumValName[0]);
More information about the llvm-commits
mailing list