//===- DAGISelMatcherOpt.cpp - Optimize a DAG Matcher ---------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the DAG Matcher optimizer. // //===----------------------------------------------------------------------===// #include "DAGISelMatcher.h" using namespace llvm; static void ContractNodes(OwningPtr &MatcherPtr) { // If we reached the end of the chain, we're done. Matcher *N = MatcherPtr.get(); if (N == 0) return; // If we have a scope node, walk down both edges. if (ScopeMatcher *Push = dyn_cast(N)) ContractNodes(Push->getCheckPtr()); // If we found a movechild node with a node that comes in a 'foochild' form, // transform it. if (MoveChildMatcher *MC = dyn_cast(N)) { Matcher *New = 0; if (RecordMatcher *RM = dyn_cast(MC->getNext())) New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor()); if (CheckTypeMatcher *CT= dyn_cast(MC->getNext())) New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType()); if (New) { // Insert the new node. New->setNext(MatcherPtr.take()); MatcherPtr.reset(New); // Remove the old one. MC->setNext(MC->getNext()->takeNext()); return ContractNodes(MatcherPtr); } } if (MoveChildMatcher *MC = dyn_cast(N)) if (MoveParentMatcher *MP = dyn_cast(MC->getNext())) { MatcherPtr.reset(MP->takeNext()); return ContractNodes(MatcherPtr); } ContractNodes(N->getNextPtr()); } static void FactorNodes(OwningPtr &MatcherPtr) { // If we reached the end of the chain, we're done. Matcher *N = MatcherPtr.get(); if (N == 0) return; // If this is not a push node, just scan for one. if (!isa(N)) return FactorNodes(N->getNextPtr()); // Okay, pull together the series of linear push nodes into a vector so we can // inspect it more easily. SmallVector OptionsToMatch; Matcher *CurNode = N; for (; ScopeMatcher *PMN = dyn_cast(CurNode); CurNode = PMN->getNext()) OptionsToMatch.push_back(PMN->getCheck()); OptionsToMatch.push_back(CurNode); } Matcher *llvm::OptimizeMatcher(Matcher *TheMatcher) { OwningPtr MatcherPtr(TheMatcher); ContractNodes(MatcherPtr); FactorNodes(MatcherPtr); return MatcherPtr.take(); }