[WebAssembly] Add some more ideas to README.txt.
[oota-llvm.git] / utils / TableGen / DAGISelEmitter.cpp
index f4a287c6c65368732835acbe2a2a57707328ebc7..0fe3bbd8d788d0c9b36e69a4bc994ddbc7ba8964 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#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;
 
+#define DEBUG_TYPE "dag-isel-emitter"
+
+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 +41,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 +57,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 +71,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<std::string, std::pair<Record*, TreePattern*> > 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,40 +78,51 @@ 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();
+
+    MVT LHSVT = (LHSSrc->getNumTypes() != 0 ? LHSSrc->getType(0) : MVT::Other);
+    MVT RHSVT = (RHSSrc->getNumTypes() != 0 ? RHSSrc->getType(0) : MVT::Other);
+    if (LHSVT.isVector() != RHSVT.isVector())
+      return RHSVT.isVector();
+
+    if (LHSVT.isFloatingPoint() != RHSVT.isFloatingPoint())
+      return RHSVT.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.
-    unsigned LHSSize = LHS->getPatternComplexity(CGP);
-    unsigned RHSSize = RHS->getPatternComplexity(CGP);
+    int LHSSize = LHS->getPatternComplexity(CGP);
+    int 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<const PatternToMatch*> 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<Matcher*> PatternMatchers;
   for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
@@ -181,12 +156,19 @@ void DAGISelEmitter::run(raw_ostream &OS) {
         break;
     }
   }
-          
-  Matcher *TheMatcher = new ScopeMatcher(&PatternMatchers[0],
-                                         PatternMatchers.size());
 
-  TheMatcher = OptimizeMatcher(TheMatcher, CGP);
+  std::unique_ptr<Matcher> TheMatcher =
+    llvm::make_unique<ScopeMatcher>(PatternMatchers);
+
+  OptimizeMatcher(TheMatcher, CGP);
   //Matcher->dump();
-  EmitMatcherTable(TheMatcher, CGP, OS);
-  delete TheMatcher;
+  EmitMatcherTable(TheMatcher.get(), CGP, OS);
 }
+
+namespace llvm {
+
+void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS) {
+  DAGISelEmitter(RK).run(OS);
+}
+
+} // End llvm namespace