Skip to content

[RISCV] Add groupid/bitmask for RISC-V extension #94440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 22, 2024

Conversation

BeMg
Copy link
Contributor

@BeMg BeMg commented Jun 5, 2024

Base on riscv-non-isa/riscv-c-api-doc#74.

This patch defines the groupid/bitmask in RISCVFeatures.td and generates the corresponding table in RISCVTargetParserDef.inc.

The groupid/bitmask of extensions provides an abstraction layer between the compiler and runtime functions.

@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Piyou Chen (BeMg)

Changes

Base on riscv-non-isa/riscv-c-api-doc#74.

This patch defines the groupid/bitmask in RISCVFeatures.td and generates the corresponding table in RISCVTargetParserDef.inc.

The groupid/bitmask of extensions provides an abstraction layer between the compiler and runtime functions.


Patch is 40.57 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/94440.diff

4 Files Affected:

  • (modified) llvm/include/llvm/TargetParser/RISCVTargetParser.h (+8)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+105)
  • (modified) llvm/lib/TargetParser/RISCVTargetParser.cpp (+32)
  • (modified) llvm/utils/TableGen/RISCVTargetDefEmitter.cpp (+39)
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index 5b1494efe7bdc..24755dcfec52a 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -24,6 +24,14 @@ class Triple;
 
 namespace RISCV {
 
+namespace RISCVExtensionBitmaskTable {
+struct RISCVExtensionBitmask {
+  const char *Name;
+  unsigned GroupID;
+  unsigned long long Bitmask;
+};
+} // namespace RISCVExtensionBitmaskTable
+
 // We use 64 bits as the known part in the scalable vector types.
 static constexpr unsigned RVVBitsPerBlock = 64;
 
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 9bf06850483d8..bfaa7b1a1b99b 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -37,6 +37,13 @@ class RISCVExtension<string name, int major, int minor, string desc,
   bit Experimental = false;
 }
 
+// TODO: Maybe integrate into RISCVExtension class
+class RISCVExtensionBitmask<string name, bits<3> groupID, int bitmaskShift> {
+    string Name = name;
+    bits<3> GroupID = groupID;
+    bits<64> Bitmask = !shl(1, bitmaskShift);
+}
+
 // Version of RISCVExtension to be used for Experimental extensions. This
 // sets the Experimental flag and prepends experimental- to the -mattr name.
 class RISCVExperimentalExtension<string name, int major, int minor, string desc,
@@ -53,18 +60,22 @@ class RISCVExperimentalExtension<string name, int major, int minor, string desc,
 def FeatureStdExtI
     : RISCVExtension<"i", 2, 1,
                      "'I' (Base Integer Instruction Set)">;
+def : RISCVExtensionBitmask<"i", 0, 0>;
 
 def FeatureStdExtE
     : RISCVExtension<"e", 2, 0,
                      "Implements RV{32,64}E (provides 16 rather than 32 GPRs)">;
+def : RISCVExtensionBitmask<"e", 0, 1>;
 
 def FeatureStdExtZic64b
     : RISCVExtension<"zic64b", 1, 0,
                      "'Zic64b' (Cache Block Size Is 64 Bytes)">;
+def : RISCVExtensionBitmask<"zic64b", 0, 2>;
 
 def FeatureStdExtZicbom
     : RISCVExtension<"zicbom", 1, 0,
                      "'Zicbom' (Cache-Block Management Instructions)">;
+def : RISCVExtensionBitmask<"zicbom", 0, 3>;
 def HasStdExtZicbom : Predicate<"Subtarget->hasStdExtZicbom()">,
                       AssemblerPredicate<(all_of FeatureStdExtZicbom),
                           "'Zicbom' (Cache-Block Management Instructions)">;
@@ -72,6 +83,7 @@ def HasStdExtZicbom : Predicate<"Subtarget->hasStdExtZicbom()">,
 def FeatureStdExtZicbop
     : RISCVExtension<"zicbop", 1, 0,
                      "'Zicbop' (Cache-Block Prefetch Instructions)">;
