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
This commit is contained in:
Chris Lattner 2010-03-07 06:29:26 +00:00
parent 98f15d27cd
commit 48aa5756a2
2 changed files with 99 additions and 0 deletions

View File

@ -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;
}

View File

@ -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;
};