X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FDAGISelEmitter.cpp;h=b47dd71e88e6b019556fa84a4578551155699eec;hb=fc699872e35ec794d7373680be6f1946fe8e9ca6;hp=f4a287c6c65368732835acbe2a2a57707328ebc7;hpb=48e86dbe29e331357b0df11075b7974009c65f34;p=oota-llvm.git diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index f4a287c6c65..b47dd71e88e 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -11,12 +11,24 @@ // //===----------------------------------------------------------------------===// -#include "DAGISelEmitter.h" +#include "CodeGenDAGPatterns.h" #include "DAGISelMatcher.h" -#include "Record.h" #include "llvm/Support/Debug.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; +namespace { +/// DAGISelEmitter - The top-level class which coordinates construction +/// and emission of the instruction selector. +class DAGISelEmitter { + CodeGenDAGPatterns CGP; +public: + explicit DAGISelEmitter(RecordKeeper &R) : CGP(R) {} + void run(raw_ostream &OS); +}; +} // End anonymous namespace + //===----------------------------------------------------------------------===// // DAGISelEmitter Helper methods // @@ -27,7 +39,7 @@ using namespace llvm; static unsigned getResultPatternCost(TreePatternNode *P, CodeGenDAGPatterns &CGP) { if (P->isLeaf()) return 0; - + unsigned Cost = 0; Record *Op = P->getOperator(); if (Op->isSubClassOf("Instruction")) { @@ -43,7 +55,7 @@ static unsigned getResultPatternCost(TreePatternNode *P, /// getResultPatternCodeSize - Compute the code size of instructions for this /// pattern. -static unsigned getResultPatternSize(TreePatternNode *P, +static unsigned getResultPatternSize(TreePatternNode *P, CodeGenDAGPatterns &CGP) { if (P->isLeaf()) return 0; @@ -57,52 +69,6 @@ static unsigned getResultPatternSize(TreePatternNode *P, return Cost; } -//===----------------------------------------------------------------------===// -// Predicate emitter implementation. -// - -void DAGISelEmitter::EmitPredicateFunctions(raw_ostream &OS) { - OS << "\n// Predicate functions.\n"; - - // Walk the pattern fragments, adding them to a map, which sorts them by - // name. - typedef std::map > PFsByNameTy; - PFsByNameTy PFsByName; - - for (CodeGenDAGPatterns::pf_iterator I = CGP.pf_begin(), E = CGP.pf_end(); - I != E; ++I) - PFsByName.insert(std::make_pair(I->first->getName(), *I)); - - - for (PFsByNameTy::iterator I = PFsByName.begin(), E = PFsByName.end(); - I != E; ++I) { - Record *PatFragRecord = I->second.first;// Record that derives from PatFrag. - TreePattern *P = I->second.second; - - // If there is a code init for this fragment, emit the predicate code. - std::string Code = PatFragRecord->getValueAsCode("Predicate"); - if (Code.empty()) continue; - - if (P->getOnlyTree()->isLeaf()) - OS << "inline bool Predicate_" << PatFragRecord->getName() - << "(SDNode *N) const {\n"; - else { - std::string ClassName = - CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName(); - const char *C2 = ClassName == "SDNode" ? "N" : "inN"; - - OS << "inline bool Predicate_" << PatFragRecord->getName() - << "(SDNode *" << C2 << ") const {\n"; - if (ClassName != "SDNode") - OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n"; - } - OS << Code << "\n}\n"; - } - - OS << "\n\n"; -} - - namespace { // PatternSortingPredicate - return true if we prefer to match LHS before RHS. // In particular, we want to match maximal patterns first and lowest cost within @@ -110,8 +76,21 @@ namespace { struct PatternSortingPredicate { PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {} CodeGenDAGPatterns &CGP; - + bool operator()(const PatternToMatch *LHS, const PatternToMatch *RHS) { + const TreePatternNode *LHSSrc = LHS->getSrcPattern(); + const TreePatternNode *RHSSrc = RHS->getSrcPattern(); + + if (LHSSrc->getNumTypes() != 0 && RHSSrc->getNumTypes() != 0 && + LHSSrc->getType(0) != RHSSrc->getType(0)) { + MVT::SimpleValueType V1 = LHSSrc->getType(0), V2 = RHSSrc->getType(0); + if (MVT(V1).isVector() != MVT(V2).isVector()) + return MVT(V2).isVector(); + + if (MVT(V1).isFloatingPoint() != MVT(V2).isFloatingPoint()) + return MVT(V2).isFloatingPoint(); + } + // Otherwise, if the patterns might both match, sort based on complexity, // which means that we prefer to match patterns that cover more nodes in the // input over nodes that cover fewer. @@ -119,31 +98,31 @@ struct PatternSortingPredicate { unsigned RHSSize = RHS->getPatternComplexity(CGP); if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost if (LHSSize < RHSSize) return false; - + // If the patterns have equal complexity, compare generated instruction cost unsigned LHSCost = getResultPatternCost(LHS->getDstPattern(), CGP); unsigned RHSCost = getResultPatternCost(RHS->getDstPattern(), CGP); if (LHSCost < RHSCost) return true; if (LHSCost > RHSCost) return false; - + unsigned LHSPatSize = getResultPatternSize(LHS->getDstPattern(), CGP); unsigned RHSPatSize = getResultPatternSize(RHS->getDstPattern(), CGP); if (LHSPatSize < RHSPatSize) return true; if (LHSPatSize > RHSPatSize) return false; - + // Sort based on the UID of the pattern, giving us a deterministic ordering // if all other sorting conditions fail. assert(LHS == RHS || LHS->ID != RHS->ID); return LHS->ID < RHS->ID; } }; -} +} // End anonymous namespace void DAGISelEmitter::run(raw_ostream &OS) { - EmitSourceFileHeader("DAG Instruction Selector for the " + + emitSourceFileHeader("DAG Instruction Selector for the " + CGP.getTargetInfo().getName() + " target", OS); - + OS << "// *** NOTE: This file is #included into the middle of the target\n" << "// *** instruction selector class. These functions are really " << "methods.\n\n"; @@ -156,9 +135,6 @@ void DAGISelEmitter::run(raw_ostream &OS) { errs() << "\n"; }); - // FIXME: These are being used by hand written code, gross. - EmitPredicateFunctions(OS); - // Add all the patterns to a temporary list so we can sort them. std::vector Patterns; for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end(); @@ -167,10 +143,9 @@ void DAGISelEmitter::run(raw_ostream &OS) { // We want to process the matches in order of minimal cost. Sort the patterns // so the least cost one is at the start. - std::stable_sort(Patterns.begin(), Patterns.end(), - PatternSortingPredicate(CGP)); - - + std::sort(Patterns.begin(), Patterns.end(), PatternSortingPredicate(CGP)); + + // Convert each variant of each pattern into a Matcher. std::vector PatternMatchers; for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { @@ -181,7 +156,7 @@ void DAGISelEmitter::run(raw_ostream &OS) { break; } } - + Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0], PatternMatchers.size()); @@ -190,3 +165,11 @@ void DAGISelEmitter::run(raw_ostream &OS) { EmitMatcherTable(TheMatcher, CGP, OS); delete TheMatcher; } + +namespace llvm { + +void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS) { + DAGISelEmitter(RK).run(OS); +} + +} // End llvm namespace