+def : RISCVExtensionBitmask<"zicbop", 0, 4>;
 def HasStdExtZicbop : Predicate<"Subtarget->hasStdExtZicbop()">,
                       AssemblerPredicate<(all_of FeatureStdExtZicbop),
                           "'Zicbop' (Cache-Block Prefetch Instructions)">;
@@ -79,6 +91,7 @@ def HasStdExtZicbop : Predicate<"Subtarget->hasStdExtZicbop()">,
 def FeatureStdExtZicboz
     : RISCVExtension<"zicboz", 1, 0,
                      "'Zicboz' (Cache-Block Zero Instructions)">;
+def : RISCVExtensionBitmask<"zicboz", 0, 5>;
 def HasStdExtZicboz : Predicate<"Subtarget->hasStdExtZicboz()">,
                       AssemblerPredicate<(all_of FeatureStdExtZicboz),
                           "'Zicboz' (Cache-Block Zero Instructions)">;
@@ -86,22 +99,27 @@ def HasStdExtZicboz : Predicate<"Subtarget->hasStdExtZicboz()">,
 def FeatureStdExtZiccamoa
     : RISCVExtension<"ziccamoa", 1, 0,
                      "'Ziccamoa' (Main Memory Supports All Atomics in A)">;
+def : RISCVExtensionBitmask<"ziccamoa", 0, 6>;
 
 def FeatureStdExtZiccif
     : RISCVExtension<"ziccif", 1, 0,
                      "'Ziccif' (Main Memory Supports Instruction Fetch with Atomicity Requirement)">;
+def : RISCVExtensionBitmask<"ziccif", 0, 7>;
 
 def FeatureStdExtZicclsm
     : RISCVExtension<"zicclsm", 1, 0,
                      "'Zicclsm' (Main Memory Supports Misaligned Loads/Stores)">;
+def : RISCVExtensionBitmask<"zicclsm", 0, 8>;
 
 def FeatureStdExtZiccrse
     : RISCVExtension<"ziccrse", 1, 0,
                      "'Ziccrse' (Main Memory Supports Forward Progress on LR/SC Sequences)">;
+def : RISCVExtensionBitmask<"ziccrse", 0, 9>;
 
 def FeatureStdExtZicsr
     : RISCVExtension<"zicsr", 2, 0,
                      "'zicsr' (CSRs)">;
+def : RISCVExtensionBitmask<"zicsr", 0, 10>;
 def HasStdExtZicsr : Predicate<"Subtarget->hasStdExtZicsr()">,
                      AssemblerPredicate<(all_of FeatureStdExtZicsr),
                                         "'Zicsr' (CSRs)">;
@@ -110,10 +128,12 @@ def FeatureStdExtZicntr
     : RISCVExtension<"zicntr", 2, 0,
                      "'Zicntr' (Base Counters and Timers)",
                        [FeatureStdExtZicsr]>;
+def : RISCVExtensionBitmask<"zicntr", 0, 11>;
 
 def FeatureStdExtZicond
     : RISCVExtension<"zicond", 1, 0,
                      "'Zicond' (Integer Conditional Operations)">;
+def : RISCVExtensionBitmask<"zicond", 0, 12>;
 def HasStdExtZicond : Predicate<"Subtarget->hasStdExtZicond()">,
                       AssemblerPredicate<(all_of FeatureStdExtZicond),
                           "'Zicond' (Integer Conditional Operations)">;
@@ -121,6 +141,7 @@ def HasStdExtZicond : Predicate<"Subtarget->hasStdExtZicond()">,
 def FeatureStdExtZifencei
     : RISCVExtension<"zifencei", 2, 0,
                      "'Zifencei' (fence.i)">;
