[clang] [Clang][AArch64]Refactor typespec handling in SveEmitter.cpp (PR #117717)

via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 27 06:02:27 PST 2024


https://github.com/SpencerAbson updated https://github.com/llvm/llvm-project/pull/117717

>From eac5704250a454ede434d4967fb88902b689fce3 Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Tue, 26 Nov 2024 13:49:12 +0000
Subject: [PATCH 1/5] Refactor parts of SveEmitter.cpp

---
 clang/include/clang/Basic/arm_sve.td |  28 +--
 clang/utils/TableGen/SveEmitter.cpp  | 356 ++++++++++++---------------
 2 files changed, 167 insertions(+), 217 deletions(-)

diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td
index d492fae4145b92..3e4eb55213c39e 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -762,14 +762,14 @@ def SVCMPLS_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone,
 ////////////////////////////////////////////////////////////////////////////////
 // While comparisons
 
-def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl",     MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl",     MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl",     MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl",     MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PcPsPiPl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PcPsPiPl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PcPsPiPl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PcPsPiPl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Counting bit
@@ -1365,10 +1365,10 @@ def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl",     MergeNon
 def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl",     MergeNone, "aarch64_sve_whilege", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
 def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl",     MergeNone, "aarch64_sve_whilegt", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
 def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl",     MergeNone, "aarch64_sve_whilegt", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
-def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PcPsPiPl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PcPsPiPl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
+def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, VerifyRuntimeMode]>;
 }
 
 let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2"  in {
