[llvm] 64d5aed - [TableGen] Add log bang operator

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 26 09:16:55 PDT 2022


Author: Michael Maitland
Date: 2022-10-26T09:16:32-07:00
New Revision: 64d5aedd0637892c5b19c145f3cebf487510d9bf

URL: https://github.com/llvm/llvm-project/commit/64d5aedd0637892c5b19c145f3cebf487510d9bf
DIFF: https://github.com/llvm/llvm-project/commit/64d5aedd0637892c5b19c145f3cebf487510d9bf.diff

LOG: [TableGen] Add log bang operator

This patch adds base 2 logarithm that returns integer result. I initially wanted to name it `!log2`,
but numbers are not permitted in the name. The documentation makes sure to clarify that it is
base 2 since it is not explicit in the operator name.

Differential Revision: https://reviews.llvm.org/D134068

Added: 
    

Modified: 
    llvm/docs/TableGen/ProgRef.rst
    llvm/include/llvm/TableGen/Record.h
    llvm/lib/TableGen/Record.cpp
    llvm/lib/TableGen/TGLexer.cpp
    llvm/lib/TableGen/TGLexer.h
    llvm/lib/TableGen/TGParser.cpp
    llvm/test/TableGen/math.td

Removed: 
    


################################################################################
diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 99835f98287cf..3ced39e8ad386 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -223,10 +223,10 @@ TableGen provides "bang operators" that have a wide variety of uses:
                : !div        !empty       !eq          !filter      !find
                : !foldl      !foreach     !ge          !getdagop    !gt
                : !head       !if          !interleave  !isa         !le
-               : !listconcat !listsplat   !lt          !mul         !ne
-               : !not        !or          !setdagop    !shl         !size
-               : !sra        !srl         !strconcat   !sub         !subst
-               : !substr     !tail        !xor
+               : !listconcat !listsplat   !logtwo      !lt          !mul
+               : !ne         !not         !or          !setdagop    !shl
+               : !size       !sra         !srl         !strconcat   !sub
+               : !subst      !substr      !tail        !xor
 
 The ``!cond`` operator has a slightly 
diff erent
 syntax compared to other bang operators, so it is defined separately:
@@ -1745,6 +1745,11 @@ and non-0 as true.
     equal to the *value*. For example, ``!listsplat(42, 3)`` results in
     ``[42, 42, 42]``.
 
+``!logtwo(``\ *a*\ ``)``
+    This operator produces the base 2 log of *a* and produces the integer
+    result. The log of 0 or a negative number produces an error. This
+    is a flooring operation.
+
 ``!lt(``\ *a*\ `,` *b*\ ``)``
     This operator produces 1 if *a* is less than *b*; 0 otherwise.
     The arguments must be ``bit``, ``bits``, ``int``, or ``string`` values.

diff  --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 3e9e90d7802fb..017beb3688054 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -784,7 +784,7 @@ class OpInit : public TypedInit {
 ///
 class UnOpInit : public OpInit, public FoldingSetNode {
 public:
-  enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP };
+  enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP, LOG2 };
 
 private:
   Init *LHS;

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 5f706ea2893a1..de0797181a7b4 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -24,6 +24,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/SMLoc.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TableGen/Error.h"
@@ -885,6 +886,23 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
       }
     }
     break;
+
+  case LOG2:
+    if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
+            LHS->convertInitializerTo(IntRecTy::get(RK)))) {
+      int64_t LHSv = LHSi->getValue();
+      if (LHSv <= 0) {
+        PrintFatalError(CurRec->getLoc(),
+                        "Illegal operation: logtwo is undefined "
+                        "on arguments less than or equal to 0");
+      } else {
+        uint64_t Log = Log2_64(LHSv);
+        assert(Log <= INT64_MAX &&
+               "Log of an int64_t must be smaller than INT64_MAX");
+        return IntInit::get(RK, static_cast<int64_t>(Log));
+      }
+    }
+    break;
   }
   return const_cast<UnOpInit *>(this);
 }
@@ -908,6 +926,7 @@ std::string UnOpInit::getAsString() const {
   case SIZE: Result = "!size"; break;
   case EMPTY: Result = "!empty"; break;
   case GETDAGOP: Result = "!getdagop"; break;
+  case LOG2 : Result = "!logtwo"; break;
   }
   return Result + "(" + LHS->getAsString() + ")";
 }