+def : RISCVExtensionBitmask<"zifencei", 0, 13>;
 def HasStdExtZifencei : Predicate<"Subtarget->hasStdExtZifencei()">,
                         AssemblerPredicate<(all_of FeatureStdExtZifencei),
                                            "'Zifencei' (fence.i)">;
@@ -128,6 +149,7 @@ def HasStdExtZifencei : Predicate<"Subtarget->hasStdExtZifencei()">,
 def FeatureStdExtZihintpause
     : RISCVExtension<"zihintpause", 2, 0,
                      "'Zihintpause' (Pause Hint)">;
+def : RISCVExtensionBitmask<"zihintpause", 0, 14>;
 def HasStdExtZihintpause : Predicate<"Subtarget->hasStdExtZihintpause()">,
                            AssemblerPredicate<(all_of FeatureStdExtZihintpause),
                                               "'Zihintpause' (Pause Hint)">;
@@ -135,6 +157,7 @@ def HasStdExtZihintpause : Predicate<"Subtarget->hasStdExtZihintpause()">,
 def FeatureStdExtZihintntl
     : RISCVExtension<"zihintntl", 1, 0,
                      "'Zihintntl' (Non-Temporal Locality Hints)">;
+def : RISCVExtensionBitmask<"zihintntl", 0, 15>;
 def HasStdExtZihintntl : Predicate<"Subtarget->hasStdExtZihintntl()">,
                          AssemblerPredicate<(all_of FeatureStdExtZihintntl),
                              "'Zihintntl' (Non-Temporal Locality Hints)">;
@@ -143,9 +166,11 @@ def FeatureStdExtZihpm
     : RISCVExtension<"zihpm", 2, 0,
                      "'Zihpm' (Hardware Performance Counters)",
                      [FeatureStdExtZicsr]>;
+def : RISCVExtensionBitmask<"zihpm", 0, 16>;
 
 def FeatureStdExtZimop : RISCVExtension<"zimop", 1, 0,
                                         "'Zimop' (May-Be-Operations)">;
+def : RISCVExtensionBitmask<"zimop", 0, 17>;
 def HasStdExtZimop : Predicate<"Subtarget->hasStdExtZimop()">,
                      AssemblerPredicate<(all_of FeatureStdExtZimop),
                                         "'Zimop' (May-Be-Operations)">;
@@ -154,6 +179,7 @@ def FeatureStdExtZicfilp
     : RISCVExperimentalExtension<"zicfilp", 0, 4,
                                  "'Zicfilp' (Landing pad)",
                                  [FeatureStdExtZicsr]>;
+def : RISCVExtensionBitmask<"zicfilp", 0, 18>;
 def HasStdExtZicfilp : Predicate<"Subtarget->hasStdExtZicfilp()">,
                        AssemblerPredicate<(all_of FeatureStdExtZicfilp),
                                           "'Zicfilp' (Landing pad)">;
@@ -164,6 +190,7 @@ def FeatureStdExtZicfiss
     : RISCVExperimentalExtension<"zicfiss", 0, 4,
                                  "'Zicfiss' (Shadow stack)",
                                  [FeatureStdExtZicsr, FeatureStdExtZimop]>;
+def : RISCVExtensionBitmask<"zicfiss", 0, 19>;
 def HasStdExtZicfiss : Predicate<"Subtarget->hasStdExtZicfiss()">,
                        AssemblerPredicate<(all_of FeatureStdExtZicfiss),
                                           "'Zicfiss' (Shadow stack)">;
@@ -174,6 +201,7 @@ def NoHasStdExtZicfiss : Predicate<"!Subtarget->hasStdExtZicfiss()">;
 def FeatureStdExtM
     : RISCVExtension<"m", 2, 0,
                      "'M' (Integer Multiplication and Division)">;
+def : RISCVExtensionBitmask<"m", 0, 20>;
 def HasStdExtM : Predicate<"Subtarget->hasStdExtM()">,
                  AssemblerPredicate<(all_of FeatureStdExtM),
                      "'M' (Integer Multiplication and Division)">;
