xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/DAGISelMatcherOpt.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- DAGISelMatcherOpt.cpp - Optimize a DAG Matcher ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the DAG Matcher optimizer.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
13*0fca6ea1SDimitry Andric #include "Basic/SDNodeProperties.h"
14*0fca6ea1SDimitry Andric #include "Common/CodeGenDAGPatterns.h"
15*0fca6ea1SDimitry Andric #include "Common/DAGISelMatcher.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringSet.h"
170b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
180b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #define DEBUG_TYPE "isel-opt"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric /// ContractNodes - Turn multiple matcher node patterns like 'MoveChild+Record'
240b57cec5SDimitry Andric /// into single compound nodes like RecordChild.
ContractNodes(std::unique_ptr<Matcher> & MatcherPtr,const CodeGenDAGPatterns & CGP)250b57cec5SDimitry Andric static void ContractNodes(std::unique_ptr<Matcher> &MatcherPtr,
260b57cec5SDimitry Andric                           const CodeGenDAGPatterns &CGP) {
270b57cec5SDimitry Andric   // If we reached the end of the chain, we're done.
280b57cec5SDimitry Andric   Matcher *N = MatcherPtr.get();
2906c3fb27SDimitry Andric   if (!N)
3006c3fb27SDimitry Andric     return;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   // If we have a scope node, walk down all of the children.
330b57cec5SDimitry Andric   if (ScopeMatcher *Scope = dyn_cast<ScopeMatcher>(N)) {
340b57cec5SDimitry Andric     for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
350b57cec5SDimitry Andric       std::unique_ptr<Matcher> Child(Scope->takeChild(i));
360b57cec5SDimitry Andric       ContractNodes(Child, CGP);
370b57cec5SDimitry Andric       Scope->resetChild(i, Child.release());
380b57cec5SDimitry Andric     }
390b57cec5SDimitry Andric     return;
400b57cec5SDimitry Andric   }
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   // If we found a movechild node with a node that comes in a 'foochild' form,
430b57cec5SDimitry Andric   // transform it.
440b57cec5SDimitry Andric   if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N)) {
450b57cec5SDimitry Andric     Matcher *New = nullptr;
460b57cec5SDimitry Andric     if (RecordMatcher *RM = dyn_cast<RecordMatcher>(MC->getNext()))
470b57cec5SDimitry Andric       if (MC->getChildNo() < 8) // Only have RecordChild0...7
480b57cec5SDimitry Andric         New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor(),
490b57cec5SDimitry Andric                                      RM->getResultNo());
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric     if (CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(MC->getNext()))
520b57cec5SDimitry Andric       if (MC->getChildNo() < 8 && // Only have CheckChildType0...7
530b57cec5SDimitry Andric           CT->getResNo() == 0)    // CheckChildType checks res #0
540b57cec5SDimitry Andric         New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType());
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric     if (CheckSameMatcher *CS = dyn_cast<CheckSameMatcher>(MC->getNext()))
570b57cec5SDimitry Andric       if (MC->getChildNo() < 4) // Only have CheckChildSame0...3
580b57cec5SDimitry Andric         New = new CheckChildSameMatcher(MC->getChildNo(), CS->getMatchNumber());
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric     if (CheckIntegerMatcher *CI = dyn_cast<CheckIntegerMatcher>(MC->getNext()))
610b57cec5SDimitry Andric       if (MC->getChildNo() < 5) // Only have CheckChildInteger0...4
620b57cec5SDimitry Andric         New = new CheckChildIntegerMatcher(MC->getChildNo(), CI->getValue());
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric     if (auto *CCC = dyn_cast<CheckCondCodeMatcher>(MC->getNext()))
650b57cec5SDimitry Andric       if (MC->getChildNo() == 2) // Only have CheckChild2CondCode
660b57cec5SDimitry Andric         New = new CheckChild2CondCodeMatcher(CCC->getCondCodeName());
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric     if (New) {
690b57cec5SDimitry Andric       // Insert the new node.
700b57cec5SDimitry Andric       New->setNext(MatcherPtr.release());
710b57cec5SDimitry Andric       MatcherPtr.reset(New);
720b57cec5SDimitry Andric       // Remove the old one.
730b57cec5SDimitry Andric       MC->setNext(MC->getNext()->takeNext());
740b57cec5SDimitry Andric       return ContractNodes(MatcherPtr, CGP);
750b57cec5SDimitry Andric     }
760b57cec5SDimitry Andric   }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // Zap movechild -> moveparent.
790b57cec5SDimitry Andric   if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N))
8006c3fb27SDimitry Andric     if (MoveParentMatcher *MP = dyn_cast<MoveParentMatcher>(MC->getNext())) {
810b57cec5SDimitry Andric       MatcherPtr.reset(MP->takeNext());
820b57cec5SDimitry Andric       return ContractNodes(MatcherPtr, CGP);
830b57cec5SDimitry Andric     }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   // Turn EmitNode->CompleteMatch into MorphNodeTo if we can.
860b57cec5SDimitry Andric   if (EmitNodeMatcher *EN = dyn_cast<EmitNodeMatcher>(N))
870b57cec5SDimitry Andric     if (CompleteMatchMatcher *CM =
880b57cec5SDimitry Andric             dyn_cast<CompleteMatchMatcher>(EN->getNext())) {
890b57cec5SDimitry Andric       // We can only use MorphNodeTo if the result values match up.
900b57cec5SDimitry Andric       unsigned RootResultFirst = EN->getFirstResultSlot();
910b57cec5SDimitry Andric       bool ResultsMatch = true;
920b57cec5SDimitry Andric       for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
930b57cec5SDimitry Andric         if (CM->getResult(i) != RootResultFirst + i)
940b57cec5SDimitry Andric           ResultsMatch = false;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric       // If the selected node defines a subset of the glue/chain results, we
970b57cec5SDimitry Andric       // can't use MorphNodeTo.  For example, we can't use MorphNodeTo if the
980b57cec5SDimitry Andric       // matched pattern has a chain but the root node doesn't.
990b57cec5SDimitry Andric       const PatternToMatch &Pattern = CM->getPattern();
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric       if (!EN->hasChain() &&
102*0fca6ea1SDimitry Andric           Pattern.getSrcPattern().NodeHasProperty(SDNPHasChain, CGP))
1030b57cec5SDimitry Andric         ResultsMatch = false;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric       // If the matched node has glue and the output root doesn't, we can't
1060b57cec5SDimitry Andric       // use MorphNodeTo.
1070b57cec5SDimitry Andric       //
1080b57cec5SDimitry Andric       // NOTE: Strictly speaking, we don't have to check for glue here
1090b57cec5SDimitry Andric       // because the code in the pattern generator doesn't handle it right.  We
1100b57cec5SDimitry Andric       // do it anyway for thoroughness.
11106c3fb27SDimitry Andric       if (!EN->hasOutGlue() &&
112*0fca6ea1SDimitry Andric           Pattern.getSrcPattern().NodeHasProperty(SDNPOutGlue, CGP))
1130b57cec5SDimitry Andric         ResultsMatch = false;
1140b57cec5SDimitry Andric 
11506c3fb27SDimitry Andric #if 0
1160b57cec5SDimitry Andric       // If the root result node defines more results than the source root node
1170b57cec5SDimitry Andric       // *and* has a chain or glue input, then we can't match it because it
1180b57cec5SDimitry Andric       // would end up replacing the extra result with the chain/glue.
1190b57cec5SDimitry Andric       if ((EN->hasGlue() || EN->hasChain()) &&
1200b57cec5SDimitry Andric           EN->getNumNonChainGlueVTs() > ... need to get no results reliably ...)
1210b57cec5SDimitry Andric         ResultMatch = false;
1220b57cec5SDimitry Andric #endif
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric       if (ResultsMatch) {
1250b57cec5SDimitry Andric         const SmallVectorImpl<MVT::SimpleValueType> &VTs = EN->getVTList();
1260b57cec5SDimitry Andric         const SmallVectorImpl<unsigned> &Operands = EN->getOperandList();
12706c3fb27SDimitry Andric         MatcherPtr.reset(new MorphNodeToMatcher(
12806c3fb27SDimitry Andric             EN->getInstruction(), VTs, Operands, EN->hasChain(),
12906c3fb27SDimitry Andric             EN->hasInGlue(), EN->hasOutGlue(), EN->hasMemRefs(),
13006c3fb27SDimitry Andric             EN->getNumFixedArityOperands(), Pattern));
1310b57cec5SDimitry Andric         return;
1320b57cec5SDimitry Andric       }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric       // FIXME2: Kill off all the SelectionDAG::SelectNodeTo and getMachineNode
1350b57cec5SDimitry Andric       // variants.
1360b57cec5SDimitry Andric     }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   ContractNodes(N->getNextPtr(), CGP);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   // If we have a CheckType/CheckChildType/Record node followed by a
1410b57cec5SDimitry Andric   // CheckOpcode, invert the two nodes.  We prefer to do structural checks
1420b57cec5SDimitry Andric   // before type checks, as this opens opportunities for factoring on targets
1430b57cec5SDimitry Andric   // like X86 where many operations are valid on multiple types.
1440b57cec5SDimitry Andric   if ((isa<CheckTypeMatcher>(N) || isa<CheckChildTypeMatcher>(N) ||
1450b57cec5SDimitry Andric        isa<RecordMatcher>(N)) &&
1460b57cec5SDimitry Andric       isa<CheckOpcodeMatcher>(N->getNext())) {
1470b57cec5SDimitry Andric     // Unlink the two nodes from the list.
1480b57cec5SDimitry Andric     Matcher *CheckType = MatcherPtr.release();
1490b57cec5SDimitry Andric     Matcher *CheckOpcode = CheckType->takeNext();
1500b57cec5SDimitry Andric     Matcher *Tail = CheckOpcode->takeNext();
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric     // Relink them.
1530b57cec5SDimitry Andric     MatcherPtr.reset(CheckOpcode);
1540b57cec5SDimitry Andric     CheckOpcode->setNext(CheckType);
1550b57cec5SDimitry Andric     CheckType->setNext(Tail);
1560b57cec5SDimitry Andric     return ContractNodes(MatcherPtr, CGP);
1570b57cec5SDimitry Andric   }
1585f757f3fSDimitry Andric 
1595f757f3fSDimitry Andric   // If we have a MoveParent followed by a MoveChild, we convert it to
1605f757f3fSDimitry Andric   // MoveSibling.
1615f757f3fSDimitry Andric   if (auto *MP = dyn_cast<MoveParentMatcher>(N)) {
1625f757f3fSDimitry Andric     if (auto *MC = dyn_cast<MoveChildMatcher>(MP->getNext())) {
1635f757f3fSDimitry Andric       auto *MS = new MoveSiblingMatcher(MC->getChildNo());
1645f757f3fSDimitry Andric       MS->setNext(MC->takeNext());
1655f757f3fSDimitry Andric       MatcherPtr.reset(MS);
1665f757f3fSDimitry Andric       return ContractNodes(MatcherPtr, CGP);
1675f757f3fSDimitry Andric     }
1685f757f3fSDimitry Andric     if (auto *RC = dyn_cast<RecordChildMatcher>(MP->getNext())) {
1695f757f3fSDimitry Andric       if (auto *MC = dyn_cast<MoveChildMatcher>(RC->getNext())) {
1705f757f3fSDimitry Andric         if (RC->getChildNo() == MC->getChildNo()) {
1715f757f3fSDimitry Andric           auto *MS = new MoveSiblingMatcher(MC->getChildNo());
1725f757f3fSDimitry Andric           auto *RM = new RecordMatcher(RC->getWhatFor(), RC->getResultNo());
1735f757f3fSDimitry Andric           // Insert the new node.
1745f757f3fSDimitry Andric           RM->setNext(MC->takeNext());
1755f757f3fSDimitry Andric           MS->setNext(RM);
1765f757f3fSDimitry Andric           MatcherPtr.reset(MS);
1775f757f3fSDimitry Andric           return ContractNodes(MatcherPtr, CGP);
1785f757f3fSDimitry Andric         }
1795f757f3fSDimitry Andric       }
1805f757f3fSDimitry Andric     }
1815f757f3fSDimitry Andric   }
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric /// FindNodeWithKind - Scan a series of matchers looking for a matcher with a
1850b57cec5SDimitry Andric /// specified kind.  Return null if we didn't find one otherwise return the
1860b57cec5SDimitry Andric /// matcher.
FindNodeWithKind(Matcher * M,Matcher::KindTy Kind)1870b57cec5SDimitry Andric static Matcher *FindNodeWithKind(Matcher *M, Matcher::KindTy Kind) {
1880b57cec5SDimitry Andric   for (; M; M = M->getNext())
1890b57cec5SDimitry Andric     if (M->getKind() == Kind)
1900b57cec5SDimitry Andric       return M;
1910b57cec5SDimitry Andric   return nullptr;
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric /// FactorNodes - Turn matches like this:
1950b57cec5SDimitry Andric ///   Scope
1960b57cec5SDimitry Andric ///     OPC_CheckType i32
1970b57cec5SDimitry Andric ///       ABC
1980b57cec5SDimitry Andric ///     OPC_CheckType i32
1990b57cec5SDimitry Andric ///       XYZ
2000b57cec5SDimitry Andric /// into:
2010b57cec5SDimitry Andric ///   OPC_CheckType i32
2020b57cec5SDimitry Andric ///     Scope
2030b57cec5SDimitry Andric ///       ABC
2040b57cec5SDimitry Andric ///       XYZ
2050b57cec5SDimitry Andric ///
FactorNodes(std::unique_ptr<Matcher> & InputMatcherPtr)2060b57cec5SDimitry Andric static void FactorNodes(std::unique_ptr<Matcher> &InputMatcherPtr) {
2070b57cec5SDimitry Andric   // Look for a push node. Iterates instead of recurses to reduce stack usage.
2080b57cec5SDimitry Andric   ScopeMatcher *Scope = nullptr;
2090b57cec5SDimitry Andric   std::unique_ptr<Matcher> *RebindableMatcherPtr = &InputMatcherPtr;
2100b57cec5SDimitry Andric   while (!Scope) {
2110b57cec5SDimitry Andric     // If we reached the end of the chain, we're done.
2120b57cec5SDimitry Andric     Matcher *N = RebindableMatcherPtr->get();
21306c3fb27SDimitry Andric     if (!N)
21406c3fb27SDimitry Andric       return;
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric     // If this is not a push node, just scan for one.
2170b57cec5SDimitry Andric     Scope = dyn_cast<ScopeMatcher>(N);
2180b57cec5SDimitry Andric     if (!Scope)
2190b57cec5SDimitry Andric       RebindableMatcherPtr = &(N->getNextPtr());
2200b57cec5SDimitry Andric   }
2210b57cec5SDimitry Andric   std::unique_ptr<Matcher> &MatcherPtr = *RebindableMatcherPtr;
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   // Okay, pull together the children of the scope node into a vector so we can
2240b57cec5SDimitry Andric   // inspect it more easily.
2250b57cec5SDimitry Andric   SmallVector<Matcher *, 32> OptionsToMatch;
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   for (unsigned i = 0, e = Scope->getNumChildren(); i != e; ++i) {
2280b57cec5SDimitry Andric     // Factor the subexpression.
2290b57cec5SDimitry Andric     std::unique_ptr<Matcher> Child(Scope->takeChild(i));
2300b57cec5SDimitry Andric     FactorNodes(Child);
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric     // If the child is a ScopeMatcher we can just merge its contents.
2330b57cec5SDimitry Andric     if (auto *SM = dyn_cast<ScopeMatcher>(Child.get())) {
2340b57cec5SDimitry Andric       for (unsigned j = 0, e = SM->getNumChildren(); j != e; ++j)
2350b57cec5SDimitry Andric         OptionsToMatch.push_back(SM->takeChild(j));
2360b57cec5SDimitry Andric     } else {
2370b57cec5SDimitry Andric       OptionsToMatch.push_back(Child.release());
2380b57cec5SDimitry Andric     }
2390b57cec5SDimitry Andric   }
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric   // Loop over options to match, merging neighboring patterns with identical
2420b57cec5SDimitry Andric   // starting nodes into a shared matcher.
24306c3fb27SDimitry Andric   auto E = OptionsToMatch.end();
24406c3fb27SDimitry Andric   for (auto I = OptionsToMatch.begin(); I != E; ++I) {
24506c3fb27SDimitry Andric     // If there are no other matchers left, there's nothing to merge with.
24606c3fb27SDimitry Andric     auto J = std::next(I);
24706c3fb27SDimitry Andric     if (J == E)
24806c3fb27SDimitry Andric       break;
2490b57cec5SDimitry Andric 
25006c3fb27SDimitry Andric     // Remember where we started. We'll use this to move non-equal elements.
25106c3fb27SDimitry Andric     auto K = J;
25206c3fb27SDimitry Andric 
25306c3fb27SDimitry Andric     // Find the set of matchers that start with this node.
25406c3fb27SDimitry Andric     Matcher *Optn = *I;
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric     // See if the next option starts with the same matcher.  If the two
2570b57cec5SDimitry Andric     // neighbors *do* start with the same matcher, we can factor the matcher out
2580b57cec5SDimitry Andric     // of at least these two patterns.  See what the maximal set we can merge
2590b57cec5SDimitry Andric     // together is.
2600b57cec5SDimitry Andric     SmallVector<Matcher *, 8> EqualMatchers;
2610b57cec5SDimitry Andric     EqualMatchers.push_back(Optn);
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric     // Factor all of the known-equal matchers after this one into the same
2640b57cec5SDimitry Andric     // group.
26506c3fb27SDimitry Andric     while (J != E && (*J)->isEqual(Optn))
26606c3fb27SDimitry Andric       EqualMatchers.push_back(*J++);
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric     // If we found a non-equal matcher, see if it is contradictory with the
2690b57cec5SDimitry Andric     // current node.  If so, we know that the ordering relation between the
2700b57cec5SDimitry Andric     // current sets of nodes and this node don't matter.  Look past it to see if
2710b57cec5SDimitry Andric     // we can merge anything else into this matching group.
27206c3fb27SDimitry Andric     while (J != E) {
27306c3fb27SDimitry Andric       Matcher *ScanMatcher = *J;
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric       // If we found an entry that matches out matcher, merge it into the set to
2760b57cec5SDimitry Andric       // handle.
2770b57cec5SDimitry Andric       if (Optn->isEqual(ScanMatcher)) {
27806c3fb27SDimitry Andric         // It is equal after all, add the option to EqualMatchers.
2790b57cec5SDimitry Andric         EqualMatchers.push_back(ScanMatcher);
28006c3fb27SDimitry Andric         ++J;
2810b57cec5SDimitry Andric         continue;
2820b57cec5SDimitry Andric       }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric       // If the option we're checking for contradicts the start of the list,
28506c3fb27SDimitry Andric       // move it earlier in OptionsToMatch for the next iteration of the outer
28606c3fb27SDimitry Andric       // loop. Then continue searching for equal or contradictory matchers.
2870b57cec5SDimitry Andric       if (Optn->isContradictory(ScanMatcher)) {
28806c3fb27SDimitry Andric         *K++ = *J++;
2890b57cec5SDimitry Andric         continue;
2900b57cec5SDimitry Andric       }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric       // If we're scanning for a simple node, see if it occurs later in the
2930b57cec5SDimitry Andric       // sequence.  If so, and if we can move it up, it might be contradictory
2940b57cec5SDimitry Andric       // or the same as what we're looking for.  If so, reorder it.
2950b57cec5SDimitry Andric       if (Optn->isSimplePredicateOrRecordNode()) {
2960b57cec5SDimitry Andric         Matcher *M2 = FindNodeWithKind(ScanMatcher, Optn->getKind());
29706c3fb27SDimitry Andric         if (M2 && M2 != ScanMatcher && M2->canMoveBefore(ScanMatcher) &&
2980b57cec5SDimitry Andric             (M2->isEqual(Optn) || M2->isContradictory(Optn))) {
2990b57cec5SDimitry Andric           Matcher *MatcherWithoutM2 = ScanMatcher->unlinkNode(M2);
3000b57cec5SDimitry Andric           M2->setNext(MatcherWithoutM2);
30106c3fb27SDimitry Andric           *J = M2;
3020b57cec5SDimitry Andric           continue;
3030b57cec5SDimitry Andric         }
3040b57cec5SDimitry Andric       }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric       // Otherwise, we don't know how to handle this entry, we have to bail.
3070b57cec5SDimitry Andric       break;
3080b57cec5SDimitry Andric     }
3090b57cec5SDimitry Andric 
31006c3fb27SDimitry Andric     if (J != E &&
31106c3fb27SDimitry Andric         // Don't print if it's obvious nothing extract could be merged anyway.
31206c3fb27SDimitry Andric         std::next(J) != E) {
3130b57cec5SDimitry Andric       LLVM_DEBUG(errs() << "Couldn't merge this:\n"; Optn->print(errs(), 4);
314*0fca6ea1SDimitry Andric                  errs() << "into this:\n"; (*J)->print(errs(), 4);
31506c3fb27SDimitry Andric                  (*std::next(J))->printOne(errs());
31606c3fb27SDimitry Andric                  if (std::next(J, 2) != E)(*std::next(J, 2))->printOne(errs());
3170b57cec5SDimitry Andric                  errs() << "\n");
3180b57cec5SDimitry Andric     }
3190b57cec5SDimitry Andric 
32006c3fb27SDimitry Andric     // If we removed any equal matchers, we may need to slide the rest of the
32106c3fb27SDimitry Andric     // elements down for the next iteration of the outer loop.
32206c3fb27SDimitry Andric     if (J != K) {
32306c3fb27SDimitry Andric       while (J != E)
32406c3fb27SDimitry Andric         *K++ = *J++;
32506c3fb27SDimitry Andric 
32606c3fb27SDimitry Andric       // Update end pointer for outer loop.
32706c3fb27SDimitry Andric       E = K;
32806c3fb27SDimitry Andric     }
32906c3fb27SDimitry Andric 
3300b57cec5SDimitry Andric     // If we only found one option starting with this matcher, no factoring is
33106c3fb27SDimitry Andric     // possible. Put the Matcher back in OptionsToMatch.
3320b57cec5SDimitry Andric     if (EqualMatchers.size() == 1) {
33306c3fb27SDimitry Andric       *I = EqualMatchers[0];
3340b57cec5SDimitry Andric       continue;
3350b57cec5SDimitry Andric     }
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric     // Factor these checks by pulling the first node off each entry and
3380b57cec5SDimitry Andric     // discarding it.  Take the first one off the first entry to reuse.
3390b57cec5SDimitry Andric     Matcher *Shared = Optn;
3400b57cec5SDimitry Andric     Optn = Optn->takeNext();
3410b57cec5SDimitry Andric     EqualMatchers[0] = Optn;
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric     // Remove and delete the first node from the other matchers we're factoring.
3440b57cec5SDimitry Andric     for (unsigned i = 1, e = EqualMatchers.size(); i != e; ++i) {
3450b57cec5SDimitry Andric       Matcher *Tmp = EqualMatchers[i]->takeNext();
3460b57cec5SDimitry Andric       delete EqualMatchers[i];
3470b57cec5SDimitry Andric       EqualMatchers[i] = Tmp;
34806c3fb27SDimitry Andric       assert(!Optn == !Tmp && "Expected all to be null if any are null");
3490b57cec5SDimitry Andric     }
3500b57cec5SDimitry Andric 
35106c3fb27SDimitry Andric     if (EqualMatchers[0]) {
35206c3fb27SDimitry Andric       Shared->setNext(new ScopeMatcher(std::move(EqualMatchers)));
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric       // Recursively factor the newly created node.
3550b57cec5SDimitry Andric       FactorNodes(Shared->getNextPtr());
3560b57cec5SDimitry Andric     }
3570b57cec5SDimitry Andric 
35806c3fb27SDimitry Andric     // Put the new Matcher where we started in OptionsToMatch.
35906c3fb27SDimitry Andric     *I = Shared;
36006c3fb27SDimitry Andric   }
36106c3fb27SDimitry Andric 
36206c3fb27SDimitry Andric   // Trim the array to match the updated end.
36306c3fb27SDimitry Andric   if (E != OptionsToMatch.end())
36406c3fb27SDimitry Andric     OptionsToMatch.erase(E, OptionsToMatch.end());
36506c3fb27SDimitry Andric 
3660b57cec5SDimitry Andric   // If we're down to a single pattern to match, then we don't need this scope
3670b57cec5SDimitry Andric   // anymore.
36806c3fb27SDimitry Andric   if (OptionsToMatch.size() == 1) {
36906c3fb27SDimitry Andric     MatcherPtr.reset(OptionsToMatch[0]);
3700b57cec5SDimitry Andric     return;
3710b57cec5SDimitry Andric   }
3720b57cec5SDimitry Andric 
37306c3fb27SDimitry Andric   if (OptionsToMatch.empty()) {
3740b57cec5SDimitry Andric     MatcherPtr.reset();
3750b57cec5SDimitry Andric     return;
3760b57cec5SDimitry Andric   }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric   // If our factoring failed (didn't achieve anything) see if we can simplify in
3790b57cec5SDimitry Andric   // other ways.
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric   // Check to see if all of the leading entries are now opcode checks.  If so,
3820b57cec5SDimitry Andric   // we can convert this Scope to be a OpcodeSwitch instead.
3830b57cec5SDimitry Andric   bool AllOpcodeChecks = true, AllTypeChecks = true;
38406c3fb27SDimitry Andric   for (unsigned i = 0, e = OptionsToMatch.size(); i != e; ++i) {
3850b57cec5SDimitry Andric     // Check to see if this breaks a series of CheckOpcodeMatchers.
38606c3fb27SDimitry Andric     if (AllOpcodeChecks && !isa<CheckOpcodeMatcher>(OptionsToMatch[i])) {
3870b57cec5SDimitry Andric #if 0
3880b57cec5SDimitry Andric       if (i > 3) {
3890b57cec5SDimitry Andric         errs() << "FAILING OPC #" << i << "\n";
39006c3fb27SDimitry Andric         OptionsToMatch[i]->dump();
3910b57cec5SDimitry Andric       }
3920b57cec5SDimitry Andric #endif
3930b57cec5SDimitry Andric       AllOpcodeChecks = false;
3940b57cec5SDimitry Andric     }
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric     // Check to see if this breaks a series of CheckTypeMatcher's.
3970b57cec5SDimitry Andric     if (AllTypeChecks) {
39806c3fb27SDimitry Andric       CheckTypeMatcher *CTM = cast_or_null<CheckTypeMatcher>(
39906c3fb27SDimitry Andric           FindNodeWithKind(OptionsToMatch[i], Matcher::CheckType));
4000b57cec5SDimitry Andric       if (!CTM ||
4010b57cec5SDimitry Andric           // iPTR checks could alias any other case without us knowing, don't
4020b57cec5SDimitry Andric           // bother with them.
4030b57cec5SDimitry Andric           CTM->getType() == MVT::iPTR ||
4040b57cec5SDimitry Andric           // SwitchType only works for result #0.
4050b57cec5SDimitry Andric           CTM->getResNo() != 0 ||
4060b57cec5SDimitry Andric           // If the CheckType isn't at the start of the list, see if we can move
4070b57cec5SDimitry Andric           // it there.
40806c3fb27SDimitry Andric           !CTM->canMoveBefore(OptionsToMatch[i])) {
4090b57cec5SDimitry Andric #if 0
4100b57cec5SDimitry Andric         if (i > 3 && AllTypeChecks) {
4110b57cec5SDimitry Andric           errs() << "FAILING TYPE #" << i << "\n";
41206c3fb27SDimitry Andric           OptionsToMatch[i]->dump();
4130b57cec5SDimitry Andric         }
4140b57cec5SDimitry Andric #endif
4150b57cec5SDimitry Andric         AllTypeChecks = false;
4160b57cec5SDimitry Andric       }
4170b57cec5SDimitry Andric     }
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   // If all the options are CheckOpcode's, we can form the SwitchOpcode, woot.
4210b57cec5SDimitry Andric   if (AllOpcodeChecks) {
4220b57cec5SDimitry Andric     StringSet<> Opcodes;
4230b57cec5SDimitry Andric     SmallVector<std::pair<const SDNodeInfo *, Matcher *>, 8> Cases;
42406c3fb27SDimitry Andric     for (unsigned i = 0, e = OptionsToMatch.size(); i != e; ++i) {
42506c3fb27SDimitry Andric       CheckOpcodeMatcher *COM = cast<CheckOpcodeMatcher>(OptionsToMatch[i]);
4260b57cec5SDimitry Andric       assert(Opcodes.insert(COM->getOpcode().getEnumName()).second &&
4270b57cec5SDimitry Andric              "Duplicate opcodes not factored?");
428*0fca6ea1SDimitry Andric       Cases.push_back(std::pair(&COM->getOpcode(), COM->takeNext()));
4290b57cec5SDimitry Andric       delete COM;
4300b57cec5SDimitry Andric     }
4310b57cec5SDimitry Andric 
43206c3fb27SDimitry Andric     MatcherPtr.reset(new SwitchOpcodeMatcher(std::move(Cases)));
4330b57cec5SDimitry Andric     return;
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   // If all the options are CheckType's, we can form the SwitchType, woot.
4370b57cec5SDimitry Andric   if (AllTypeChecks) {
4380b57cec5SDimitry Andric     DenseMap<unsigned, unsigned> TypeEntry;
4390b57cec5SDimitry Andric     SmallVector<std::pair<MVT::SimpleValueType, Matcher *>, 8> Cases;
44006c3fb27SDimitry Andric     for (unsigned i = 0, e = OptionsToMatch.size(); i != e; ++i) {
44106c3fb27SDimitry Andric       Matcher *M = FindNodeWithKind(OptionsToMatch[i], Matcher::CheckType);
4428bcb0991SDimitry Andric       assert(M && isa<CheckTypeMatcher>(M) && "Unknown Matcher type");
4438bcb0991SDimitry Andric 
4448bcb0991SDimitry Andric       auto *CTM = cast<CheckTypeMatcher>(M);
44506c3fb27SDimitry Andric       Matcher *MatcherWithoutCTM = OptionsToMatch[i]->unlinkNode(CTM);
4460b57cec5SDimitry Andric       MVT::SimpleValueType CTMTy = CTM->getType();
4470b57cec5SDimitry Andric       delete CTM;
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric       unsigned &Entry = TypeEntry[CTMTy];
4500b57cec5SDimitry Andric       if (Entry != 0) {
4510b57cec5SDimitry Andric         // If we have unfactored duplicate types, then we should factor them.
4520b57cec5SDimitry Andric         Matcher *PrevMatcher = Cases[Entry - 1].second;
4530b57cec5SDimitry Andric         if (ScopeMatcher *SM = dyn_cast<ScopeMatcher>(PrevMatcher)) {
4540b57cec5SDimitry Andric           SM->setNumChildren(SM->getNumChildren() + 1);
4550b57cec5SDimitry Andric           SM->resetChild(SM->getNumChildren() - 1, MatcherWithoutCTM);
4560b57cec5SDimitry Andric           continue;
4570b57cec5SDimitry Andric         }
4580b57cec5SDimitry Andric 
45906c3fb27SDimitry Andric         SmallVector<Matcher *, 2> Entries = {PrevMatcher, MatcherWithoutCTM};
46006c3fb27SDimitry Andric         Cases[Entry - 1].second = new ScopeMatcher(std::move(Entries));
4610b57cec5SDimitry Andric         continue;
4620b57cec5SDimitry Andric       }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric       Entry = Cases.size() + 1;
465*0fca6ea1SDimitry Andric       Cases.push_back(std::pair(CTMTy, MatcherWithoutCTM));
4660b57cec5SDimitry Andric     }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric     // Make sure we recursively factor any scopes we may have created.
4690b57cec5SDimitry Andric     for (auto &M : Cases) {
4700b57cec5SDimitry Andric       if (ScopeMatcher *SM = dyn_cast<ScopeMatcher>(M.second)) {
4710b57cec5SDimitry Andric         std::unique_ptr<Matcher> Scope(SM);
4720b57cec5SDimitry Andric         FactorNodes(Scope);
4730b57cec5SDimitry Andric         M.second = Scope.release();
4740b57cec5SDimitry Andric         assert(M.second && "null matcher");
4750b57cec5SDimitry Andric       }
4760b57cec5SDimitry Andric     }
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric     if (Cases.size() != 1) {
47906c3fb27SDimitry Andric       MatcherPtr.reset(new SwitchTypeMatcher(std::move(Cases)));
4800b57cec5SDimitry Andric     } else {
4810b57cec5SDimitry Andric       // If we factored and ended up with one case, create it now.
4820b57cec5SDimitry Andric       MatcherPtr.reset(new CheckTypeMatcher(Cases[0].first, 0));
4830b57cec5SDimitry Andric       MatcherPtr->setNext(Cases[0].second);
4840b57cec5SDimitry Andric     }
4850b57cec5SDimitry Andric     return;
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   // Reassemble the Scope node with the adjusted children.
48906c3fb27SDimitry Andric   Scope->setNumChildren(OptionsToMatch.size());
49006c3fb27SDimitry Andric   for (unsigned i = 0, e = OptionsToMatch.size(); i != e; ++i)
49106c3fb27SDimitry Andric     Scope->resetChild(i, OptionsToMatch[i]);
4920b57cec5SDimitry Andric }
4930b57cec5SDimitry Andric 
OptimizeMatcher(std::unique_ptr<Matcher> & MatcherPtr,const CodeGenDAGPatterns & CGP)49406c3fb27SDimitry Andric void llvm::OptimizeMatcher(std::unique_ptr<Matcher> &MatcherPtr,
4950b57cec5SDimitry Andric                            const CodeGenDAGPatterns &CGP) {
4960b57cec5SDimitry Andric   ContractNodes(MatcherPtr, CGP);
4970b57cec5SDimitry Andric   FactorNodes(MatcherPtr);
4980b57cec5SDimitry Andric }
499