Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions llvm/docs/TableGen/ProgRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
-----------------------
Expand Down Expand Up @@ -1819,6 +1820,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.
Expand Down Expand Up @@ -1949,6 +1954,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
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/TableGen/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@ class UnOpInit final : public OpInit, public FoldingSetNode {
SIZE,
EMPTY,
GETDAGOP,
GETDAGOPNAME,
LOG2,
REPR,
LISTFLATTEN,
Expand Down Expand Up @@ -910,6 +911,7 @@ class BinOpInit final : public OpInit, public FoldingSetNode {
GETDAGARG,
GETDAGNAME,
SETDAGOP,
SETDAGOPNAME
};

private:
Expand Down
22 changes: 21 additions & 1 deletion llvm/lib/TableGen/Record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)))) {
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -1310,7 +1319,7 @@ 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);
return DagInit::get(Op, LHSs->getName(), Args);
Copy link
Contributor

Choose a reason for hiding this comment

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

See comment below, should we choose the non-empty name if LHS name is empty but LHS not?

Copy link
Member Author

Choose a reason for hiding this comment

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

I am certainly not opposed to doing so. I didn't do it initially in order to ensure consistency of behaviour (i.e. always using the name of the LHS regardless of whether it exists). However, perhaps I should favour the LHS name if set and use the RHS name if the LHS name isn't.
I should also perhaps add a note about that behaviour in the documentation. Please let me know what you think.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that might be better. Use lhs name if it's not empty else use rhs name. When both names exist, we have a choice of just using lhs, or using lhs if it matches rhs else concat the names with some delimiter. But just something simple like lhs or rhs name seems reasonable.

}
break;
}
Expand Down Expand Up @@ -1508,6 +1517,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:
Expand Down Expand Up @@ -1620,6 +1637,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;
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/TableGen/TGLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/TableGen/TGLexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ enum TokKind {
XGt,
XSetDagOp,
XGetDagOp,
XSetDagOpName,
XGetDagOpName,
XExists,
XListRemove,
XToLower,
Expand Down
65 changes: 45 additions & 20 deletions llvm/lib/TableGen/TGParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1547,9 +1555,18 @@ const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
case tgtok::XListRemove:
Code = BinOpInit::LISTREMOVE;
break;
case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break;
case tgtok::XSetDagOp: Code = BinOpInit::SETDAGOP; break;
case tgtok::XStrConcat:
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like unrelated formatting change. Can you undo it? Or did clang-format do it?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was done by git-clang-format because I added the tgtok::XSetDagOpName and attempted to format it the same as the rest. I can certainly undo it if you insist though.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, if we can undo that would be good. Additionally the new code now is formatted differently. May be we can run clang-format on this file wholesale after this PR goes in.

So for now, let's undo formatting changes to code not touched by this change. Thanks.

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;
Expand Down Expand Up @@ -1580,6 +1597,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);
Expand Down Expand Up @@ -1773,22 +1794,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))
Expand Down
14 changes: 14 additions & 0 deletions llvm/test/TableGen/getsetop.td
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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"]);

Expand Down
6 changes: 6 additions & 0 deletions llvm/test/TableGen/unsetop.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 1, 2);
Copy link
Contributor

Choose a reason for hiding this comment

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

For these 2, should we choose the rhs name if the lhs one is empty?

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)'
Expand Down
Loading