diff  --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index c7c8ffe51f67c..34a04e4a506f2 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -569,6 +569,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
     .Case("mul", tgtok::XMUL)
     .Case("div", tgtok::XDIV)
     .Case("not", tgtok::XNOT)
+    .Case("logtwo", tgtok::XLOG2)
     .Case("and", tgtok::XAND)
     .Case("or", tgtok::XOR)
     .Case("xor", tgtok::XXOR)

diff  --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index a1c08fe5bd224..cf1746f70bca6 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -52,9 +52,9 @@ namespace tgtok {
     String, Then, TrueKW,
 
     // Bang operators.
-    XConcat, XADD, XSUB, XMUL, XDIV, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
-    XListConcat, XListSplat, XStrConcat, XInterleave, XSubstr, XFind, XCast,
-    XSubst, XForEach, XFilter, XFoldl, XHead, XTail, XSize, XEmpty, XIf,
+    XConcat, XADD, XSUB, XMUL, XDIV, XNOT, XLOG2, XAND, XOR, XXOR, XSRA, XSRL,
+    XSHL, XListConcat, XListSplat, XStrConcat, XInterleave, XSubstr, XFind,
+    XCast, XSubst, XForEach, XFilter, XFoldl, XHead, XTail, XSize, XEmpty, XIf,
     XCond, XEq, XIsA, XDag, XNe, XLe, XLt, XGe, XGt, XSetDagOp, XGetDagOp,
     XExists,
 

diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 4608d892f2320..094a73a7de2b2 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -945,6 +945,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
     TokError("unknown bang operator");
     return nullptr;
   case tgtok::XNOT:
+  case tgtok::XLOG2:
   case tgtok::XHead:
   case tgtok::XTail:
   case tgtok::XSize:
@@ -973,6 +974,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
       Code = UnOpInit::NOT;
       Type = IntRecTy::get(Records);
       break;
+    case tgtok::XLOG2:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::LOG2;
+      Type = IntRecTy::get(Records);
+      break;
     case tgtok::XHead:
       Lex.Lex();  // eat the operation
       Code = UnOpInit::HEAD;
@@ -2433,6 +2439,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
   case tgtok::XMUL:
   case tgtok::XDIV:
   case tgtok::XNOT:
+  case tgtok::XLOG2:
   case tgtok::XAND:
   case tgtok::XOR:
   case tgtok::XXOR:

diff  --git a/llvm/test/TableGen/math.td b/llvm/test/TableGen/math.td
index 07cfb33532834..64151a5ca0075 100644
--- a/llvm/test/TableGen/math.td
+++ b/llvm/test/TableGen/math.td
@@ -1,6 +1,8 @@
 // RUN: llvm-tblgen %s | FileCheck %s
 // RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
 // RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
+// RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s
+// RUN: not llvm-tblgen -DERROR4 %s 2>&1 | FileCheck --check-prefix=ERROR4 %s
 // XFAIL: vg_leak
 
 // CHECK: def shifts
@@ -116,6 +118,28 @@ def v924   : Int<!mul(v84.Value, 11)>;
 // CHECK: Value = 925
 def v925 : Int<!sub(v924.Value, -1)>;
 
+// CHECK: def v950
+// CHECK: Value = 4
+def v950: Int<!logtwo(16)>;
+
+// CHECK: def v951
+// CHECK: Value = 10
+def v951 : Int<!logtwo(1024)>;
+
+// CHECK: def v952
+// CHECK: Value = 10
+def v952 : Int<!logtwo(1025)>;
+
+#ifdef ERROR3
+// ERROR3: error: Illegal operation: logtwo is undefined on arguments less than or equal to 0
+def v953 : Int<!logtwo(0)>;
+#endif
+
+#ifdef ERROR4
+// ERROR4: error: Illegal operation: logtwo is undefined on arguments less than or equal to 0
+def v954 : Int<!logtwo(-1)>;
+#endif
+
 // CHECK: def vneg
 // CHECK: Value = -2
-def vneg : Int<!sub(v925.Value, 927)>;
\ No newline at end of file
+def vneg : Int<!sub(v925.Value, 927)>;


        


More information about the llvm-commits mailing list