summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2018-03-09 12:24:06 +0000
committerNicolai Haehnle <nhaehnle@gmail.com>2018-03-09 12:24:06 +0000
commitb537605956400d62729cebc9d5d053c45aa5f4c5 (patch)
tree309691df62219727c021261ba83e0dd95a1082f3 /llvm/lib
parent47c3472c412b79ccd9df9b1461910127df0d1d97 (diff)
downloadbcm5719-llvm-b537605956400d62729cebc9d5d053c45aa5f4c5.tar.gz
bcm5719-llvm-b537605956400d62729cebc9d5d053c45aa5f4c5.zip
TableGen: add !isa operation
Change-Id: Iddb724c3ae706d82933a2d82c91d07e0e36b30e3 Differential revision: https://reviews.llvm.org/D44105 llvm-svn: 327117
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/TableGen/Record.cpp62
-rw-r--r--llvm/lib/TableGen/TGLexer.cpp1
-rw-r--r--llvm/lib/TableGen/TGLexer.h2
-rw-r--r--llvm/lib/TableGen/TGParser.cpp28
4 files changed, 92 insertions, 1 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index c1344aea4eb..76bbe7a0e5d 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1231,6 +1231,68 @@ std::string FoldOpInit::getAsString() const {
.str();
}
+static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType,
+ Init *Expr) {
+ ID.AddPointer(CheckType);
+ ID.AddPointer(Expr);
+}
+
+IsAOpInit *IsAOpInit::get(RecTy *CheckType, Init *Expr) {
+ static FoldingSet<IsAOpInit> ThePool;
+
+ FoldingSetNodeID ID;
+ ProfileIsAOpInit(ID, CheckType, Expr);
+
+ void *IP = nullptr;
+ if (IsAOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
+ return I;
+
+ IsAOpInit *I = new (Allocator) IsAOpInit(CheckType, Expr);
+ ThePool.InsertNode(I, IP);
+ return I;
+}
+
+void IsAOpInit::Profile(FoldingSetNodeID &ID) const {
+ ProfileIsAOpInit(ID, CheckType, Expr);
+}
+
+Init *IsAOpInit::Fold() const {
+ if (TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
+ // Is the expression type known to be (a subclass of) the desired type?
+ if (TI->getType()->typeIsConvertibleTo(CheckType))
+ return IntInit::get(1);
+
+ if (isa<RecordRecTy>(CheckType)) {
+ // If the target type is not a subclass of the expression type, or if
+ // the expression has fully resolved to a record, we know that it can't
+ // be of the required type.
+ if (!CheckType->typeIsConvertibleTo(TI->getType()) || isa<DefInit>(Expr))
+ return IntInit::get(0);
+ } else {
+ // We treat non-record types as not castable.
+ return IntInit::get(0);
+ }
+ }
+ return const_cast<IsAOpInit *>(this);
+}
+
+Init *IsAOpInit::resolveReferences(Resolver &R) const {
+ Init *NewExpr = Expr->resolveReferences(R);
+ if (Expr != NewExpr)
+ return get(CheckType, NewExpr)->Fold();
+ return const_cast<IsAOpInit *>(this);
+}
+
+Init *IsAOpInit::getBit(unsigned Bit) const {
+ return VarBitInit::get(const_cast<IsAOpInit *>(this), Bit);
+}
+
+std::string IsAOpInit::getAsString() const {
+ return (Twine("!isa<") + CheckType->getAsString() + ">(" +
+ Expr->getAsString() + ")")
+ .str();
+}
+
RecTy *TypedInit::getFieldType(StringInit *FieldName) const {
if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) {
for (Record *Rec : RecordType->getClasses()) {
diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index 9d8d693f975..222aac25f9d 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -467,6 +467,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
StringSwitch<tgtok::TokKind>(StringRef(Start, CurPtr - Start))
.Case("eq", tgtok::XEq)
.Case("if", tgtok::XIf)
+ .Case("isa", tgtok::XIsA)
.Case("head", tgtok::XHead)
.Case("tail", tgtok::XTail)
.Case("size", tgtok::XSize)
diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index cfed08ec4d4..bebe3176d7b 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,
+ XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty, XIf, XEq, XIsA,
// Integer value.
IntVal,
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 488d1c8d82a..47c734502f0 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -936,6 +936,33 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
}
+ case tgtok::XIsA: {
+ // Value ::= !isa '<' Type '>' '(' Value ')'
+ Lex.Lex(); // eat the operation
+
+ RecTy *Type = ParseOperatorType();
+ if (!Type)
+ return nullptr;
+
+ if (Lex.getCode() != tgtok::l_paren) {
+ TokError("expected '(' after type of !isa");
+ return nullptr;
+ }
+ Lex.Lex(); // eat the '('
+
+ Init *LHS = ParseValue(CurRec);
+ if (!LHS)
+ return nullptr;
+
+ if (Lex.getCode() != tgtok::r_paren) {
+ TokError("expected ')' in !isa");
+ return nullptr;
+ }
+ Lex.Lex(); // eat the ')'
+
+ return (IsAOpInit::get(Type, LHS))->Fold();
+ }
+
case tgtok::XConcat:
case tgtok::XADD:
case tgtok::XAND:
@@ -1696,6 +1723,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XSize:
case tgtok::XEmpty:
case tgtok::XCast: // Value ::= !unop '(' Value ')'
+ case tgtok::XIsA:
case tgtok::XConcat:
case tgtok::XADD:
case tgtok::XAND:
OpenPOWER on IntegriCloud