@@ -181,6 +209,7 @@ def HasStdExtM : Predicate<"Subtarget->hasStdExtM()">,
 def FeatureStdExtZmmul
     : RISCVExtension<"zmmul", 1, 0,
                      "'Zmmul' (Integer Multiplication)">;
+def : RISCVExtensionBitmask<"zmmul", 0, 21>;
 
 def HasStdExtMOrZmmul
     : Predicate<"Subtarget->hasStdExtM() || Subtarget->hasStdExtZmmul()">,
@@ -193,6 +222,7 @@ def HasStdExtMOrZmmul
 def FeatureStdExtA
     : RISCVExtension<"a", 2, 1,
                      "'A' (Atomic Instructions)">;
+def : RISCVExtensionBitmask<"a", 0, 22>;
 def HasStdExtA : Predicate<"Subtarget->hasStdExtA()">,
                  AssemblerPredicate<(all_of FeatureStdExtA),
                                     "'A' (Atomic Instructions)">;
@@ -200,6 +230,7 @@ def HasStdExtA : Predicate<"Subtarget->hasStdExtA()">,
 def FeatureStdExtZtso
     : RISCVExperimentalExtension<"ztso", 0, 1,
                                  "'Ztso' (Memory Model - Total Store Order)">;
+def : RISCVExtensionBitmask<"ztso", 0, 23>;
 def HasStdExtZtso : Predicate<"Subtarget->hasStdExtZtso()">,
                     AssemblerPredicate<(all_of FeatureStdExtZtso),
                         "'Ztso' (Memory Model - Total Store Order)">;
@@ -207,13 +238,16 @@ def NotHasStdExtZtso : Predicate<"!Subtarget->hasStdExtZtso()">;
 
 def FeatureStdExtZa64rs : RISCVExtension<"za64rs", 1, 0,
                                          "'Za64rs' (Reservation Set Size of at Most 64 Bytes)">;
+def : RISCVExtensionBitmask<"za64rs", 0, 24>;
 
 def FeatureStdExtZa128rs : RISCVExtension<"za128rs", 1, 0,
                                           "'Za128rs' (Reservation Set Size of at Most 128 Bytes)">;
+def : RISCVExtensionBitmask<"za128rs", 0, 25>;
 
 def FeatureStdExtZaamo
     : RISCVExtension<"zaamo", 1, 0,
                      "'Zaamo' (Atomic Memory Operations)">;
+def : RISCVExtensionBitmask<"zaamo", 0, 26>;
 def HasStdExtAOrZaamo
     : Predicate<"Subtarget->hasStdExtA() || Subtarget->hasStdExtZaamo()">,
       AssemblerPredicate<(any_of FeatureStdExtA, FeatureStdExtZaamo),
@@ -223,6 +257,7 @@ def HasStdExtAOrZaamo
 def FeatureStdExtZabha
     : RISCVExtension<"zabha", 1, 0,
                      "'Zabha' (Byte and Halfword Atomic Memory Operations)">;
+def : RISCVExtensionBitmask<"zabha", 0, 27>;
 def HasStdExtZabha : Predicate<"Subtarget->hasStdExtZabha()">,
                      AssemblerPredicate<(all_of FeatureStdExtZabha),
                          "'Zabha' (Byte and Halfword Atomic Memory Operations)">;
@@ -230,6 +265,7 @@ def HasStdExtZabha : Predicate<"Subtarget->hasStdExtZabha()">,
 def FeatureStdExtZacas
     : RISCVExtension<"zacas", 1, 0,
                      "'Zacas' (Atomic Compare-And-Swap Instructions)">;
+def : RISCVExtensionBitmask<"zacas", 0, 28>;
 def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">,
                      AssemblerPredicate<(all_of FeatureStdExtZacas),
                          "'Zacas' (Atomic Compare-And-Swap Instructions)">;
