Chris Lattner | 36e646c | 2010-02-24 07:06:50 +0000 | [diff] [blame] | 1 | //===- DAGISelMatcherOpt.cpp - Optimize a DAG Matcher ---------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file implements the DAG Matcher optimizer. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "DAGISelMatcher.h" |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 15 | #include "llvm/ADT/DenseMap.h" |
| 16 | #include <vector> |
Chris Lattner | 36e646c | 2010-02-24 07:06:50 +0000 | [diff] [blame] | 17 | using namespace llvm; |
| 18 | |
Chris Lattner | f4950d0 | 2010-02-27 06:22:57 +0000 | [diff] [blame] | 19 | /// ContractNodes - Turn multiple matcher node patterns like 'MoveChild+Record' |
| 20 | /// into single compound nodes like RecordChild. |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 21 | static void ContractNodes(OwningPtr<Matcher> &MatcherPtr) { |
Chris Lattner | 3ee1bc4 | 2010-02-24 07:31:45 +0000 | [diff] [blame] | 22 | // If we reached the end of the chain, we're done. |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 23 | Matcher *N = MatcherPtr.get(); |
Chris Lattner | 3ee1bc4 | 2010-02-24 07:31:45 +0000 | [diff] [blame] | 24 | if (N == 0) return; |
| 25 | |
Chris Lattner | 4236366 | 2010-02-25 19:00:39 +0000 | [diff] [blame] | 26 | // If we have a scope node, walk down all of the children. |
| 27 | if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) { |
| 28 | for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) { |
| 29 | OwningPtr<Matcher> Child(Scope->takeChild(i)); |
| 30 | ContractNodes(Child); |
| 31 | Scope->resetChild(i, Child.take()); |
| 32 | } |
| 33 | return; |
| 34 | } |
Chris Lattner | 3ee1bc4 | 2010-02-24 07:31:45 +0000 | [diff] [blame] | 35 | |
Chris Lattner | 9feb1e3 | 2010-02-24 19:52:48 +0000 | [diff] [blame] | 36 | // If we found a movechild node with a node that comes in a 'foochild' form, |
| 37 | // transform it. |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 38 | if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N)) { |
| 39 | Matcher *New = 0; |
| 40 | if (RecordMatcher *RM = dyn_cast<RecordMatcher>(MC->getNext())) |
| 41 | New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor()); |
Chris Lattner | 3c664b3 | 2010-02-24 20:15:25 +0000 | [diff] [blame] | 42 | |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 43 | if (CheckTypeMatcher *CT= dyn_cast<CheckTypeMatcher>(MC->getNext())) |
| 44 | New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType()); |
Chris Lattner | 3c664b3 | 2010-02-24 20:15:25 +0000 | [diff] [blame] | 45 | |
| 46 | if (New) { |
| 47 | // Insert the new node. |
Chris Lattner | ac10e4f | 2010-02-25 01:56:48 +0000 | [diff] [blame] | 48 | New->setNext(MatcherPtr.take()); |
| 49 | MatcherPtr.reset(New); |
Chris Lattner | 3c664b3 | 2010-02-24 20:15:25 +0000 | [diff] [blame] | 50 | // Remove the old one. |
| 51 | MC->setNext(MC->getNext()->takeNext()); |
Chris Lattner | ac10e4f | 2010-02-25 01:56:48 +0000 | [diff] [blame] | 52 | return ContractNodes(MatcherPtr); |
Chris Lattner | 9feb1e3 | 2010-02-24 19:52:48 +0000 | [diff] [blame] | 53 | } |
Chris Lattner | 3ee1bc4 | 2010-02-24 07:31:45 +0000 | [diff] [blame] | 54 | } |
Chris Lattner | 9feb1e3 | 2010-02-24 19:52:48 +0000 | [diff] [blame] | 55 | |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 56 | if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N)) |
| 57 | if (MoveParentMatcher *MP = |
| 58 | dyn_cast<MoveParentMatcher>(MC->getNext())) { |
Chris Lattner | ac10e4f | 2010-02-25 01:56:48 +0000 | [diff] [blame] | 59 | MatcherPtr.reset(MP->takeNext()); |
| 60 | return ContractNodes(MatcherPtr); |
Chris Lattner | 9feb1e3 | 2010-02-24 19:52:48 +0000 | [diff] [blame] | 61 | } |
| 62 | |
| 63 | ContractNodes(N->getNextPtr()); |
Chris Lattner | 3ee1bc4 | 2010-02-24 07:31:45 +0000 | [diff] [blame] | 64 | } |
| 65 | |
Chris Lattner | f4950d0 | 2010-02-27 06:22:57 +0000 | [diff] [blame] | 66 | /// SinkPatternPredicates - Pattern predicates can be checked at any level of |
| 67 | /// the matching tree. The generator dumps them at the top level of the pattern |
| 68 | /// though, which prevents factoring from being able to see past them. This |
| 69 | /// optimization sinks them as far down into the pattern as possible. |
| 70 | /// |
| 71 | /// Conceptually, we'd like to sink these predicates all the way to the last |
| 72 | /// matcher predicate in the series. However, it turns out that some |
| 73 | /// ComplexPatterns have side effects on the graph, so we really don't want to |
| 74 | /// run a the complex pattern if the pattern predicate will fail. For this |
| 75 | /// reason, we refuse to sink the pattern predicate past a ComplexPattern. |
| 76 | /// |
| 77 | static void SinkPatternPredicates(OwningPtr<Matcher> &MatcherPtr) { |
| 78 | // Recursively scan for a PatternPredicate. |
| 79 | // If we reached the end of the chain, we're done. |
| 80 | Matcher *N = MatcherPtr.get(); |
| 81 | if (N == 0) return; |
| 82 | |
| 83 | // Walk down all members of a scope node. |
| 84 | if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) { |
| 85 | for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) { |
| 86 | OwningPtr<Matcher> Child(Scope->takeChild(i)); |
| 87 | SinkPatternPredicates(Child); |
| 88 | Scope->resetChild(i, Child.take()); |
| 89 | } |
| 90 | return; |
| 91 | } |
| 92 | |
| 93 | // If this node isn't a CheckPatternPredicateMatcher we keep scanning until |
| 94 | // we find one. |
| 95 | CheckPatternPredicateMatcher *CPPM =dyn_cast<CheckPatternPredicateMatcher>(N); |
| 96 | if (CPPM == 0) |
| 97 | return SinkPatternPredicates(N->getNextPtr()); |
| 98 | |
| 99 | // Ok, we found one, lets try to sink it. Check if we can sink it past the |
| 100 | // next node in the chain. If not, we won't be able to change anything and |
| 101 | // might as well bail. |
| 102 | if (!CPPM->getNext()->isSafeToReorderWithPatternPredicate()) |
| 103 | return; |
| 104 | |
| 105 | // Okay, we know we can sink it past at least one node. Unlink it from the |
| 106 | // chain and scan for the new insertion point. |
| 107 | MatcherPtr.take(); // Don't delete CPPM. |
| 108 | MatcherPtr.reset(CPPM->takeNext()); |
| 109 | |
| 110 | N = MatcherPtr.get(); |
| 111 | while (N->getNext()->isSafeToReorderWithPatternPredicate()) |
| 112 | N = N->getNext(); |
| 113 | |
| 114 | // At this point, we want to insert CPPM after N. |
| 115 | CPPM->setNext(N->takeNext()); |
| 116 | N->setNext(CPPM); |
| 117 | } |
| 118 | |
| 119 | /// FactorNodes - Turn matches like this: |
| 120 | /// Scope |
| 121 | /// OPC_CheckType i32 |
| 122 | /// ABC |
| 123 | /// OPC_CheckType i32 |
| 124 | /// XYZ |
| 125 | /// into: |
| 126 | /// OPC_CheckType i32 |
| 127 | /// Scope |
| 128 | /// ABC |
| 129 | /// XYZ |
| 130 | /// |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 131 | static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) { |
Chris Lattner | 0acf2ba | 2010-02-25 01:57:41 +0000 | [diff] [blame] | 132 | // If we reached the end of the chain, we're done. |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 133 | Matcher *N = MatcherPtr.get(); |
Chris Lattner | 0acf2ba | 2010-02-25 01:57:41 +0000 | [diff] [blame] | 134 | if (N == 0) return; |
| 135 | |
| 136 | // If this is not a push node, just scan for one. |
Chris Lattner | 4236366 | 2010-02-25 19:00:39 +0000 | [diff] [blame] | 137 | ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N); |
| 138 | if (Scope == 0) |
Chris Lattner | 0acf2ba | 2010-02-25 01:57:41 +0000 | [diff] [blame] | 139 | return FactorNodes(N->getNextPtr()); |
| 140 | |
Chris Lattner | 4236366 | 2010-02-25 19:00:39 +0000 | [diff] [blame] | 141 | // Okay, pull together the children of the scope node into a vector so we can |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 142 | // inspect it more easily. While we're at it, bucket them up by the hash |
| 143 | // code of their first predicate. |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 144 | SmallVector<Matcher*, 32> OptionsToMatch; |
Chris Lattner | 0acf2ba | 2010-02-25 01:57:41 +0000 | [diff] [blame] | 145 | |
Chris Lattner | 4236366 | 2010-02-25 19:00:39 +0000 | [diff] [blame] | 146 | for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) { |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 147 | // Factor the subexpression. |
Chris Lattner | 4236366 | 2010-02-25 19:00:39 +0000 | [diff] [blame] | 148 | OwningPtr<Matcher> Child(Scope->takeChild(i)); |
| 149 | FactorNodes(Child); |
| 150 | |
Chris Lattner | 92a2246 | 2010-02-26 08:08:41 +0000 | [diff] [blame] | 151 | if (Matcher *N = Child.take()) |
Chris Lattner | 4236366 | 2010-02-25 19:00:39 +0000 | [diff] [blame] | 152 | OptionsToMatch.push_back(N); |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 153 | } |
Chris Lattner | 0acf2ba | 2010-02-25 01:57:41 +0000 | [diff] [blame] | 154 | |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 155 | SmallVector<Matcher*, 32> NewOptionsToMatch; |
| 156 | |
Chris Lattner | 92a2246 | 2010-02-26 08:08:41 +0000 | [diff] [blame] | 157 | // Loop over options to match, merging neighboring patterns with identical |
| 158 | // starting nodes into a shared matcher. |
| 159 | for (unsigned i = 0, e = OptionsToMatch.size(); i != e;) { |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 160 | // Find the set of matchers that start with this node. |
Chris Lattner | 92a2246 | 2010-02-26 08:08:41 +0000 | [diff] [blame] | 161 | Matcher *Optn = OptionsToMatch[i++]; |
| 162 | |
| 163 | // See if the next option starts with the same matcher, if not, no sharing. |
| 164 | if (i == e || !OptionsToMatch[i]->isEqual(Optn)) { |
| 165 | // TODO: Skip over mutually exclusive patterns. |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 166 | NewOptionsToMatch.push_back(Optn); |
| 167 | continue; |
| 168 | } |
| 169 | |
Chris Lattner | 92a2246 | 2010-02-26 08:08:41 +0000 | [diff] [blame] | 170 | // If the two neighbors *do* start with the same matcher, we can factor the |
| 171 | // matcher out of at least these two patterns. See what the maximal set we |
| 172 | // can merge together is. |
| 173 | SmallVector<Matcher*, 8> EqualMatchers; |
| 174 | EqualMatchers.push_back(Optn); |
| 175 | EqualMatchers.push_back(OptionsToMatch[i++]); |
| 176 | |
| 177 | while (i != e && OptionsToMatch[i]->isEqual(Optn)) |
| 178 | EqualMatchers.push_back(OptionsToMatch[i++]); |
| 179 | |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 180 | // Factor these checks by pulling the first node off each entry and |
Chris Lattner | b0e6810 | 2010-02-26 07:36:37 +0000 | [diff] [blame] | 181 | // discarding it. Take the first one off the first entry to reuse. |
| 182 | Matcher *Shared = Optn; |
| 183 | Optn = Optn->takeNext(); |
| 184 | EqualMatchers[0] = Optn; |
| 185 | |
Chris Lattner | 92a2246 | 2010-02-26 08:08:41 +0000 | [diff] [blame] | 186 | // Remove and delete the first node from the other matchers we're factoring. |
| 187 | for (unsigned i = 1, e = EqualMatchers.size(); i != e; ++i) { |
| 188 | Matcher *Tmp = EqualMatchers[i]->takeNext(); |
| 189 | delete EqualMatchers[i]; |
| 190 | EqualMatchers[i] = Tmp; |
| 191 | } |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 192 | |
Chris Lattner | b0e6810 | 2010-02-26 07:36:37 +0000 | [diff] [blame] | 193 | Shared->setNext(new ScopeMatcher(&EqualMatchers[0], EqualMatchers.size())); |
| 194 | |
| 195 | // Recursively factor the newly created node. |
| 196 | FactorNodes(Shared->getNextPtr()); |
| 197 | |
| 198 | NewOptionsToMatch.push_back(Shared); |
Chris Lattner | cd632fb | 2010-02-25 07:45:24 +0000 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | // Reassemble a new Scope node. |
Chris Lattner | b0e6810 | 2010-02-26 07:36:37 +0000 | [diff] [blame] | 202 | assert(!NewOptionsToMatch.empty() && "where'd all our children go?"); |
| 203 | if (NewOptionsToMatch.size() == 1) |
| 204 | MatcherPtr.reset(NewOptionsToMatch[0]); |
| 205 | else { |
| 206 | Scope->setNumChildren(NewOptionsToMatch.size()); |
| 207 | for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) |
| 208 | Scope->resetChild(i, NewOptionsToMatch[i]); |
| 209 | } |
Chris Lattner | 0acf2ba | 2010-02-25 01:57:41 +0000 | [diff] [blame] | 210 | } |
| 211 | |
Chris Lattner | 9a51517 | 2010-02-25 02:04:40 +0000 | [diff] [blame] | 212 | Matcher *llvm::OptimizeMatcher(Matcher *TheMatcher) { |
| 213 | OwningPtr<Matcher> MatcherPtr(TheMatcher); |
Chris Lattner | 9feb1e3 | 2010-02-24 19:52:48 +0000 | [diff] [blame] | 214 | ContractNodes(MatcherPtr); |
Chris Lattner | f4950d0 | 2010-02-27 06:22:57 +0000 | [diff] [blame] | 215 | SinkPatternPredicates(MatcherPtr); |
Chris Lattner | 0acf2ba | 2010-02-25 01:57:41 +0000 | [diff] [blame] | 216 | FactorNodes(MatcherPtr); |
Chris Lattner | 3ee1bc4 | 2010-02-24 07:31:45 +0000 | [diff] [blame] | 217 | return MatcherPtr.take(); |
Chris Lattner | 36e646c | 2010-02-24 07:06:50 +0000 | [diff] [blame] | 218 | } |