diff options
| -rw-r--r-- | llvm/docs/TableGen/ProgRef.rst | 39 | ||||
| -rw-r--r-- | llvm/include/llvm/TableGen/Record.h | 2 | ||||
| -rw-r--r-- | llvm/lib/TableGen/Record.cpp | 26 | ||||
| -rw-r--r-- | llvm/lib/TableGen/TGLexer.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/TableGen/TGLexer.h | 2 | ||||
| -rw-r--r-- | llvm/lib/TableGen/TGParser.cpp | 53 | ||||
| -rw-r--r-- | llvm/test/TableGen/getsetop.td | 14 | ||||
| -rw-r--r-- | llvm/test/TableGen/unsetop.td | 6 |
8 files changed, 112 insertions, 32 deletions
diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst index 7b30698..2b1af05 100644 --- a/llvm/docs/TableGen/ProgRef.rst +++ b/llvm/docs/TableGen/ProgRef.rst @@ -219,17 +219,17 @@ TableGen provides "bang operators" that have a wide variety of uses: .. productionlist:: BangOperator: one of - : !add !and !cast !con !dag - : !div !empty !eq !exists !filter - : !find !foldl !foreach !ge !getdagarg - : !getdagname !getdagop !gt !head !if - : !initialized !instances !interleave !isa !le - : !listconcat !listflatten !listremove !listsplat !logtwo - : !lt !match !mul !ne !not - : !or !range !repr !setdagarg !setdagname - : !setdagop !shl !size !sra !srl - : !strconcat !sub !subst !substr !tail - : !tolower !toupper !xor + : !add !and !cast !con !dag + : !div !empty !eq !exists !filter + : !find !foldl !foreach !ge !getdagarg + : !getdagname !getdagop !getdagopname !gt !head + : !if !initialized !instances !interleave !isa + : !le !listconcat !listflatten !listremove !listsplat + : !logtwo !lt !match !mul !ne + : !not !or !range !repr !setdagarg + : !setdagname !setdagop !setdagopname !shl !size + : !sra !srl !strconcat !sub !subst + : !substr !tail !tolower !toupper !xor The ``!cond`` operator has a slightly different syntax compared to other bang operators, so it is defined separately: @@ -1443,7 +1443,8 @@ DAG. The following bang operators are useful for working with DAGs: ``!con``, ``!dag``, ``!empty``, ``!foreach``, ``!getdagarg``, ``!getdagname``, -``!getdagop``, ``!setdagarg``, ``!setdagname``, ``!setdagop``, ``!size``. +``!getdagop``, ``!getdagopname``, ``!setdagarg``, ``!setdagname``, ``!setdagop``, +``!setdagopname``, ``!size``. Defvar in a record body ----------------------- @@ -1695,9 +1696,11 @@ and non-0 as true. This operator concatenates the DAG nodes *a*, *b*, etc. Their operations must equal. - ``!con((op a1:$name1, a2:$name2), (op b1:$name3))`` + ``!con((op:$lhs a1:$name1, a2:$name2), (op:$rhs b1:$name3))`` - results in the DAG node ``(op a1:$name1, a2:$name2, b1:$name3)``. + results in the DAG node ``(op:$lhs a1:$name1, a2:$name2, b1:$name3)``. + The name of the dag operator is derived from the LHS DAG node if it is + set, otherwise from the RHS DAG node. ``!cond(``\ *cond1* ``:`` *val1*\ ``,`` *cond2* ``:`` *val2*\ ``, ...,`` *condn* ``:`` *valn*\ ``)`` This operator tests *cond1* and returns *val1* if the result is true. @@ -1819,6 +1822,10 @@ and non-0 as true. dag d = !dag(!getdagop(someDag), args, names); +``!getdagopname(``\ *dag*\ ``)`` + This operator retrieves the name of the given *dag* operator. If the operator + has no name associated, ``?`` is returned. + ``!gt(``\ *a*\ `,` *b*\ ``)`` This operator produces 1 if *a* is greater than *b*; 0 otherwise. The arguments must be ``bit``, ``bits``, ``int``, or ``string`` values. @@ -1949,6 +1956,10 @@ and non-0 as true. Example: ``!setdagop((foo 1, 2), bar)`` results in ``(bar 1, 2)``. +``!setdagopname(``\ *dag*\ ``,``\ *name*\ ``)`` + This operator produces a DAG node with the same operator and arguments as + *dag*, but replacing the name of the operator with *name*. + ``!shl(``\ *a*\ ``,`` *count*\ ``)`` This operator shifts *a* left logically by *count* bits and produces the resulting value. The operation is performed on a 64-bit integer; the result diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h index a2b86eb..9d67d8b 100644 --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -841,6 +841,7 @@ public: SIZE, EMPTY, GETDAGOP, + GETDAGOPNAME, LOG2, REPR, LISTFLATTEN, @@ -910,6 +911,7 @@ public: GETDAGARG, GETDAGNAME, SETDAGOP, + SETDAGOPNAME }; private: diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 1f3e5dc..3f318e2 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -985,6 +985,12 @@ const Init *UnOpInit::Fold(const Record *CurRec, bool IsFinal) const { } break; + case GETDAGOPNAME: + if (const auto *Dag = dyn_cast<DagInit>(LHS)) { + return Dag->getName(); + } + break; + case LOG2: if (const auto *LHSi = dyn_cast_or_null<IntInit>( LHS->convertInitializerTo(IntRecTy::get(RK)))) { @@ -1050,6 +1056,9 @@ std::string UnOpInit::getAsString() const { case SIZE: Result = "!size"; break; case EMPTY: Result = "!empty"; break; case GETDAGOP: Result = "!getdagop"; break; + case GETDAGOPNAME: + Result = "!getdagopname"; + break; case LOG2 : Result = "!logtwo"; break; case LISTFLATTEN: Result = "!listflatten"; @@ -1310,7 +1319,11 @@ const Init *BinOpInit::Fold(const Record *CurRec) const { SmallVector<std::pair<const Init *, const StringInit *>, 8> Args; llvm::append_range(Args, LHSs->getArgAndNames()); llvm::append_range(Args, RHSs->getArgAndNames()); - return DagInit::get(Op, Args); + // Use the name of the LHS DAG if it's set, otherwise the name of the RHS. + const auto *NameInit = LHSs->getName(); + if (!NameInit) + NameInit = RHSs->getName(); + return DagInit::get(Op, NameInit, Args); } break; } @@ -1508,6 +1521,14 @@ const Init *BinOpInit::Fold(const Record *CurRec) const { return DagInit::get(Op, Dag->getArgs(), Dag->getArgNames()); break; } + case SETDAGOPNAME: { + const auto *Dag = dyn_cast<DagInit>(LHS); + const auto *Op = dyn_cast<StringInit>(RHS); + if (Dag && Op) + return DagInit::get(Dag->getOperator(), Op, Dag->getArgs(), + Dag->getArgNames()); + break; + } case ADD: case SUB: case MUL: @@ -1620,6 +1641,9 @@ std::string BinOpInit::getAsString() const { case STRCONCAT: Result = "!strconcat"; break; case INTERLEAVE: Result = "!interleave"; break; case SETDAGOP: Result = "!setdagop"; break; + case SETDAGOPNAME: + Result = "!setdagopname"; + break; case GETDAGARG: Result = "!getdagarg<" + getType()->getAsString() + ">"; break; diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp index aea1bb0..c369916 100644 --- a/llvm/lib/TableGen/TGLexer.cpp +++ b/llvm/lib/TableGen/TGLexer.cpp @@ -680,6 +680,8 @@ tgtok::TokKind TGLexer::LexExclaim() { .Case("find", tgtok::XFind) .Cases("setdagop", "setop", tgtok::XSetDagOp) // !setop is deprecated. .Cases("getdagop", "getop", tgtok::XGetDagOp) // !getop is deprecated. + .Case("setdagopname", tgtok::XSetDagOpName) + .Case("getdagopname", tgtok::XGetDagOpName) .Case("getdagarg", tgtok::XGetDagArg) .Case("getdagname", tgtok::XGetDagName) .Case("setdagarg", tgtok::XSetDagArg) diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h index ed7d8f3..5725e39 100644 --- a/llvm/lib/TableGen/TGLexer.h +++ b/llvm/lib/TableGen/TGLexer.h @@ -150,6 +150,8 @@ enum TokKind { XGt, XSetDagOp, XGetDagOp, + XSetDagOpName, + XGetDagOpName, XExists, XListRemove, XToLower, diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp index 62c5355..81b61b1 100644 --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "TGParser.h" +#include "TGLexer.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" @@ -1199,6 +1200,7 @@ const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) { case tgtok::XCast: case tgtok::XRepr: case tgtok::XGetDagOp: + case tgtok::XGetDagOpName: case tgtok::XInitialized: { // Value ::= !unop '(' Value ')' UnOpInit::UnaryOp Code; const RecTy *Type = nullptr; @@ -1287,6 +1289,11 @@ const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) { } Code = UnOpInit::GETDAGOP; break; + case tgtok::XGetDagOpName: + Lex.Lex(); // eat the operation + Type = StringRecTy::get(Records); + Code = UnOpInit::GETDAGOPNAME; + break; case tgtok::XInitialized: Lex.Lex(); // eat the operation Code = UnOpInit::INITIALIZED; @@ -1514,7 +1521,8 @@ const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) { case tgtok::XInterleave: case tgtok::XGetDagArg: case tgtok::XGetDagName: - case tgtok::XSetDagOp: { // Value ::= !binop '(' Value ',' Value ')' + case tgtok::XSetDagOp: + case tgtok::XSetDagOpName: { // Value ::= !binop '(' Value ',' Value ')' tgtok::TokKind OpTok = Lex.getCode(); SMLoc OpLoc = Lex.getLoc(); Lex.Lex(); // eat the operation @@ -1550,6 +1558,9 @@ const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) { case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break; case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break; case tgtok::XSetDagOp: Code = BinOpInit::SETDAGOP; break; + case tgtok::XSetDagOpName: + Code = BinOpInit::SETDAGOPNAME; + break; case tgtok::XGetDagArg: Code = BinOpInit::GETDAGARG; break; @@ -1580,6 +1591,10 @@ const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) { } ArgType = DagRecTy::get(Records); break; + case tgtok::XSetDagOpName: + Type = DagRecTy::get(Records); + ArgType = DagRecTy::get(Records); + break; case tgtok::XGetDagName: Type = StringRecTy::get(Records); ArgType = DagRecTy::get(Records); @@ -1773,22 +1788,26 @@ const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) { // Deal with BinOps whose arguments have different types, by // rewriting ArgType in between them. switch (Code) { - case BinOpInit::SETDAGOP: - // After parsing the first dag argument, switch to expecting - // a record, with no restriction on its superclasses. - ArgType = RecordRecTy::get(Records, {}); - break; - case BinOpInit::GETDAGARG: - // After parsing the first dag argument, expect an index integer or a - // name string. - ArgType = nullptr; - break; - case BinOpInit::GETDAGNAME: - // After parsing the first dag argument, expect an index integer. - ArgType = IntRecTy::get(Records); - break; - default: - break; + case BinOpInit::SETDAGOPNAME: + // After parsing the first dag argument, expect a string. + ArgType = StringRecTy::get(Records); + break; + case BinOpInit::SETDAGOP: + // After parsing the first dag argument, switch to expecting + // a record, with no restriction on its superclasses. + ArgType = RecordRecTy::get(Records, {}); + break; + case BinOpInit::GETDAGARG: + // After parsing the first dag argument, expect an index integer or a + // name string. + ArgType = nullptr; + break; + case BinOpInit::GETDAGNAME: + // After parsing the first dag argument, expect an index integer. + ArgType = IntRecTy::get(Records); + break; + default: + break; } if (!consume(tgtok::comma)) diff --git a/llvm/test/TableGen/getsetop.td b/llvm/test/TableGen/getsetop.td index aac644f..031606f 100644 --- a/llvm/test/TableGen/getsetop.td +++ b/llvm/test/TableGen/getsetop.td @@ -28,6 +28,7 @@ def bob : Super; def test { dag orig = (foo 1, 2:$a, $b); dag another = (qux "hello", $world); + dag named = (foo:$root 1, 2:$a, $b); // CHECK: dag replaceWithBar = (bar 1, 2:$a, ?:$b); dag replaceWithBar = !setop(orig, bar); @@ -41,6 +42,19 @@ def test { // CHECK: dag getopToSetop = (foo "hello", ?:$world); dag getopToSetop = !setdagop(another, !getdagop(orig)); + // CHECK: dag setOpName = (foo:$baz 1, 2:$a, ?:$b); + dag setOpName = !setdagopname(orig, "baz"); + + // CHECK: dag getopNameToSetOpName = (foo:$root 1, 2:$a, ?:$b); + dag getopNameToSetOpName = !setdagopname(orig, !getdagopname(named)); + + // CHECK: dag setOpNameExpl = (foo:$baz 1, 2:$a, ?:$b); + dag setOpNameExpl = !setdagopname((foo 1, 2:$a, $b), "baz"); + + // CHECK: dag getopNameToSetOpNameExpl = (foo:$root 1, 2:$a, ?:$b); + dag getopNameToSetOpNameExpl = + !setdagopname(orig, !getdagopname((foo:$root 1, 2:$a, $b))); + // CHECK: dag getopToBangDag = (foo 1:$a, 2:$b, 3:$c); dag getopToBangDag = !dag(!getdagop(orig), [1, 2, 3], ["a", "b", "c"]); diff --git a/llvm/test/TableGen/unsetop.td b/llvm/test/TableGen/unsetop.td index 7a4f98a..54ede19 100644 --- a/llvm/test/TableGen/unsetop.td +++ b/llvm/test/TableGen/unsetop.td @@ -16,6 +16,12 @@ def test { dag undefSecond = !con((op 1), (? 2)); // CHECK: dag undefBoth = (? 1, 2); dag undefBoth = !con((? 1), (? 2)); + // CHECK: dag namedLHS = (op:$lhs 1, 2); + dag namedLHS = !con((op:$lhs 1), (op 2)); + // CHECK: dag namedRHS = (op:$rhs 1, 2); + dag namedRHS = !con((op 1), (op:$rhs 2)); + // CHECK: dag namedBoth = (op:$lhs 1, 2); + dag namedBoth = !con((op:$lhs 1), (op:$rhs 2)); #ifdef ERROR // ERROR: Concatenated Dag operators do not match: '(op 1)' vs. '(otherop 2)' |
