summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
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