Teach tblgen to accept register source operands in patterns, e.g.
authorEvan Cheng <evan.cheng@apple.com>
Thu, 1 Dec 2005 00:18:45 +0000 (00:18 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Thu, 1 Dec 2005 00:18:45 +0000 (00:18 +0000)
def SHL8rCL  : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
                 "shl{b} {%cl, $dst|$dst, %CL}",
                 [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>;

This generates a CopyToReg operand and added its 2nd result to the shl as
a flag operand.

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

include/llvm/CodeGen/SelectionDAG.h
utils/TableGen/DAGISelEmitter.cpp
utils/TableGen/DAGISelEmitter.h

index 5f7d2d7249902c90ff33d53a4c7b21e041809d59..546b990eb91d312069ea0e0e66b3afd7049a5a83 100644 (file)
@@ -143,6 +143,20 @@ public:
     if (Flag.Val) Ops.push_back(Flag);
     return getNode(ISD::CopyToReg, VTs, Ops);
   }
+
+  // Similar to last getCopyToReg() except parameter Reg is a SDOperand
+  SDOperand getCopyToReg(SDOperand Chain, SDOperand Reg, SDOperand N,
+                         SDOperand Flag) {
+    std::vector<MVT::ValueType> VTs;
+    VTs.push_back(MVT::Other);
+    VTs.push_back(MVT::Flag);
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Chain);
+    Ops.push_back(Reg);
+    Ops.push_back(N);
+    if (Flag.Val) Ops.push_back(Flag);
+    return getNode(ISD::CopyToReg, VTs, Ops);
+  }
   
   SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT) {
     std::vector<MVT::ValueType> ResultTys;
index d7d8fd8b95692a02f85455e33807705b52037597..4b40561b2689a3ebf792fe23ec34b39e5f761f5d 100644 (file)
@@ -1574,7 +1574,7 @@ struct PatternSortingPredicate {
 /// matches, and the SDNode for the result has the RootName specified name.
 void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
                                          const std::string &RootName,
-                                     std::map<std::string,std::string> &VarMap,
+                                         std::map<std::string,std::string> &VarMap,
                                          unsigned PatternNo, std::ostream &OS) {
   if (N->isLeaf()) {
     if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
@@ -1637,7 +1637,8 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
       // Handle leaves of various types.
       if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
         Record *LeafRec = DI->getDef();
-        if (LeafRec->isSubClassOf("RegisterClass")) {
+        if (LeafRec->isSubClassOf("RegisterClass") ||
+            LeafRec->isSubClassOf("Register")) {
           // Handle register references.  Nothing to do here.
         } else if (LeafRec->isSubClassOf("ValueType")) {
           // Make sure this is the specified value type.
@@ -1671,12 +1672,60 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
        << ".Val)) goto P" << PatternNo << "Fail;\n";
 }
 
+/// getRegisterValueType - Look up and return ValueType of specified record
+static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) {
+  const std::vector<CodeGenRegisterClass> &RegisterClasses =
+    T.getRegisterClasses();
+
+  for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
+    const CodeGenRegisterClass &RC = RegisterClasses[i];
+    for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
+      if (R == RC.Elements[ei]) {
+        return RC.VT;
+      }
+    }
+  }
+
+  return MVT::Other;
+}
+
+
+/// EmitCopyToRegsForPattern - Emit the flag operands for the DAG that will be
+/// built in CodeGenPatternResult.
+void DAGISelEmitter::EmitCopyToRegsForPattern(TreePatternNode *N,
+                                              const std::string &RootName,
+                                              std::ostream &OS, bool &InFlag) {
+  const CodeGenTarget &T = getTargetInfo();
+  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+    TreePatternNode *Child = N->getChild(i);
+    if (!Child->isLeaf()) {
+      EmitCopyToRegsForPattern(Child, RootName + utostr(i), OS, InFlag);
+    } else {
+      if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
+        Record *RR = DI->getDef();
+        if (RR->isSubClassOf("Register")) {
+          MVT::ValueType RVT = getRegisterValueType(RR, T);
+          if (!InFlag) {
+            OS << "      SDOperand InFlag;  // Null incoming flag value.\n";
+            InFlag = true;
+          }
+          OS << "      InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode()"
+             << ", CurDAG->getRegister(" << getQualifiedName(RR)
+             << ", MVT::" << getEnumName(RVT) << ")"
+             << ", " << RootName << i << ", InFlag).getValue(1);\n";
+
+        }
+      }
+    }
+  }
+}
+
 /// CodeGenPatternResult - Emit the action for a pattern.  Now that it has
 /// matched, we actually have to build a DAG!
 unsigned DAGISelEmitter::
 CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr,
                      std::map<std::string,std::string> &VariableMap, 