@@ -2326,7 +2326,7 @@ let SVETargetGuard = "sve2p1,bf16", SMETargetGuard = "sme2p1,bf16" in {
 // Multi-vector convert to/from floating-point.
 //
 let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in {
-  def SVCVT_F16_X2  : SInst<"svcvt_f16[_f32_x2]", "e2", "f", MergeNone, "aarch64_sve_fcvt_x2", [IsStreaming],[]>;
+  def SVCVT_F16_X2  : SInst<"svcvt_f16[_f32_x2]", "h2", "f", MergeNone, "aarch64_sve_fcvt_x2", [IsStreaming],[]>;
   def SVCVT_BF16_X2 : SInst<"svcvt_bf16[_f32_x2]", "$2", "f", MergeNone, "aarch64_sve_bfcvt_x2", [IsOverloadNone, IsStreaming],[]>;
 
   def SVCVT_F32_U32_X2 : SInst<"svcvt_{d}[_u32_x2]", "2.d2.u", "f",  MergeNone, "aarch64_sve_ucvtf_x2",  [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
@@ -2348,7 +2348,7 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme-f16f16" in {
 // Multi-vector floating-point convert from single-precision to interleaved half-precision/BFloat16
 //
 let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in {
-  def SVCVTN_F16_X2  : SInst<"svcvtn_f16[_f32_x2]", "e2", "f", MergeNone, "aarch64_sve_fcvtn_x2", [IsStreaming],[]>;
+  def SVCVTN_F16_X2  : SInst<"svcvtn_f16[_f32_x2]", "h2", "f", MergeNone, "aarch64_sve_fcvtn_x2", [IsStreaming],[]>;
   def SVCVTN_BF16_X2 : SInst<"svcvtn_bf16[_f32_x2]", "$2", "f", MergeNone, "aarch64_sve_bfcvtn_x2", [IsOverloadNone, IsStreaming],[]>;
 }
 
diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index e8883488f32356..7419658f06bc15 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -50,20 +50,30 @@ using TypeSpec = std::string;
 
 namespace {
 class SVEType {
-  bool Float, Signed, Immediate, Void, Constant, Pointer, BFloat, MFloat;
-  bool DefaultType, IsScalable, Predicate, PredicatePattern, PrefetchOp,
-      Svcount;
+
+  enum TypeKind {
+    Void,
+    Float,
+    SInt,
+    UInt,
+    BFloat16,
+    MFloat8,
+    Svcount,
+    PrefetchOp,
+    PredicatePattern,
+    Predicate
+  };
+  TypeKind Kind;
+  bool Immediate, Constant, Pointer, DefaultType, IsScalable;
   unsigned Bitwidth, ElementBitwidth, NumVectors;
 
 public:
   SVEType() : SVEType("", 'v') {}
 
   SVEType(StringRef TS, char CharMod, unsigned NumVectors = 1)
-      : Float(false), Signed(true), Immediate(false), Void(false),
-        Constant(false), Pointer(false), BFloat(false), MFloat(false),
-        DefaultType(false), IsScalable(true), Predicate(false),
-        PredicatePattern(false), PrefetchOp(false), Svcount(false),
-        Bitwidth(128), ElementBitwidth(~0U), NumVectors(NumVectors) {
+      : Kind(SInt), Immediate(false), Constant(false), Pointer(false),
+        DefaultType(false), IsScalable(true), Bitwidth(128),
+        ElementBitwidth(~0U), NumVectors(NumVectors) {
     if (!TS.empty())
       applyTypespec(TS);
     applyModifier(CharMod);
@@ -74,33 +84,31 @@ class SVEType {
   }
 
   bool isPointer() const { return Pointer; }
-  bool isVoidPointer() const { return Pointer && Void; }
-  bool isSigned() const { return Signed; }
+  bool isConstant() const { return Constant; }
   bool isImmediate() const { return Immediate; }
+  bool isSigned() const { return Kind != UInt; }
   bool isScalar() const { return NumVectors == 0; }
   bool isVector() const { return NumVectors > 0; }
   bool isScalableVector() const { return isVector() && IsScalable; }
   bool isFixedLengthVector() const { return isVector() && !IsScalable; }
-  bool isChar() const { return ElementBitwidth == 8 && !MFloat; }
-  bool isVoid() const { return Void && !Pointer; }
+  bool isChar() const { return ElementBitwidth == 8 && isInteger(); }
+  bool isVoid() const { return Kind == Void; }
   bool isDefault() const { return DefaultType; }
-  bool isFloat() const { return Float && !BFloat && !MFloat; }
-  bool isBFloat() const { return BFloat && !Float && !MFloat; }
-  bool isMFloat() const {
-    return MFloat && !BFloat && !Float;
-  }
-  bool isFloatingPoint() const { return Float || BFloat; }
-  bool isInteger() const {
-    return !isFloatingPoint() && !Predicate && !Svcount;
+  bool isFloat() const { return Kind == Float; }
+  bool isBFloat() const { return Kind == BFloat16; }
+  bool isMFloat() const { return Kind == MFloat8; }
+  bool isTypedPointer() const { return Pointer && Kind != Void; }
+  bool isFloatingPoint() const {
+    return Kind == Float || Kind == BFloat16 || Kind == MFloat8;
   }
+  bool isInteger() const { return Kind == SInt || Kind == UInt; }
   bool isScalarPredicate() const {
-    return !isFloatingPoint() && Predicate && NumVectors == 0;
+    return Kind == Predicate && NumVectors == 0;
   }
-  bool isPredicateVector() const { return Predicate; }
-  bool isPredicatePattern() const { return PredicatePattern; }
-  bool isPrefetchOp() const { return PrefetchOp; }
-  bool isSvcount() const { return Svcount; }
-  bool isConstant() const { return Constant; }
+  bool isPredicate() const { return Kind == Predicate; }
+  bool isPredicatePattern() const { return Kind == PredicatePattern; }
+  bool isPrefetchOp() const { return Kind == PrefetchOp; }
+  bool isSvcount() const { return Kind == Svcount; }
   unsigned getElementSizeInBits() const { return ElementBitwidth; }
   unsigned getNumVectors() const { return NumVectors; }
 
@@ -424,9 +432,7 @@ const std::array<SVEEmitter::ReinterpretTypeInfo, 12> SVEEmitter::Reinterprets =
 //===----------------------------------------------------------------------===//
 
 std::string SVEType::builtin_str() const {
-  std::string S;
-  if (isVoid())
-    return "v";
+  std::string OutStr;
 
   if (isScalarPredicate())
     return "b";
@@ -434,62 +440,81 @@ std::string SVEType::builtin_str() const {
   if (isSvcount())
     return "Qa";
 
-  if (isVoidPointer())
-    S += "v";
-  else if (!isFloatingPoint())
+  if (isVoid()) {
+    OutStr += "v";
+    if (!isPointer())
+      return OutStr;
+  } else if (isFloat()) {
     switch (ElementBitwidth) {
-    case 1: S += "b"; break;
-    case 8: S += "c"; break;
-    case 16: S += "s"; break;
-    case 32: S += "i"; break;
-    case 64: S += "Wi"; break;
-    case 128: S += "LLLi"; break;
-    default: llvm_unreachable("Unhandled case!");
-    }
-  else if (isFloat())
-    switch (ElementBitwidth) {
-    case 16: S += "h"; break;
-    case 32: S += "f"; break;
-    case 64: S += "d"; break;
-    default: llvm_unreachable("Unhandled case!");
+    case 16:
+      OutStr += "h";
+      break;
+    case 32:
+      OutStr += "f";
+      break;
+    case 64:
+      OutStr += "d";
+      break;
+    default:
+      llvm_unreachable("Unhandled float type!");
     }
-  else if (isBFloat()) {
+  } else if (isBFloat()) {
     assert(ElementBitwidth == 16 && "Not a valid BFloat.");
-    S += "y";
+    OutStr += "y";
   } else if (isMFloat()) {
     assert(ElementBitwidth == 8 && "Not a valid MFloat.");
-    S += "m";
+    OutStr += "m";
+  } else {
+    switch (ElementBitwidth) {
+    case 1:
+      OutStr += "b";
+      break;
+    case 8:
+      OutStr += "c";
+      break;
+    case 16:
+      OutStr += "s";
+      break;
+    case 32:
+      OutStr += "i";
+      break;
+    case 64:
+      OutStr += "Wi";
+      break;
+    case 128:
+      OutStr += "LLLi";
+      break;
+    default:
+      llvm_unreachable("Unhandled bitwidth!");
+    }
   }
 
-  if (!isFloatingPoint()) {
-    if ((isChar() || isPointer()) && !isVoidPointer()) {
-      // Make chars and typed pointers explicitly signed.
-      if (Signed)
-        S = "S" + S;
-      else if (!Signed)
-        S = "U" + S;
-    } else if (!isVoidPointer() && !Signed) {
-      S = "U" + S;
-    }
+  // Make chars and typed pointers explicitly signed.
+  if (!isFloatingPoint() && !isVoid()) {
+    if ((ElementBitwidth == 8 || isPointer()) && isSigned())
+      OutStr = "S" + OutStr;
+    if (!isSigned())
+      OutStr = "U" + OutStr;
   }
 
   // Constant indices are "int", but have the "constant expression" modifier.
   if (isImmediate()) {
-    assert(!isFloat() && "fp immediates are not supported");
-    S = "I" + S;
+    assert(!isFloatingPoint() && "fp immediates are not supported");
+    OutStr = "I" + OutStr;
   }
 
   if (isScalar()) {
-    if (Constant) S += "C";
-    if (Pointer) S += "*";
-    return S;
+    if (Constant)
+      OutStr += "C";
+    if (Pointer)
+      OutStr += "*";
+    return OutStr;
   }
 
   if (isFixedLengthVector())
-    return "V" + utostr(getNumElements() * NumVectors) + S;
-  return "q" + utostr(getNumElements() * NumVectors) + S;
+    return "V" + utostr(getNumElements() * NumVectors) + OutStr;
+  return "q" + utostr(getNumElements() * NumVectors) + OutStr;
 }
-
 std::string SVEType::str() const {
   if (isPredicatePattern())
     return "enum svpattern";
@@ -498,28 +523,30 @@ std::string SVEType::str() const {
     return "enum svprfop";
 
   std::string S;
-  if (Void)
+  if (isVoid())
     S += "void";
   else {
     if (isScalableVector() || isSvcount())
       S += "sv";
-    if (!Signed && !isFloatingPoint())
-      S += "u";
 
-    if (Float)
+    if (isFloat())
       S += "float";
     else if (isSvcount())
       S += "count";
-    else if (isScalarPredicate() || isPredicateVector())
+    else if (isPredicate())
       S += "bool";
     else if (isBFloat())
       S += "bfloat";
     else if (isMFloat())
       S += "mfloat";
-    else
-      S += "int";
+    else {
+      if (isSigned())
+        S += "int";
+      else
+        S += "uint";
+    };
 
-    if (!isScalarPredicate() && !isPredicateVector() && !isSvcount())
+    if (!isPredicate() && !isSvcount())
       S += utostr(ElementBitwidth);
     if (isFixedLengthVector())
       S += "x" + utostr(getNumElements());
@@ -541,13 +568,13 @@ void SVEType::applyTypespec(StringRef TS) {
   for (char I : TS) {
     switch (I) {
     case 'Q':
-      Svcount = true;
+      Kind = Svcount;
       break;
     case 'P':
-      Predicate = true;
+      Kind = Predicate;
       break;
     case 'U':
-      Signed = false;
+      Kind = UInt;
       break;
     case 'c':
       ElementBitwidth = 8;
@@ -565,28 +592,23 @@ void SVEType::applyTypespec(StringRef TS) {
       ElementBitwidth = 128;
       break;
     case 'h':
-      Float = true;
+      Kind = Float;
       ElementBitwidth = 16;
       break;
     case 'f':
-      Float = true;
+      Kind = Float;
       ElementBitwidth = 32;
       break;
     case 'd':
-      Float = true;
+      Kind = Float;
       ElementBitwidth = 64;
       break;
     case 'b':
-      BFloat = true;
-      Float = false;
-      MFloat = false;
+      Kind = BFloat16;
       ElementBitwidth = 16;
       break;
     case 'm':
-      Signed = false;
-      MFloat = true;
-      Float = false;
-      BFloat = false;
+      Kind = MFloat8;
       ElementBitwidth = 8;
       break;
     default:
@@ -599,7 +621,7 @@ void SVEType::applyTypespec(StringRef TS) {
 void SVEType::applyModifier(char Mod) {
   switch (Mod) {
   case 'v':
-    Void = true;
+    Kind = Void;
     break;
   case 'd':
     DefaultType = true;
@@ -613,7 +635,7 @@ void SVEType::applyModifier(char Mod) {
     NumVectors = 0;
     break;
   case 'e':
-    Signed = false;
+    Kind = UInt;
     ElementBitwidth /= 2;
     break;
   case 'h':
@@ -623,20 +645,14 @@ void SVEType::applyModifier(char Mod) {
     ElementBitwidth /= 4;
     break;
   case 'b':
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth /= 4;
     break;
   case 'o':
     ElementBitwidth *= 4;
     break;
   case 'P':
-    Signed = true;
-    Float = false;
-    BFloat = false;
-    Predicate = true;
-    Svcount = false;
+    Kind = Predicate;
     Bitwidth = 16;
     ElementBitwidth = 1;
     break;
@@ -659,105 +675,61 @@ void SVEType::applyModifier(char Mod) {
     NumVectors = 0;
     break;
   case '@':
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth /= 4;
     NumVectors = 0;
     break;
   case 'K':
-    Signed = true;
-    Float = false;
-    BFloat = false;
+    Kind = SInt;
     Bitwidth = ElementBitwidth;
     NumVectors = 0;
     break;
   case 'L':
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     Bitwidth = ElementBitwidth;
     NumVectors = 0;
     break;
   case 'u':
-    Predicate = false;
-    Svcount = false;
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     break;
   case 'x':
-    Predicate = false;
-    Svcount = false;
-    Signed = true;
-    Float = false;
-    BFloat = false;
+    Kind = SInt;
     break;
   case 'i':
-    Predicate = false;
-    Svcount = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth = Bitwidth = 64;
     NumVectors = 0;
-    Signed = false;
     Immediate = true;
     break;
   case 'I':
-    Predicate = false;
-    Svcount = false;
-    Float = false;
-    BFloat = false;
+    Kind = PredicatePattern;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
-    Signed = true;
     Immediate = true;
-    PredicatePattern = true;
     break;
   case 'J':
-    Predicate = false;
-    Svcount = false;
-    Float = false;
-    BFloat = false;
+    Kind = PrefetchOp;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
-    Signed = true;
     Immediate = true;
-    PrefetchOp = true;
     break;
   case 'k':
-    Predicate = false;
-    Svcount = false;
-    Signed = true;
-    Float = false;
-    BFloat = false;
+    Kind = SInt;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
     break;
   case 'l':
-    Predicate = false;
-    Svcount = false;
-    Signed = true;
-    Float = false;
-    BFloat = false;
+    Kind = SInt;
     ElementBitwidth = Bitwidth = 64;
     NumVectors = 0;
     break;
   case 'm':
-    Predicate = false;
-    Svcount = false;
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
     break;
   case 'n':
-    Predicate = false;
-    Svcount = false;
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth = Bitwidth = 64;
     NumVectors = 0;
     break;
@@ -769,162 +741,140 @@ void SVEType::applyModifier(char Mod) {
     NumVectors = 0;
     break;
   case 'f':
-    Signed = false;
+    Kind = UInt;
     ElementBitwidth = Bitwidth = 64;
     NumVectors = 0;
     break;
   case 'g':
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth = 64;
     break;
   case '[':
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth = 8;
     break;
   case 't':
-    Signed = true;
-    Float = false;
-    BFloat = false;
+    Kind = SInt;
     ElementBitwidth = 32;
     break;
   case 'z':
-    Signed = false;
-    Float = false;
-    BFloat = false;
+    Kind = UInt;
     ElementBitwidth = 32;
     break;
   case 'O':
-    Predicate = false;
-    Svcount = false;
-    Float = true;
+    Kind = Float;
     ElementBitwidth = 16;
     break;
   case 'M':
-    Predicate = false;
-    Svcount = false;
-    Float = true;
-    BFloat = false;
+    Kind = Float;
     ElementBitwidth = 32;
     break;
   case 'N':
-    Predicate = false;
-    Svcount = false;
-    Float = true;
+    Kind = Float;
     ElementBitwidth = 64;
     break;
   case 'Q':
+    Kind = Void;
     Constant = true;
     Pointer = true;
-    Void = true;
     NumVectors = 0;
     break;
   case 'S':
+    Kind = SInt;
     Constant = true;
     Pointer = true;
     ElementBitwidth = Bitwidth = 8;
     NumVectors = 0;
-    Signed = true;
     break;
   case 'W':
+    Kind = UInt;
     Constant = true;
     Pointer = true;
     ElementBitwidth = Bitwidth = 8;
     NumVectors = 0;
-    Signed = false;
     break;
   case 'T':
+    Kind = SInt;
     Constant = true;
     Pointer = true;
     ElementBitwidth = Bitwidth = 16;
     NumVectors = 0;
-    Signed = true;
     break;
   case 'X':
+    Kind = UInt;
     Constant = true;
     Pointer = true;
     ElementBitwidth = Bitwidth = 16;
     NumVectors = 0;
-    Signed = false;
     break;
   case 'Y':
+    Kind = UInt;
     Constant = true;
     Pointer = true;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
-    Signed = false;
     break;
   case 'U':
+    Kind = SInt;
     Constant = true;
     Pointer = true;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
-    Signed = true;
     break;
   case '%':
+    Kind = Void;
     Pointer = true;
-    Void = true;
     NumVectors = 0;
     break;
   case 'A':
+    Kind = SInt;
     Pointer = true;
     ElementBitwidth = Bitwidth = 8;
     NumVectors = 0;
-    Signed = true;
     break;
   case 'B':
+    Kind = SInt;
     Pointer = true;
     ElementBitwidth = Bitwidth = 16;
     NumVectors = 0;
-    Signed = true;
     break;
   case 'C':
+    Kind = SInt;
     Pointer = true;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
-    Signed = true;
     break;
   case 'D':
+    Kind = SInt;
     Pointer = true;
     ElementBitwidth = Bitwidth = 64;
     NumVectors = 0;
-    Signed = true;
     break;
   case 'E':
+    Kind = UInt;
     Pointer = true;
     ElementBitwidth = Bitwidth = 8;
     NumVectors = 0;
-    Signed = false;
     break;
   case 'F':
+    Kind = UInt;
     Pointer = true;
     ElementBitwidth = Bitwidth = 16;
     NumVectors = 0;
-    Signed = false;
     break;
   case 'G':
+    Kind = UInt;
     Pointer = true;
     ElementBitwidth = Bitwidth = 32;
     NumVectors = 0;
-    Signed = false;
     break;
   case '$':
-    Predicate = false;
-    Svcount = false;
-    Float = false;
-    BFloat = true;
+    Kind = BFloat16;
     ElementBitwidth = 16;
     break;
   case '}':
-    Predicate = false;
-    Signed = true;
-    Svcount = true;
+    Kind = Svcount;
     NumVectors = 0;
-    Float = false;
-    BFloat = false;
     break;
   case '.':
     llvm_unreachable(". is never a type in itself");
@@ -1048,7 +998,7 @@ std::string Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
       TypeCode = T.isSigned() ? 's' : 'u';
     else if (T.isSvcount())
       TypeCode = 'c';
-    else if (T.isPredicateVector())
+    else if (T.isPredicate())
       TypeCode = 'b';
     else if (T.isBFloat())
       TypeCode = "bf";
@@ -1152,7 +1102,7 @@ uint64_t SVEEmitter::encodeTypeFlags(const SVEType &T) {
     return encodeEltType("EltTyMFloat8");
   }
 
-  if (T.isPredicateVector() || T.isSvcount()) {
+  if (T.isPredicate() || T.isSvcount()) {
     switch (T.getElementSizeInBits()) {
     case 8:
       return encodeEltType("EltTyBool8");

>From 449c564fc18b871d6975e3c473b184866b79cb3b Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Tue, 26 Nov 2024 16:35:51 +0000
Subject: [PATCH 2/5] Replace isSigned()

---
 clang/utils/TableGen/SveEmitter.cpp | 33 ++++++++++++++---------------
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index 7419658f06bc15..a68edd78be57fc 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -86,7 +86,6 @@ class SVEType {
   bool isPointer() const { return Pointer; }
   bool isConstant() const { return Constant; }
   bool isImmediate() const { return Immediate; }
-  bool isSigned() const { return Kind != UInt; }
   bool isScalar() const { return NumVectors == 0; }
   bool isVector() const { return NumVectors > 0; }
   bool isScalableVector() const { return isVector() && IsScalable; }
@@ -97,11 +96,12 @@ class SVEType {
   bool isFloat() const { return Kind == Float; }
   bool isBFloat() const { return Kind == BFloat16; }
   bool isMFloat() const { return Kind == MFloat8; }
-  bool isTypedPointer() const { return Pointer && Kind != Void; }
   bool isFloatingPoint() const {
     return Kind == Float || Kind == BFloat16 || Kind == MFloat8;
   }
   bool isInteger() const { return Kind == SInt || Kind == UInt; }
+  bool isSignedInteger() const { return Kind == SInt; }
+  bool isUnsignedInteger() const { return Kind == UInt; }
   bool isScalarPredicate() const {
     return Kind == Predicate && NumVectors == 0;
   }
@@ -489,13 +489,11 @@ std::string SVEType::builtin_str() const {
     }
   }
 
-  // Make chars and typed pointers explicitly signed.
-  if (!isFloatingPoint() && !isVoid()) {
-    if ((ElementBitwidth == 8 || isPointer()) && isSigned())
-      OutStr = "S" + OutStr;
-    if (!isSigned())
-      OutStr = "U" + OutStr;
-  }
+  // Make chars and integer pointers explicitly signed.
+  if((ElementBitwidth == 8 || isPointer()) && isSignedInteger())
+    OutStr = "S" + OutStr;
+  else if(isUnsignedInteger())
+    OutStr = "U" + OutStr;
 
   // Constant indices are "int", but have the "constant expression" modifier.
   if (isImmediate()) {
@@ -539,12 +537,10 @@ std::string SVEType::str() const {
       S += "bfloat";
     else if (isMFloat())
       S += "mfloat";
-    else {
-      if (isSigned())
-        S += "int";
-      else
-        S += "uint";
-    };
+    else if (isSignedInteger())
+      S += "int";
+    else if (isUnsignedInteger())
+      S += "uint";
 
     if (!isPredicate() && !isSvcount())
       S += utostr(ElementBitwidth);
@@ -994,8 +990,11 @@ std::string Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
 
     // Replace templated arg with the right suffix (e.g. u32)
     std::string TypeCode;
-    if (T.isInteger())
-      TypeCode = T.isSigned() ? 's' : 'u';
+
+    if(T.isSignedInteger())
+      TypeCode = 's';
+    else if (T.isUnsignedInteger())
+      TypeCode = 'u';
     else if (T.isSvcount())
       TypeCode = 'c';
     else if (T.isPredicate())

>From 631932531e98d619b8e7e6399556039ad50e63c7 Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Tue, 26 Nov 2024 16:43:41 +0000
Subject: [PATCH 3/5] [NFC] Fix format

---
 clang/utils/TableGen/SveEmitter.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index a68edd78be57fc..2754a4d2dec023 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -490,9 +490,9 @@ std::string SVEType::builtin_str() const {
   }
 
   // Make chars and integer pointers explicitly signed.
-  if((ElementBitwidth == 8 || isPointer()) && isSignedInteger())
+  if ((ElementBitwidth == 8 || isPointer()) && isSignedInteger())
     OutStr = "S" + OutStr;
-  else if(isUnsignedInteger())
+  else if (isUnsignedInteger())
     OutStr = "U" + OutStr;
 
   // Constant indices are "int", but have the "constant expression" modifier.
@@ -991,7 +991,7 @@ std::string Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
     // Replace templated arg with the right suffix (e.g. u32)
     std::string TypeCode;
 
-    if(T.isSignedInteger())
+    if (T.isSignedInteger())
       TypeCode = 's';
     else if (T.isUnsignedInteger())
       TypeCode = 'u';

>From e0f28dc44eea4ce3078153ca43d2599c8ee828df Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Wed, 27 Nov 2024 13:32:38 +0000
Subject: [PATCH 4/5] Refactor builtin_str()

---
 clang/utils/TableGen/SveEmitter.cpp | 112 ++++++++++++++--------------
 1 file changed, 55 insertions(+), 57 deletions(-)

diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index 2754a4d2dec023..219a68adb18e2a 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -134,6 +134,9 @@ class SVEType {
 
   /// Applies a prototype modifier to the type.
   void applyModifier(char Mod);
+
+  /// Get the builtin base for this SVEType, e.g, 'Wi' for svint64_t.
+  std::string builtinBaseType() const;
 };
 
 class SVEEmitter;
@@ -431,88 +434,82 @@ const std::array<SVEEmitter::ReinterpretTypeInfo, 12> SVEEmitter::Reinterprets =
 // Type implementation
 //===----------------------------------------------------------------------===//
 
-std::string SVEType::builtin_str() const {
-  std::string OutStr;
-
-  if (isScalarPredicate())
-    return "b";
-
-  if (isSvcount())
+std::string SVEType::builtinBaseType() const {
+  switch (Kind) {
+  case TypeKind::Void:
+    return "v";
+  case TypeKind::Svcount:
     return "Qa";
-
-  if (isVoid()) {
-    OutStr += "v";
-    if (!isPointer())
-      return OutStr;
-  } else if (isFloat()) {
+  case TypeKind::BFloat16:
+    assert(ElementBitwidth == 16 && "Invalid BFloat16!");
+    return "y";
+  case TypeKind::MFloat8:
+    assert(ElementBitwidth == 8 && "Invalid MFloat8!");
+    return "c";
+  case TypeKind::Float:
     switch (ElementBitwidth) {
     case 16:
-      OutStr += "h";
-      break;
+      return "h";
     case 32:
-      OutStr += "f";
-      break;
+      return "f";
     case 64:
-      OutStr += "d";
-      break;
+      return "d";
     default:
-      llvm_unreachable("Unhandled float type!");
+      llvm_unreachable("Unhandled float width!");
     }
-  } else if (isBFloat()) {
-    assert(ElementBitwidth == 16 && "Not a valid BFloat.");
-    OutStr += "y";
-  } else if (isMFloat()) {
-    assert(ElementBitwidth == 8 && "Not a valid MFloat.");
-    OutStr += "m";
-  } else {
+  case TypeKind::Predicate:
+    if (isScalar())
+      return "b";
+    [[fallthrough]];
+  // SInt/UInt, PredicatePattern, PrefetchOp.
+  default:
     switch (ElementBitwidth) {
     case 1:
-      OutStr += "b";
-      break;
+      return "b";
     case 8:
-      OutStr += "c";
-      break;
+      return "c";
     case 16:
-      OutStr += "s";
-      break;
+      return "s";
     case 32:
-      OutStr += "i";
-      break;
+      return "i";
     case 64:
-      OutStr += "Wi";
-      break;
+      return "Wi";
     case 128:
-      OutStr += "LLLi";
-      break;
+      return "LLLi";
     default:
       llvm_unreachable("Unhandled bitwidth!");
     }
   }
+}
 
-  // Make chars and integer pointers explicitly signed.
-  if ((ElementBitwidth == 8 || isPointer()) && isSignedInteger())
-    OutStr = "S" + OutStr;
-  else if (isUnsignedInteger())
-    OutStr = "U" + OutStr;
+std::string SVEType::builtin_str() const {
+
+  std::string Prefix;
 
-  // Constant indices are "int", but have the "constant expression" modifier.
-  if (isImmediate()) {
+  if (isScalableVector())
+    Prefix = "q" + llvm::utostr(getNumElements() * NumVectors);
+  else if (isFixedLengthVector())
+    Prefix = "V" + llvm::utostr(getNumElements() * NumVectors);
+  else if (isImmediate()) {
     assert(!isFloatingPoint() && "fp immediates are not supported");
-    OutStr = "I" + OutStr;
+    Prefix = "I";
   }
 
-  if (isScalar()) {
-    if (Constant)
-      OutStr += "C";
-    if (Pointer)
-      OutStr += "*";
-    return OutStr;
-  }
+  // Make chars and integer pointers explicitly signed.
+  if ((ElementBitwidth == 8 || isPointer()) && isSignedInteger())
+    Prefix += "S";
+  else if (isUnsignedInteger())
+    Prefix += "U";
 
-  if (isFixedLengthVector())
-    return "V" + utostr(getNumElements() * NumVectors) + OutStr;
-  return "q" + utostr(getNumElements() * NumVectors) + OutStr;
+  std::string BuiltinStr = Prefix + builtinBaseType();
+  if (isConstant())
+    BuiltinStr += "C";
+  if (isPointer())
+    BuiltinStr += "*";
+
+  return BuiltinStr;
 }
+
 std::string SVEType::str() const {
   if (isPredicatePattern())
     return "enum svpattern";
@@ -618,6 +615,7 @@ void SVEType::applyModifier(char Mod) {
   switch (Mod) {
   case 'v':
     Kind = Void;
+    NumVectors = 0;
     break;
   case 'd':
     DefaultType = true;

>From 1e3ed56243ccd7cebdba01ea82142d43361397bf Mon Sep 17 00:00:00 2001
From: Spencer Abson <Spencer.Abson at arm.com>
Date: Wed, 27 Nov 2024 14:00:10 +0000
Subject: [PATCH 5/5] Refactor SVEType::str()

---
 clang/utils/TableGen/SveEmitter.cpp | 81 +++++++++++++++--------------
 1 file changed, 42 insertions(+), 39 deletions(-)

diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index 219a68adb18e2a..1dd7558f33ea3f 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -511,50 +511,53 @@ std::string SVEType::builtin_str() const {
 }
 
 std::string SVEType::str() const {
-  if (isPredicatePattern())
-    return "enum svpattern";
+  std::string TypeStr;
 
-  if (isPrefetchOp())
+  switch (Kind) {
+  case TypeKind::PrefetchOp:
     return "enum svprfop";
-
-  std::string S;
-  if (isVoid())
-    S += "void";
-  else {
-    if (isScalableVector() || isSvcount())
-      S += "sv";
-
-    if (isFloat())
-      S += "float";
-    else if (isSvcount())
-      S += "count";
-    else if (isPredicate())
-      S += "bool";
-    else if (isBFloat())
-      S += "bfloat";
-    else if (isMFloat())
-      S += "mfloat";
-    else if (isSignedInteger())
-      S += "int";
-    else if (isUnsignedInteger())
-      S += "uint";
-
-    if (!isPredicate() && !isSvcount())
-      S += utostr(ElementBitwidth);
-    if (isFixedLengthVector())
-      S += "x" + utostr(getNumElements());
-    if (NumVectors > 1)
-      S += "x" + utostr(NumVectors);
-    if (!isScalarPredicate())
-      S += "_t";
+  case TypeKind::PredicatePattern:
+    return "enum svpattern";
+  case TypeKind::Void:
+    TypeStr += "void";
+    break;
+  case TypeKind::Float:
+    TypeStr += "float" + llvm::utostr(ElementBitwidth);
+    break;
+  case TypeKind::Svcount:
+    TypeStr += "svcount";
+    break;
+  case TypeKind::Predicate:
+    TypeStr += "bool";
+    break;
+  case TypeKind::BFloat16:
+    TypeStr += "bfloat16";
+    break;
+  case TypeKind::MFloat8:
+    TypeStr += "mfloat8";
+    break;
+  case TypeKind::SInt:
+    TypeStr += "int" + llvm::utostr(ElementBitwidth);
+    break;
+  case TypeKind::UInt:
+    TypeStr += "uint" + llvm::utostr(ElementBitwidth);
   }
 
-  if (Constant)
-    S += " const";
-  if (Pointer)
-    S += " *";
+  if (isFixedLengthVector())
+    TypeStr += "x" + llvm::utostr(getNumElements());
+  else if (isScalableVector())
+    TypeStr = "sv" + TypeStr;
 
-  return S;
+  if (NumVectors > 1)
+    TypeStr += "x" + llvm::utostr(NumVectors);
+  if (!isScalarPredicate() && !isVoid())
+    TypeStr += "_t";
+  if (isConstant())
+    TypeStr += " const";
+  if (isPointer())
+    TypeStr += " *";
+
+  return TypeStr;
 }
 
 void SVEType::applyTypespec(StringRef TS) {



More information about the cfe-commits mailing list