[llvm-commits] [llvm] r99725 - in /llvm/trunk/utils/TableGen: CodeGenDAGPatterns.cpp DAGISelMatcherGen.cpp

Chris Lattner sabre at nondot.org
Sat Mar 27 12:15:02 PDT 2010


Author: lattner
Date: Sat Mar 27 14:15:02 2010
New Revision: 99725

URL: http://llvm.org/viewvc/llvm-project?rev=99725&view=rev
Log:
continue pushing tblgen's support for nodes with multiple
results forward.  We can now handle an instruction that 
produces one implicit def and one result instead of one or
the other when not at the root of the pattern.

Modified:
    llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
    llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp

Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=99725&r1=99724&r2=99725&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Sat Mar 27 14:15:02 2010
@@ -775,10 +775,9 @@
   
   if (Operator->isSubClassOf("Instruction")) {
     CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator);
-    
-    // FIXME: Handle implicit defs right.
-    if (InstInfo.NumDefs != 0)
-      return 1;     // FIXME: Handle inst results right!
+
+    // FIXME: Should allow access to all the results here.
+    unsigned NumDefsToAdd = InstInfo.NumDefs ? 1 : 0;
     
     if (!InstInfo.ImplicitDefs.empty()) {
       // Add on one implicit def if it has a resolvable type.
@@ -787,9 +786,9 @@
       const std::vector<MVT::SimpleValueType> &RegVTs = 
       CDP.getTargetInfo().getRegisterVTs(FirstImplicitDef);
       if (RegVTs.size() == 1)
-        return 1;
+        return NumDefsToAdd+1;
     }
-    return 0;
+    return NumDefsToAdd;
   }
   
   if (Operator->isSubClassOf("SDNodeXForm"))
@@ -1250,21 +1249,20 @@
   
   if (getOperator()->isSubClassOf("Instruction")) {
     const DAGInstruction &Inst = CDP.getInstruction(getOperator());
-    unsigned ResNo = 0;
-    assert(Inst.getNumResults() <= 1 &&
-           "FIXME: Only supports zero or one result instrs!");
-
     CodeGenInstruction &InstInfo =
       CDP.getTargetInfo().getInstruction(getOperator());
     
-    EEVT::TypeSet ResultType;
-    
-    // Apply the result type to the node
-    if (InstInfo.NumDefs != 0) { // # of elements in (outs) list
-      Record *ResultNode = Inst.getResult(0);
+    bool MadeChange = false;
+
+    // Apply the result types to the node, these come from the things in the
+    // (outs) list of the instruction.
+    // FIXME: Cap at one result so far.
+    unsigned NumResultsToAdd = InstInfo.NumDefs ? 1 : 0;
+    for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) {
+      Record *ResultNode = Inst.getResult(ResNo);
       
       if (ResultNode->isSubClassOf("PointerLikeRegClass")) {
-        ResultType = EEVT::TypeSet(MVT::iPTR, TP);
+        MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP);
       } else if (ResultNode->getName() == "unknown") {
         // Nothing to do.
       } else {
@@ -1272,26 +1270,23 @@
                "Operands should be register classes!");
         const CodeGenRegisterClass &RC = 
           CDP.getTargetInfo().getRegisterClass(ResultNode);
-        ResultType = RC.getValueTypes();
+        MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP);
       }
-    } else if (!InstInfo.ImplicitDefs.empty()) {
-      // If the instruction has implicit defs, the first one defines the result
-      // type.
+    }
+    
+    // If the instruction has implicit defs, we apply the first one as a result.
+    // FIXME: This sucks, it should apply all implicit defs.
+    if (!InstInfo.ImplicitDefs.empty()) {
+      unsigned ResNo = NumResultsToAdd;
+      
       Record *FirstImplicitDef = InstInfo.ImplicitDefs[0];
       assert(FirstImplicitDef->isSubClassOf("Register"));
       const std::vector<MVT::SimpleValueType> &RegVTs = 
         CDP.getTargetInfo().getRegisterVTs(FirstImplicitDef);
       if (RegVTs.size() == 1)   // FIXME: Generalize.
-        ResultType = EEVT::TypeSet(RegVTs);
-    } else {
-      // Otherwise, the instruction produces no value result.
+        MadeChange |= UpdateNodeType(ResNo, EEVT::TypeSet(RegVTs), TP);
     }
     