-                     std::ostream &OS, bool isRoot) {
+                     std::ostream &OS, bool InFlag, bool isRoot) {
   // This is something selected from the pattern we matched.
   if (!N->getName().empty()) {
     assert(!isRoot && "Root of pattern cannot be a leaf!");
@@ -1742,7 +1791,8 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr,
     // Emit all of the operands.
     std::vector<unsigned> Ops;
     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
-      Ops.push_back(CodeGenPatternResult(N->getChild(i), Ctr, VariableMap, OS));
+      Ops.push_back(CodeGenPatternResult(N->getChild(i),
+                                         Ctr, VariableMap, OS, InFlag));
 
     CodeGenInstruction &II = Target.getInstruction(Op->getName());
     unsigned ResNo = Ctr++;
@@ -1763,6 +1813,8 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr,
          << getEnumName(N->getType());
       for (unsigned i = 0, e = Ops.size(); i != e; ++i)
         OS << ", Tmp" << Ops[i];
+      if (InFlag)
+        OS << ", InFlag";
       OS << ");\n";
       OS << "      } else {\n";
       OS << "        return CodeGenMap[N] = CurDAG->getTargetNode("
@@ -1770,13 +1822,16 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr,
       << getEnumName(N->getType());
       for (unsigned i = 0, e = Ops.size(); i != e; ++i)
         OS << ", Tmp" << Ops[i];
+      if (InFlag)
+        OS << ", InFlag";
       OS << ");\n";
       OS << "      }\n";
     }
     return ResNo;
   } else if (Op->isSubClassOf("SDNodeXForm")) {
     assert(N->getNumChildren() == 1 && "node xform should have one child!");
-    unsigned OpVal = CodeGenPatternResult(N->getChild(0), Ctr, VariableMap, OS);
+    unsigned OpVal = CodeGenPatternResult(N->getChild(0),
+                                          Ctr, VariableMap, OS, InFlag);
     
     unsigned ResNo = Ctr++;
     OS << "      SDOperand Tmp" << ResNo << " = Transform_" << Op->getName()
@@ -1886,10 +1941,13 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
     // an unresolved type to add a check for, this returns true and we iterate,
     // otherwise we are done.
   } while (InsertOneTypeCheck(Pat, Pattern.first, "N", PatternNo, OS));
+
+  bool InFlag = false;
+  EmitCopyToRegsForPattern(Pattern.first, "N", OS, InFlag);
   
   unsigned TmpNo = 0;
-  CodeGenPatternResult(Pattern.second, TmpNo,
-                       VariableMap, OS, true /*the root*/);
+  CodeGenPatternResult(Pattern.second,
+                       TmpNo, VariableMap, OS, InFlag, true /*the root*/);
   delete Pat;
   
   OS << "    }\n  P" << PatternNo << "Fail:\n";
index 404b00b5223c82f20eb5f95def635b0d19b5880d..ed1e97804cd73e20b78b8d39fa0cd3ff4cd93de1 100644 (file)
@@ -418,9 +418,12 @@ private:
   void EmitMatchForPattern(TreePatternNode *N, const std::string &RootName,
                            std::map<std::string,std::string> &VarMap,
                            unsigned PatternNo, std::ostream &OS);
+  void EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName,
+                                std::ostream &OS, bool &InFlag);
   unsigned CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr,
                                 std::map<std::string,std::string> &VariableMap, 
-                                std::ostream &OS, bool isRoot = false);      
+                                std::ostream &OS, bool InFlag,
+                                bool isRoot = false);
   void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS);
   void EmitInstructionSelector(std::ostream &OS);
 };