@@ -238,6 +274,7 @@ def NoStdExtZacas : Predicate<"!Subtarget->hasStdExtZacas()">;
 def FeatureStdExtZalasr
     : RISCVExperimentalExtension<"zalasr", 0, 1,
                                  "'Zalasr' (Load-Acquire and Store-Release Instructions)">;
+def : RISCVExtensionBitmask<"zalasr", 0, 29>;
 def HasStdExtZalasr : Predicate<"Subtarget->hasStdExtZalasr()">,
                       AssemblerPredicate<(all_of FeatureStdExtZalasr),
                           "'Zalasr' (Load-Acquire and Store-Release Instructions)">;
@@ -245,6 +282,7 @@ def HasStdExtZalasr : Predicate<"Subtarget->hasStdExtZalasr()">,
 def FeatureStdExtZalrsc
     : RISCVExtension<"zalrsc", 1, 0,
                      "'Zalrsc' (Load-Reserved/Store-Conditional)">;
+def : RISCVExtensionBitmask<"zalrsc", 0, 30>;
 def HasStdExtAOrZalrsc
     : Predicate<"Subtarget->hasStdExtA() || Subtarget->hasStdExtZalrsc()">,
       AssemblerPredicate<(any_of FeatureStdExtA, FeatureStdExtZalrsc),
@@ -254,9 +292,11 @@ def HasStdExtAOrZalrsc
 def FeatureStdExtZama16b
     : RISCVExtension<"zama16b", 1, 0,
                      "'Zama16b' (Atomic 16-byte misaligned loads, stores and AMOs)">;
+def : RISCVExtensionBitmask<"zama16b", 0, 31>;
 
 def FeatureStdExtZawrs : RISCVExtension<"zawrs", 1, 0,
                                         "'Zawrs' (Wait on Reservation Set)">;
+def : RISCVExtensionBitmask<"zawrs", 0, 32>;
 def HasStdExtZawrs : Predicate<"Subtarget->hasStdExtZawrs()">,
                      AssemblerPredicate<(all_of FeatureStdExtZawrs),
                                         "'Zawrs' (Wait on Reservation Set)">;
@@ -267,6 +307,7 @@ def FeatureStdExtF
     : RISCVExtension<"f", 2, 2,
                      "'F' (Single-Precision Floating-Point)",
                      [FeatureStdExtZicsr]>;
+def : RISCVExtensionBitmask<"f", 0, 33>;
 def HasStdExtF : Predicate<"Subtarget->hasStdExtF()">,
                  AssemblerPredicate<(all_of FeatureStdExtF),
                                     "'F' (Single-Precision Floating-Point)">;
@@ -275,6 +316,7 @@ def FeatureStdExtD
     : RISCVExtension<"d", 2, 2,
                      "'D' (Double-Precision Floating-Point)",
                      [FeatureStdExtF]>;
+def : RISCVExtensionBitmask<"d", 0, 34>;
 def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
                  AssemblerPredicate<(all_of FeatureStdExtD),
                                     "'D' (Double-Precision Floating-Point)">;
@@ -283,6 +325,7 @@ def FeatureStdExtZfhmin
     : RISCVExtension<"zfhmin", 1, 0,
                      "'Zfhmin' (Half-Precision Floating-Point Minimal)",
                      [FeatureStdExtF]>;
+def : RISCVExtensionBitmask<"zfhmin", 0, 35>;
 def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">,
                       AssemblerPredicate<(all_of FeatureStdExtZfhmin),
                           "'Zfh' (Half-Precision Floating-Point) or "
@@ -292,6 +335,7 @@ def FeatureStdExtZfh
     : RISCVExtension<"zfh", 1, 0,
                      "'Zfh' (Half-Precision Floating-Point)",
                      [FeatureStdExtZfhmin]>;
+def : RISCVExtensionBitmask<"zfh", 0, 36>;
 def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">,
                    AssemblerPredicate<(all_of FeatureStdExtZfh),
                        "'Zfh' (Half-Precision Floating-Point)">;
