diff options
author | Chris Lattner <sabre@nondot.org> | 2010-03-01 06:59:22 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-03-01 06:59:22 +0000 |
commit | eb66921adb943ea841e72c8eee4777607c48b70e (patch) | |
tree | 3fdd7526a69161b2a068815424b87456b8f442cc /utils/TableGen/DAGISelMatcherOpt.cpp | |
parent | c99b5a25bb7ea5ed14e242d16dbfd683dba68f4a (diff) | |
download | external_llvm-eb66921adb943ea841e72c8eee4777607c48b70e.zip external_llvm-eb66921adb943ea841e72c8eee4777607c48b70e.tar.gz external_llvm-eb66921adb943ea841e72c8eee4777607c48b70e.tar.bz2 |
add a new OPC_SwitchOpcode which is semantically equivalent
to a scope where every child starts with a CheckOpcode, but
executes more efficiently. Enhance DAGISelMatcherOpt to
form it.
This also fixes a bug in CheckOpcode: apparently the SDNodeInfo
objects are not pointer comparable, we have to compare the
enum name.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97438 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/DAGISelMatcherOpt.cpp')
-rw-r--r-- | utils/TableGen/DAGISelMatcherOpt.cpp | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/utils/TableGen/DAGISelMatcherOpt.cpp b/utils/TableGen/DAGISelMatcherOpt.cpp index 5fe21f6..41ce6ae 100644 --- a/utils/TableGen/DAGISelMatcherOpt.cpp +++ b/utils/TableGen/DAGISelMatcherOpt.cpp @@ -15,6 +15,7 @@ #include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include <vector> @@ -152,7 +153,8 @@ static void ContractNodes(OwningPtr<Matcher> &MatcherPtr, // like X86 where many operations are valid on multiple types. if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) || isa<RecordMatcher>(N)) && - isa<CheckOpcodeMatcher>(N->getNext())) { + (isa<CheckOpcodeMatcher>(N->getNext()) || + isa<CheckMultiOpcodeMatcher>(N->getNext()))) { // Unlink the two nodes from the list. Matcher *CheckType = MatcherPtr.take(); Matcher *CheckOpcode = CheckType->takeNext(); @@ -256,7 +258,7 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) { } SmallVector<Matcher*, 32> NewOptionsToMatch; - + // Loop over options to match, merging neighboring patterns with identical // starting nodes into a shared matcher. for (unsigned OptionIdx = 0, e = OptionsToMatch.size(); OptionIdx != e;) { @@ -342,13 +344,55 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) { NewOptionsToMatch.push_back(Shared); } + + // If we're down to a single pattern to match, then we don't need this scope + // anymore. + if (NewOptionsToMatch.size() == 1) { + MatcherPtr.reset(NewOptionsToMatch[0]); + return; + } + + // If our factoring failed (didn't achieve anything) see if we can simplify in + // other ways. + + // Check to see if all of the leading entries are now opcode checks. If so, + // we can convert this Scope to be a OpcodeSwitch instead. + bool AllOpcodeChecks = true; + for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) { + if (isa<CheckOpcodeMatcher>(NewOptionsToMatch[i])) continue; + +#if 0 + if (i > 3) { + errs() << "FAILING OPC #" << i << "\n"; + NewOptionsToMatch[i]->dump(); + } +#endif + + AllOpcodeChecks = false; + break; + } + + // If all the options are CheckOpcode's, we can form the SwitchOpcode, woot. + if (AllOpcodeChecks) { + StringSet<> Opcodes; + SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases; + for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) { + CheckOpcodeMatcher *COM =cast<CheckOpcodeMatcher>(NewOptionsToMatch[i]); + assert(Opcodes.insert(COM->getOpcode().getEnumName()) && + "Duplicate opcodes not factored?"); + Cases.push_back(std::make_pair(&COM->getOpcode(), COM->getNext())); + } + + MatcherPtr.reset(new SwitchOpcodeMatcher(&Cases[0], Cases.size())); + return; + } + // Reassemble a new Scope node. - assert(!NewOptionsToMatch.empty() && "where'd all our children go?"); + assert(!NewOptionsToMatch.empty() && + "Where'd all our children go? Did we really factor everything??"); if (NewOptionsToMatch.empty()) MatcherPtr.reset(0); - if (NewOptionsToMatch.size() == 1) - MatcherPtr.reset(NewOptionsToMatch[0]); else { Scope->setNumChildren(NewOptionsToMatch.size()); for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) |