[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