@@ -301,6 +345,7 @@ def FeatureStdExtZfbfmin
     : RISCVExperimentalExtension<"zfbfmin", 1, 0,
                                  "'Zfbfmin' (Scalar BF16 Converts)",
                                  [FeatureStdExtF]>;
+def : RISCVExtensionBitmask<"zfbfmin", 0, 37>;
 def HasStdExtZfbfmin : Predicate<"Subtarget->hasStdExtZfbfmin()">,
                        AssemblerPredicate<(all_of FeatureStdExtZfbfmin),
                                           "'Zfbfmin' (Scalar BF16 Converts)">;
@@ -317,6 +362,7 @@ def FeatureStdExtZfa
     : RISCVExtension<"zfa", 1, 0,
                      "'Zfa' (Additional Floating-Point)",
                      [FeatureStdExtF]>;
+def : RISCVExtensionBitmask<"zfa", 0, 38>;
 def HasStdExtZfa : Predicate<"Subtarget->hasStdExtZfa()">,
                    AssemblerPredicate<(all_of FeatureStdExtZfa),
                                       "'Zfa' (Additional Floating-Point)">;
@@ -325,6 +371,7 @@ def FeatureStdExtZfinx
     : RISCVExtension<"zfinx", 1, 0,
                      "'Zfinx' (Float in Integer)",
                      [FeatureStdExtZicsr]>;
+def : RISCVExtensionBitmask<"zfinx", 0, 39>;
 def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">,
                      AssemblerPredicate<(all_of FeatureStdExtZfinx),
                                         "'Zfinx' (Float in Integer)">;
@@ -333,6 +380,7 @@ def FeatureStdExtZdinx
     : RISCVExtension<"zdinx", 1, 0,
                      "'Zdinx' (Double in Integer)",
                      [FeatureStdExtZfinx]>;
+def : RISCVExtensionBitmask<"zdinx", 0, 40>;
 def HasStdExtZdinx : Predicate<"Subtarget->hasStdExtZdinx()">,
                      AssemblerPredicate<(all_of FeatureStdExtZdinx),
                                         "'Zdinx' (Double in Integer)">;
@@ -341,6 +389,7 @@ def FeatureStdExtZhinxmin
     : RISCVExtension<"zhinxmin", 1, 0,
                      "'Zhinxmin' (Half Float in Integer Minimal)",
                      [FeatureStdExtZfinx]>;
+def : RISCVExtensionBitmask<"zhinxmin", 0, 41>;
 def HasStdExtZhinxmin : Predicate<"Subtarget->hasStdExtZhinxmin()">,
                         AssemblerPredicate<(all_of FeatureStdExtZhinxmin),
                             "'Zhinx' (Half Float in Integer) or "
@@ -350,6 +399,7 @@ def FeatureStdExtZhinx
     : RISCVExtension<"zhinx", 1, 0,
                      "'Zhinx' (Half Float in Integer)",
                      [FeatureStdExtZhinxmin]>;
+def : RISCVExtensionBitmask<"zhinx", 0, 42>;
 def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">,
                      AssemblerPredicate<(all_of FeatureStdExtZhinx),
                                         "'Zhinx' (Half Float in Integer)">;
@@ -360,6 +410,7 @@ def NoStdExtZhinx : Predicate<"!Subtarget->hasStdExtZhinx()">;
 def FeatureStdExtC
     : RISCVExtension<"c", 2, 0,
                      "'C' (Compressed Instructions)">;
+def : RISCVExtensionBitmask<"c", 0, 43>;
 def HasStdExtC : Predicate<"Subtarget->hasStdExtC()">,
                  AssemblerPredicate<(all_of FeatureStdExtC),
                                     "'C' (Compressed Instructions)">;