-    bool MadeChange = false;
-    
-    if (!ResultType.isCompletelyUnknown())
-      MadeChange |= UpdateNodeType(ResNo, ResultType, TP);
-    
     // If this is an INSERT_SUBREG, constrain the source and destination VTs to
     // be the same.
     if (getOperator()->getName() == "INSERT_SUBREG") {
@@ -1319,17 +1314,17 @@
       
       MVT::SimpleValueType VT;
       TreePatternNode *Child = getChild(ChildNo++);
-      assert(Child->getNumTypes() == 1 && "Unknown case?");
+      unsigned ChildResNo = 0;  // Instructions always use res #0 of their op.
       
       if (OperandNode->isSubClassOf("RegisterClass")) {
         const CodeGenRegisterClass &RC = 
           CDP.getTargetInfo().getRegisterClass(OperandNode);
-        MadeChange |= Child->UpdateNodeType(0, RC.getValueTypes(), TP);
+        MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
       } else if (OperandNode->isSubClassOf("Operand")) {
         VT = getValueType(OperandNode->getValueAsDef("Type"));
-        MadeChange |= Child->UpdateNodeType(0, VT, TP);
+        MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP);
       } else if (OperandNode->isSubClassOf("PointerLikeRegClass")) {
-        MadeChange |= Child->UpdateNodeType(0, MVT::iPTR, TP);
+        MadeChange |= Child->UpdateNodeType(ChildResNo, MVT::iPTR, TP);
       } else if (OperandNode->getName() == "unknown") {
         // Nothing to do.
       } else {

Modified: llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp?rev=99725&r1=99724&r2=99725&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelMatcherGen.cpp Sat Mar 27 14:15:02 2010
@@ -687,9 +687,19 @@
       continue;
     }
     
+    const TreePatternNode *Child = N->getChild(ChildNo);
+    
     // Otherwise this is a normal operand or a predicate operand without
     // 'execute always'; emit it.
-    EmitResultOperand(N->getChild(ChildNo), InstOps);
+    unsigned BeforeAddingNumOps = InstOps.size();
+    EmitResultOperand(Child, InstOps);
+    assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands");
+    
+    // If the operand is an instruction and it produced multiple results, just
+    // take the first one.
+    if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction"))
+      InstOps.resize(BeforeAddingNumOps+1);
+    
     ++ChildNo;
   }
   
@@ -711,12 +721,8 @@
   
   // Determine the result types.
   SmallVector<MVT::SimpleValueType, 4> ResultVTs;
-  if (N->getNumTypes()) {
-    // FIXME2: If the node has multiple results, we should add them.  For now,
-    // preserve existing behavior?!
-    assert(N->getNumTypes() == 1);
-    ResultVTs.push_back(N->getType(0));
-  }
+  for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i)
+    ResultVTs.push_back(N->getType(i));
   
   // If this is the root instruction of a pattern that has physical registers in
   // its result pattern, add output VTs for them.  For example, X86 has:
@@ -727,7 +733,7 @@
     // If the root came from an implicit def in the instruction handling stuff,
     // don't re-add it.
     Record *HandledReg = 0;
-    if (NumResults == 0 && N->getNumTypes() != 0 &&
+    if (N->getNumTypes() != 0 &&
         !II.ImplicitDefs.empty())
       HandledReg = II.ImplicitDefs[0];
     
@@ -762,6 +768,9 @@
   bool NodeHasMemRefs =
     isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP);
 
+  assert((!ResultVTs.empty() || TreeHasOutFlag || NodeHasChain) &&
+         "Node has no result");
+  
   AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
                                  ResultVTs.data(), ResultVTs.size(),
                                  InstOps.data(), InstOps.size(),





More information about the llvm-commits mailing list