aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-03-01 02:15:34 +0000
committerChris Lattner <sabre@nondot.org>2010-03-01 02:15:34 +0000
commite9eeda878beb8d36507a69a2be2fe08fcc968fef (patch)
treea592c260e96508c1e738d1c7887e3a03e5e34010
parent4d0c931ba7758a98864dc7e968a10df7fed7ab70 (diff)
Emit redundant opcode checks for andimm and orimm tests at root
so that we get grouping at the top level. Add an optimization to reorder type check & record nodes after opcode checks. We prefer to expose tree shape matching which improves grouping and will enhance the next optimization. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97432 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp7
-rw-r--r--utils/TableGen/DAGISelMatcherOpt.cpp20
2 files changed, 27 insertions, 0 deletions
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 120a3dc1d5..d198488305 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -320,6 +320,13 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
N->getPredicateFns().empty()) {
if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
+ // If this is at the root of the pattern, we emit a redundant
+ // CheckOpcode so that the following checks get factored properly under
+ // a single opcode check.
+ if (N == Pattern.getSrcPattern())
+ AddMatcher(new CheckOpcodeMatcher(CInfo));
+
+ // Emit the CheckAndImm/CheckOrImm node.
if (N->getOperator()->getName() == "and")
AddMatcher(new CheckAndImmMatcher(II->getValue()));
else
diff --git a/utils/TableGen/DAGISelMatcherOpt.cpp b/utils/TableGen/DAGISelMatcherOpt.cpp
index 37643c3184..1181827905 100644
--- a/utils/TableGen/DAGISelMatcherOpt.cpp
+++ b/utils/TableGen/DAGISelMatcherOpt.cpp
@@ -127,6 +127,26 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr,
}
ContractNodes(N->getNextPtr(), CGP);
+
+
+ // If we have a CheckType/CheckChildType/Record node followed by a
+ // CheckOpcode, invert the two nodes. We prefer to do structural checks
+ // before type checks, as this opens opportunities for factoring on targets
+ // like X86 where many operations are valid on multiple types.
+ if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
+ isa<RecordMatcher>(N)) &&
+ isa<CheckOpcodeMatcher>(N->getNext())) {
+ // Unlink the two nodes from the list.
+ Matcher *CheckType = MatcherPtr.take();
+ Matcher *CheckOpcode = CheckType->takeNext();
+ Matcher *Tail = CheckOpcode->takeNext();
+
+ // Relink them.
+ MatcherPtr.reset(CheckOpcode);
+ CheckOpcode->setNext(CheckType);
+ CheckType->setNext(Tail);
+ return ContractNodes(MatcherPtr, CGP);
+ }
}
/// SinkPatternPredicates - Pattern predicates can be checked at any level of