@@ -375,6 +426,7 @@ def FeatureStdExtZca
     : RISCVExtension<"zca", 1, 0,
                      "'Zca' (part of the C extension, excluding compressed "
                      "floating point loads/stores)">;
+def : RISCVExtensionBitmask<"zca", 0, 44>;
 
 def HasStdExtCOrZca
     : Predicate<"Subtarget->hasStdExtCOrZca()">,
@@ -387,6 +439,7 @@ def FeatureStdExtZcb
     : RISCVExtension<"zcb", 1, 0,
                      "'Zcb' (Compressed basic bit manipulation instructions)",
                      [FeatureStdExtZca]>;
+def : RISCVExtensionBitmask<"zcb", 0, 45>;
 def HasStdExtZcb : Predicate<"Subtarget->hasStdExtZcb()">,
                    AssemblerPredicate<(all_of FeatureStdExtZcb),
                        "'Zcb' (Compressed basic bit manipulation instructions)">;
@@ -395,6 +448,7 @@ def FeatureStdExtZcd
     : RISCVExtension<"zcd", 1, 0,
                      "'Zcd' (Compressed Double-Precision Floating-Point Instructions)",
                      [FeatureStdExtD, FeatureStdExtZca]>;
+def : RISCVExtensionBitmask<"zcd", 0, 46>;
 
 def HasStdExtCOrZcd
     : Predicate<"Subtarget->hasStdExtCOrZcd()">,
@@ -406,11 +460,13 @@ def FeatureStdExtZcf
     : RISCVExtension<"zcf", 1, 0,
                      "'Zcf' (Compressed Single-Precision Floating-Point Instructions)",
                      [FeatureStdExtF, FeatureStdExtZca]>;
+def : RISCVExtensionBitmask<"zcf", 0, 47>;
 
 def FeatureStdExtZcmp
     : RISCVExtension<"zcmp", 1, 0,
                      "'Zcmp' (sequenced instuctions for code-size reduction)",
                      [FeatureStdExtZca]>;
+def : RISCVExtensionBitmask<"zcmp", 0, 48>;
 def HasStdExtZcmp : Predicate<"Subtarget->hasStdExtZcmp() && !Subtarget->hasStdExtC()">,
                     AssemblerPredicate<(all_of FeatureStdExtZcmp),
                         "'Zcmp' (sequenced instuctions for code-size reduction)">;
@@ -419,6 +475,7 @@ def FeatureStdExtZcmt
     : RISCVExtension<"zcmt", 1, 0,
                      "'Zcmt' (table jump instuctions for code-size reduction)",
                      [FeatureStdExtZca, FeatureStdExtZicsr]>;
+def : RISCVExtensionBitmask<"zcmt", 0, 49>;
 def HasStdExtZcmt : Predicate<"Subtarget->hasStdExtZcmt()">,
                            AssemblerPredicate<(all_of FeatureStdExtZcmt),
                            "'Zcmt' (table jump instuctions for ...
[truncated]

Copy link

github-actions bot commented Jun 5, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@wangpc-pp wangpc-pp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add tests to llvm/test/TableGen/riscv-target-def.td.

@BeMg BeMg requested review from kito-cheng and wangpc-pp June 5, 2024 11:13
@BeMg
Copy link
Contributor Author

BeMg commented Jun 5, 2024

You can add tests to llvm/test/TableGen/riscv-target-def.td.

Thanks your advice. Update test with bitmask table

@topperc
Copy link
Collaborator

topperc commented Jun 6, 2024

I'm not sure we should allocate bits for extensions that aren't supported by hwprobe. Without hwprobe or another enumeration method, the multiversion function that uses a feature that isn't in hwprobe will always never be called. Does that give users false hope?

Should we try to keep the most common features in the same group as long as we can? Like F and V in the same group.

@jrtc27
Copy link
Collaborator

jrtc27 commented Jun 6, 2024

