summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2018-03-14 11:00:26 +0000
committerNicolai Haehnle <nhaehnle@gmail.com>2018-03-14 11:00:26 +0000
commit6c118656380f5ee8827e73fb6e4fc5aa0950dee4 (patch)
tree0bb7e07dbc5f760d678ab5013bfe8b5bb1947554 /llvm/lib
parent3a17e75be9589517e03f59fe03fc39bebfccd0ce (diff)
downloadbcm5719-llvm-6c118656380f5ee8827e73fb6e4fc5aa0950dee4.tar.gz
bcm5719-llvm-6c118656380f5ee8827e73fb6e4fc5aa0950dee4.zip
TableGen: Add !dag function for construction
This allows constructing DAG nodes with programmatically determined names, and can simplify constructing DAG nodes in other cases as well. Also, add documentation and some very simple tests for the already existing !con. Change-Id: Ida61cd82e99752548d7109ce8da34d29da56a5f7 Differential revision: https://reviews.llvm.org/D44110 llvm-svn: 327492
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/TableGen/Record.cpp25
-rw-r--r--llvm/lib/TableGen/TGLexer.cpp1
-rw-r--r--llvm/lib/TableGen/TGLexer.h2
-rw-r--r--llvm/lib/TableGen/TGParser.cpp39
4 files changed, 66 insertions, 1 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 2fbe4cc493f..48197f04d11 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1114,6 +1114,30 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
}
break;
}
+
+ case DAG: {
+ ListInit *MHSl = dyn_cast<ListInit>(MHS);
+ ListInit *RHSl = dyn_cast<ListInit>(RHS);
+ bool MHSok = MHSl || isa<UnsetInit>(MHS);
+ bool RHSok = RHSl || isa<UnsetInit>(RHS);
+
+ if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
+ break; // Typically prevented by the parser, but might happen with template args
+
+ if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
+ SmallVector<std::pair<Init *, StringInit *>, 8> Children;
+ unsigned Size = MHSl ? MHSl->size() : RHSl->size();
+ for (unsigned i = 0; i != Size; ++i) {
+ Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get();
+ Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get();
+ if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name))
+ return const_cast<TernOpInit *>(this);
+ Children.emplace_back(Node, dyn_cast<StringInit>(Name));
+ }
+ return DagInit::get(LHS, nullptr, Children);
+ }
+ break;
+ }
}
return const_cast<TernOpInit *>(this);
@@ -1155,6 +1179,7 @@ std::string TernOpInit::getAsString() const {
case SUBST: Result = "!subst"; break;
case FOREACH: Result = "!foreach"; break;
case IF: Result = "!if"; break;
+ case DAG: Result = "!dag"; break;
}
return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", " +
RHS->getAsString() + ")";
diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index f833782e203..d4762a42191 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -473,6 +473,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("tail", tgtok::XTail)
.Case("size", tgtok::XSize)
.Case("con", tgtok::XConcat)
+ .Case("dag", tgtok::XDag)
.Case("add", tgtok::XADD)
.Case("and", tgtok::XAND)
.Case("or", tgtok::XOR)
diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index 2ffc2efdc30..18559773d74 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -48,7 +48,7 @@ namespace tgtok {
// !keywords.
XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast,
- XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty, XIf, XEq, XIsA,
+ XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty, XIf, XEq, XIsA, XDag,
// Integer value.
IntVal,
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 5d87bfdf19d..629320975a6 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -1159,6 +1159,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
->Fold(CurRec, CurMultiClass);
}
+ case tgtok::XDag:
case tgtok::XIf:
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
TernOpInit::TernaryOp Code;
@@ -1168,6 +1169,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
Lex.Lex(); // eat the operation
switch (LexCode) {
default: llvm_unreachable("Unhandled code!");
+ case tgtok::XDag:
+ Code = TernOpInit::DAG;
+ Type = DagRecTy::get();
+ ItemType = nullptr;
+ break;
case tgtok::XIf:
Code = TernOpInit::IF;
break;
@@ -1190,6 +1196,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
}
Lex.Lex(); // eat the ','
+ SMLoc MHSLoc = Lex.getLoc();
Init *MHS = ParseValue(CurRec, ItemType);
if (!MHS)
return nullptr;
@@ -1200,6 +1207,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
}
Lex.Lex(); // eat the ','
+ SMLoc RHSLoc = Lex.getLoc();
Init *RHS = ParseValue(CurRec, ItemType);
if (!RHS)
return nullptr;
@@ -1212,6 +1220,36 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
switch (LexCode) {
default: llvm_unreachable("Unhandled code!");
+ case tgtok::XDag: {
+ TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+ if (!MHSt && !isa<UnsetInit>(MHS)) {
+ Error(MHSLoc, "could not determine type of the child list in !dag");
+ return nullptr;
+ }
+ if (MHSt && !isa<ListRecTy>(MHSt->getType())) {
+ Error(MHSLoc, Twine("expected list of children, got type '") +
+ MHSt->getType()->getAsString() + "'");
+ return nullptr;
+ }
+
+ TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+ if (!RHSt && !isa<UnsetInit>(RHS)) {
+ Error(RHSLoc, "could not determine type of the name list in !dag");
+ return nullptr;
+ }
+ if (RHSt && StringRecTy::get()->getListTy() != RHSt->getType()) {
+ Error(RHSLoc, Twine("expected list<string>, got type '") +
+ RHSt->getType()->getAsString() + "'");
+ return nullptr;
+ }
+
+ if (!MHSt && !RHSt) {
+ Error(MHSLoc,
+ "cannot have both unset children and unset names in !dag");
+ return nullptr;
+ }
+ break;
+ }
case tgtok::XIf: {
RecTy *MHSTy = nullptr;
RecTy *RHSTy = nullptr;
@@ -1728,6 +1766,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XCast: // Value ::= !unop '(' Value ')'
case tgtok::XIsA:
case tgtok::XConcat:
+ case tgtok::XDag:
case tgtok::XADD:
case tgtok::XAND:
case tgtok::XOR:
OpenPOWER on IntegriCloud