diff options
author | Chris Lattner <sabre@nondot.org> | 2010-03-07 06:29:26 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-03-07 06:29:26 +0000 |
commit | 48aa5756a29a7b96850ac646d1edd806c9df4643 (patch) | |
tree | 793ecfc4db29d31bb6a03469fec5c46054f4d8fe /utils | |
parent | 98f15d27cda62ca2f973da0244b6b5e15f18acb7 (diff) | |
download | external_llvm-48aa5756a29a7b96850ac646d1edd806c9df4643.zip external_llvm-48aa5756a29a7b96850ac646d1edd806c9df4643.tar.gz external_llvm-48aa5756a29a7b96850ac646d1edd806c9df4643.tar.bz2 |
add some helper functions and implement isContradictory
for CheckValueTypeMatcher. The isContradictory implementation
helps us factor better, shrinking x86 table from 79144 -> 78896
bytes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97905 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/DAGISelMatcher.cpp | 55 | ||||
-rw-r--r-- | utils/TableGen/DAGISelMatcher.h | 44 |
2 files changed, 99 insertions, 0 deletions
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp index c4f1cbf..22d2fe8 100644 --- a/utils/TableGen/DAGISelMatcher.cpp +++ b/utils/TableGen/DAGISelMatcher.cpp @@ -29,6 +29,54 @@ void Matcher::printOne(raw_ostream &OS) const { printImpl(OS, 0); } +/// unlinkNode - Unlink the specified node from this chain. If Other == this, +/// we unlink the next pointer and return it. Otherwise we unlink Other from +/// the list and return this. +Matcher *Matcher::unlinkNode(Matcher *Other) { + if (this == Other) + return takeNext(); + + // Scan until we find the predecessor of Other. + Matcher *Cur = this; + for (; Cur && Cur->getNext() != Other; Cur = Cur->getNext()) + /*empty*/; + + if (Cur == 0) return 0; + Cur->takeNext(); + Cur->setNext(Other->takeNext()); + return this; +} + +/// canMoveBefore - Return true if this matcher is the same as Other, or if +/// we can move this matcher past all of the nodes in-between Other and this +/// node. Other must be equal to or before this. +bool Matcher::canMoveBefore(const Matcher *Other) const { + for (;; Other = Other->getNext()) { + assert(Other && "Other didn't come before 'this'?"); + if (this == Other) return true; + + // We have to be able to move this node across the Other node. + if (!canMoveBeforeNode(Other)) + return false; + } +} + +/// canMoveBefore - Return true if it is safe to move the current matcher +/// across the specified one. +bool Matcher::canMoveBeforeNode(const Matcher *Other) const { + // We can move simple predicates before record nodes. + if (isSimplePredicateNode()) + return Other->isSimplePredicateOrRecordNode(); + + // We can move record nodes across simple predicates. + if (isSimplePredicateOrRecordNode()) + return isSimplePredicateNode(); + + // We can't move record nodes across each other etc. + return false; +} + + ScopeMatcher::~ScopeMatcher() { for (unsigned i = 0, e = Children.size(); i != e; ++i) delete Children[i]; @@ -345,3 +393,10 @@ bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const { return CIM->getValue() != getValue(); return false; } + +bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const { + if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M)) + return CVT->getTypeName() != getTypeName(); + return false; +} + diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h index 7955c7e..ef7ecf4 100644 --- a/utils/TableGen/DAGISelMatcher.h +++ b/utils/TableGen/DAGISelMatcher.h @@ -113,6 +113,49 @@ public: return false; } + /// isSimplePredicateNode - Return true if this is a simple predicate that + /// operates on the node or its children without potential side effects or a + /// change of the current node. + bool isSimplePredicateNode() const { + switch (getKind()) { + default: return false; + case CheckSame: + case CheckPatternPredicate: + case CheckPredicate: + case CheckOpcode: + case CheckType: + case CheckChildType: + case CheckInteger: + case CheckCondCode: + case CheckValueType: + case CheckAndImm: + case CheckOrImm: + case CheckFoldableChainNode: + return true; + } + } + + /// isSimplePredicateOrRecordNode - Return true if this is a record node or + /// a simple predicate. + bool isSimplePredicateOrRecordNode() const { + return isSimplePredicateNode() || + getKind() == RecordNode || getKind() == RecordChild; + } + + /// unlinkNode - Unlink the specified node from this chain. If Other == this, + /// we unlink the next pointer and return it. Otherwise we unlink Other from + /// the list and return this. + Matcher *unlinkNode(Matcher *Other); + + /// canMoveBefore - Return true if this matcher is the same as Other, or if + /// we can move this matcher past all of the nodes in-between Other and this + /// node. Other must be equal to or before this. + bool canMoveBefore(const Matcher *Other) const; + + /// canMoveBefore - Return true if it is safe to move the current matcher + /// across the specified one. + bool canMoveBeforeNode(const Matcher *Other) const; + /// isContradictory - Return true of these two matchers could never match on /// the same node. bool isContradictory(const Matcher *Other) const { @@ -601,6 +644,7 @@ private: return cast<CheckValueTypeMatcher>(M)->TypeName == TypeName; } virtual unsigned getHashImpl() const; + bool isContradictoryImpl(const Matcher *M) const; }; |