I'm not sure we should allocate bits for extensions that aren't supported by hwprobe. Without hwprobe or another enumeration method, the multiversion function that uses a feature that isn't in hwprobe will always never be called. Does that give users false hope?

Should we try to keep the most common features in the same group as long as we can? Like F and V in the same group.

hwprobe is Linux-specific, this proposed interface (which I don’t love, but at least it’s not hwprobe) is not. And it can still fail at run time if you run on an OS that doesn’t yet support the extension.

@topperc
Copy link
Collaborator

topperc commented Jun 6, 2024

I'm not sure we should allocate bits for extensions that aren't supported by hwprobe. Without hwprobe or another enumeration method, the multiversion function that uses a feature that isn't in hwprobe will always never be called. Does that give users false hope?
Should we try to keep the most common features in the same group as long as we can? Like F and V in the same group.

hwprobe is Linux-specific, this proposed interface (which I don’t love, but at least it’s not hwprobe) is not. And it can still fail at run time if you run on an OS that doesn’t yet support the extension.

Do you envision that other OSes that aren't Linux will support more extensions than what hwprobe supports? Or that hwprobe will grow to support all extensions?

I'm just not sure we should we allocate bit positions that no OS will expose.

@BeMg
Copy link
Contributor Author

BeMg commented Jun 13, 2024

Remove extension bitmasks as no platform can check these extensions; add them back when platforms are ready.

@BeMg
Copy link
Contributor Author

BeMg commented Jun 13, 2024

I'm not sure we should allocate bits for extensions that aren't supported by hwprobe. Without hwprobe or another enumeration method, the multiversion function that uses a feature that isn't in hwprobe will always never be called. Does that give users false hope?

Removed some never be detected extensions.

Should we try to keep the most common features in the same group as long as we can? Like F and V in the same group.

In my thought, we should remain this abstract layer more expressive (By assigning individual bitmasks to each queryable extension), ensuring compatibility with different platforms.

@BeMg BeMg requested review from topperc, 4vtomat and wangpc-pp June 13, 2024 08:41
@BeMg BeMg requested a review from topperc June 24, 2024 05:31
@BeMg BeMg force-pushed the IFUNC/Add-extension-bitmask branch from 7329954 to 8e03d8c Compare July 11, 2024 10:28
@BeMg
Copy link
Contributor Author

BeMg commented Jul 11, 2024

Rebase and align the bitmask with riscv-non-isa/riscv-c-api-doc#74.

@BeMg BeMg requested a review from topperc July 14, 2024 11:08
@BeMg BeMg requested a review from topperc July 16, 2024 02:50
@topperc topperc requested a review from preames July 16, 2024 03:00
Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

BeMg added 7 commits July 20, 2024 01:40
Base on riscv-non-isa/riscv-c-api-doc#74.

This patch defines the groupid/bitmask in RISCVFeatures.td and generates the corresponding table in RISCVTargetParserDef.inc.

The groupid/bitmask of extensions provides an abstraction layer between the compiler and runtime functions.
@BeMg BeMg force-pushed the IFUNC/Add-extension-bitmask branch from c0e1808 to 34310c2 Compare July 22, 2024 04:12
@BeMg
Copy link
Contributor Author

BeMg commented Jul 22, 2024

Rebase and add one more condition after lower_bound result.

Copy link
Contributor

@wangpc-pp wangpc-pp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@BeMg BeMg merged commit f4d4ce1 into llvm:main Jul 22, 2024
7 checks passed
} // namespace

static RISCVExtensionBitmaskTable::RISCVExtensionBitmask
getExtensionBitmask(StringRef ExtName) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this function is not used in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reminder and sorry for breaking the buildbot.

yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
Base on riscv-non-isa/riscv-c-api-doc#74.

This patch defines the groupid/bitmask in RISCVFeatures.td and generates
the corresponding table in RISCVTargetParserDef.inc.

The groupid/bitmask of extensions provides an abstraction layer between
the compiler and runtime functions.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60251500
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants