Emit better code (no more copies for var references), and support DAG patterns
authorChris Lattner <sabre@nondot.org>
Fri, 23 Sep 2005 23:16:51 +0000 (23:16 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 23 Sep 2005 23:16:51 +0000 (23:16 +0000)
(e.g. things like rotates).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23416 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/DAGISelEmitter.cpp
utils/TableGen/DAGISelEmitter.h

index 5c664edbb98454ee2efb343239e72d325d4b1435..6ea5d9604c5a2adf67c5379e650571f65847dca9 100644 (file)
@@ -989,7 +989,8 @@ void DAGISelEmitter::ParsePatterns() {
 /// if the match fails.  At this point, we already know that the opcode for N
 /// matches, and the SDNode for the result has the RootName specified name.
 void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
-                                         const std::string &RootName, 
+                                         const std::string &RootName,
+                                     std::map<std::string,std::string> &VarMap,
                                          unsigned PatternNo, std::ostream &OS) {
   assert(!N->isLeaf() && "Cannot match against a leaf!");
   // Emit code to load the child nodes and match their contents recursively.
@@ -997,12 +998,30 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
     OS << "      SDOperand " << RootName << i <<" = " << RootName
        << ".getOperand(" << i << ");\n";
     TreePatternNode *Child = N->getChild(i);
+    
+    // If this child has a name associated with it, capture it in VarMap.  If
+    // we already saw this in the pattern, emit code to verify dagness.
+    if (!Child->getName().empty()) {
+      std::string &VarMapEntry = VarMap[Child->getName()];
+      if (VarMapEntry.empty()) {
+        VarMapEntry = RootName + utostr(i);
+      } else {
+        // If we get here, this is a second reference to a specific name.  Since
+        // we already have checked that the first reference is valid, we don't
+        // have to recursively match it, just check that it's the same as the
+        // previously named thing.
+        OS << "      if (" << VarMapEntry << " != " << RootName << i
+           << ") goto P" << PatternNo << "Fail;\n";
+        continue;
+      }
+    }
+    
     if (!Child->isLeaf()) {
       // If it's not a leaf, recursively match.
       const SDNodeInfo &CInfo = getSDNodeInfo(Child->getOperator());
       OS << "      if (" << RootName << i << ".getOpcode() != "
          << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n";
-      EmitMatchForPattern(Child, RootName + utostr(i), PatternNo, OS);
+      EmitMatchForPattern(Child, RootName + utostr(i), VarMap, PatternNo, OS);
     } else {
       // Handle leaves of various types.
       Init *LeafVal = Child->getLeafValue();
@@ -1019,11 +1038,6 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
         assert(0 && "Unknown leaf type!");
       }
     }
-    
-    // If this child has a name associated with it, capture it as a variable.
-    if (!Child->getName().empty())
-      OS << "      SDOperand op" << Child->getName() << " = " << RootName
-         << i << ";\n";
   }
   
   // If there is a node predicate for this, emit the call.
@@ -1043,7 +1057,9 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
   Pattern.first->print(OS);
   OS << "\n";
 
-  EmitMatchForPattern(Pattern.first, "N", PatternNo, OS);
+  // Emit the matcher, capturing named arguments in VariableMap.
+  std::map<std::string,std::string> VariableMap;
+  EmitMatchForPattern(Pattern.first, "N", VariableMap, PatternNo, OS);
   
   OS << "      // Emit: ";
   Pattern.second->print(OS);
index 7695f26d73714727271ff68abe438577791cfe74..5cfab18626e2da4a056d3cce69447db2c317d2e0 100644 (file)
@@ -366,6 +366,7 @@ private:
                                             TreePatternNode*> &InstInputs,
                                    std::map<std::string, Record*> &InstResults);
   void EmitMatchForPattern(TreePatternNode *N, const std::string &RootName,
+                           std::map<std::string,std::string> &VarMap,
                            unsigned PatternNo, std::ostream &OS);
   void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS);
   void EmitInstructionSelector(std::ostream &OS);