[llvm-commits] CVS: llvm/utils/TableGen/CodeGenInstruction.h CodeGenTarget.cpp DAGISelEmitter.cpp DAGISelEmitter.h

Evan Cheng evan.cheng at apple.com
Fri Dec 23 14:11:59 PST 2005



Changes in directory llvm/utils/TableGen:

CodeGenInstruction.h updated: 1.16 -> 1.17
CodeGenTarget.cpp updated: 1.50 -> 1.51
DAGISelEmitter.cpp updated: 1.114 -> 1.115
DAGISelEmitter.h updated: 1.47 -> 1.48
---
Log message:

* Support for hasInFlag and hasOutFlag (on instructions). Remove nameless FLAG
support which is fragile.
* Fixed a number of bugs.


---
Diffs of the changes:  (+122 -109)

 CodeGenInstruction.h |    2 
 CodeGenTarget.cpp    |    2 
 DAGISelEmitter.cpp   |  213 +++++++++++++++++++++++++--------------------------
 DAGISelEmitter.h     |   14 ++-
 4 files changed, 122 insertions(+), 109 deletions(-)


Index: llvm/utils/TableGen/CodeGenInstruction.h
diff -u llvm/utils/TableGen/CodeGenInstruction.h:1.16 llvm/utils/TableGen/CodeGenInstruction.h:1.17
--- llvm/utils/TableGen/CodeGenInstruction.h:1.16	Sun Dec  4 02:18:16 2005
+++ llvm/utils/TableGen/CodeGenInstruction.h	Fri Dec 23 16:11:47 2005
@@ -85,6 +85,8 @@
     bool usesCustomDAGSchedInserter;
     bool hasVariableNumberOfOperands;
     bool hasCtrlDep;
+    bool hasInFlag;
+    bool hasOutFlag;
 
     CodeGenInstruction(Record *R, const std::string &AsmStr);
 


Index: llvm/utils/TableGen/CodeGenTarget.cpp
diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.50 llvm/utils/TableGen/CodeGenTarget.cpp:1.51
--- llvm/utils/TableGen/CodeGenTarget.cpp:1.50	Fri Dec 16 19:19:28 2005
+++ llvm/utils/TableGen/CodeGenTarget.cpp	Fri Dec 23 16:11:47 2005
@@ -271,6 +271,8 @@
   hasDelaySlot = R->getValueAsBit("hasDelaySlot");
   usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
   hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
+  hasInFlag    = R->getValueAsBit("hasInFlag");
+  hasOutFlag   = R->getValueAsBit("hasOutFlag");
   hasVariableNumberOfOperands = false;
   
   DagInit *DI;


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.114 llvm/utils/TableGen/DAGISelEmitter.cpp:1.115
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.114	Thu Dec 22 14:37:36 2005
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Fri Dec 23 16:11:47 2005
@@ -489,9 +489,6 @@
   } else if (R->getName() == "node" || R->getName() == "srcvalue") {
     // Placeholder.
     return MVT::isUnknown;
-  } else if (R->getName() == "FLAG") {
-    // Some pseudo flag operand.
-    return MVT::Flag;
   }
   
   TP.error("Unknown node flavor used in pattern: " + R->getName());
@@ -955,13 +952,16 @@
 /// HandleUse - Given "Pat" a leaf in the pattern, check to see if it is an
 /// instruction input.  Return true if this is a real use.
 static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
-                      std::map<std::string, TreePatternNode*> &InstInputs) {
+                      std::map<std::string, TreePatternNode*> &InstInputs,
+                      std::vector<Record*> &InstImpInputs) {
   // No name -> not interesting.
   if (Pat->getName().empty()) {
     if (Pat->isLeaf()) {
       DefInit *DI = dynamic_cast<DefInit*>(Pat->getLeafValue());
       if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
         I->error("Input " + DI->getDef()->getName() + " must be named!");
+      else if (DI && DI->getDef()->isSubClassOf("Register")) 
+        InstImpInputs.push_back(DI->getDef());
     }
     return false;
   }
@@ -1008,9 +1008,10 @@
 FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
                             std::map<std::string, TreePatternNode*> &InstInputs,
                             std::map<std::string, Record*> &InstResults,
+                            std::vector<Record*> &InstImpInputs,
                             std::vector<Record*> &InstImpResults) {
   if (Pat->isLeaf()) {
-    bool isUse = HandleUse(I, Pat, InstInputs);
+    bool isUse = HandleUse(I, Pat, InstInputs, InstImpInputs);
     if (!isUse && Pat->getTransformFn())
       I->error("Cannot specify a transform function for a non-input value!");
     return;
@@ -1021,14 +1022,14 @@
       if (Pat->getChild(i)->getExtType() == MVT::isVoid)
         I->error("Cannot have void nodes inside of patterns!");
       FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults,
-                                  InstImpResults);
+                                  InstImpInputs, InstImpResults);
     }
     
     // If this is a non-leaf node with no children, treat it basically as if
     // it were a leaf.  This handles nodes like (imm).
     bool isUse = false;
     if (Pat->getNumChildren() == 0)
-      isUse = HandleUse(I, Pat, InstInputs);
+      isUse = HandleUse(I, Pat, InstInputs, InstImpInputs);
     
     if (!isUse && Pat->getTransformFn())
       I->error("Cannot specify a transform function for a non-input value!");
@@ -1061,8 +1062,7 @@
       if (InstResults.count(Dest->getName()))
         I->error("cannot set '" + Dest->getName() +"' multiple times");
       InstResults[Dest->getName()] = Val->getDef();
-    } else if (Val->getDef()->isSubClassOf("Register") ||
-               Val->getDef()->getName() == "FLAG") {
+    } else if (Val->getDef()->isSubClassOf("Register")) {
       InstImpResults.push_back(Val->getDef());
     } else {
       I->error("set destination should be a register!");
@@ -1070,39 +1070,11 @@
     
     // Verify and collect info from the computation.
     FindPatternInputsAndOutputs(I, Pat->getChild(i+NumValues),
-                                InstInputs, InstResults, InstImpResults);
+                                InstInputs, InstResults,
+                                InstImpInputs, InstImpResults);
   }
 }
 
-/// NodeHasChain - return true if TreePatternNode has the property
-/// 'hasChain', meaning it reads a ctrl-flow chain operand and writes
-/// a chain result.
-static bool NodeHasChain(TreePatternNode *N, DAGISelEmitter &ISE)
-{
-  if (N->isLeaf()) return false;
-  Record *Operator = N->getOperator();
-  if (!Operator->isSubClassOf("SDNode")) return false;
-
-  const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(Operator);
-  return NodeInfo.hasProperty(SDNodeInfo::SDNPHasChain);
-}
-
-static bool PatternHasCtrlDep(TreePatternNode *N, DAGISelEmitter &ISE)
-{
-  if (NodeHasChain(N, ISE))
-    return true;
-  else {
-    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
-      TreePatternNode *Child = N->getChild(i);
-      if (PatternHasCtrlDep(Child, ISE))
-        return true;
-    }
-  }
-
-  return false;
-}
-
-
 /// ParseInstructions - Parse all of the instructions, inlining and resolving
 /// any fragments involved.  This populates the Instructions list with fully
 /// resolved instructions.
@@ -1147,7 +1119,8 @@
       std::vector<Record*> ImpResults;
       std::vector<Record*> ImpOperands;
       Instructions.insert(std::make_pair(Instrs[i], 
-                          DAGInstruction(0, Results, Operands, ImpResults)));
+                          DAGInstruction(0, Results, Operands, ImpResults,
+                                         ImpOperands)));
       continue;  // no pattern.
     }
     
@@ -1168,6 +1141,8 @@
     // InstResults - Keep track of all the virtual registers that are 'set'
     // in the instruction, including what reg class they are.
     std::map<std::string, Record*> InstResults;
+
+    std::vector<Record*> InstImpInputs;
     std::vector<Record*> InstImpResults;
     
     // Verify that the top-level forms in the instruction are of void type, and
@@ -1180,7 +1155,7 @@
 
       // Find inputs and outputs, and verify the structure of the uses/defs.
       FindPatternInputsAndOutputs(I, Pat, InstInputs, InstResults,
-                                  InstImpResults);
+                                  InstImpInputs, InstImpResults);
     }
 
     // Now that we have inputs and outputs of the pattern, inspect the operands
@@ -1269,7 +1244,7 @@
       new TreePatternNode(I->getRecord(), ResultNodeOperands);
 
     // Create and insert the instruction.
-    DAGInstruction TheInst(I, Results, Operands, InstImpResults);
+    DAGInstruction TheInst(I, Results, Operands, InstImpResults, InstImpInputs);
     Instructions.insert(std::make_pair(I->getRecord(), TheInst));
 
     // Use a temporary tree pattern to infer all types and make sure that the
@@ -1316,11 +1291,6 @@
     PatternsToMatch.
       push_back(PatternToMatch(Instr->getValueAsListInit("Predicates"),
                                SrcPattern, DstPattern));
-
-    if (PatternHasCtrlDep(Pattern, *this)) {
-      CodeGenInstruction &InstInfo = Target.getInstruction(Instr->getName());
-      InstInfo.hasCtrlDep = true;
-    }
   }
 }
 
@@ -1343,10 +1313,11 @@
     {
       std::map<std::string, TreePatternNode*> InstInputs;
       std::map<std::string, Record*> InstResults;
+      std::vector<Record*> InstImpInputs;
       std::vector<Record*> InstImpResults;
       FindPatternInputsAndOutputs(Pattern, Pattern->getOnlyTree(),
                                   InstInputs, InstResults,
-                                  InstImpResults);
+                                  InstImpInputs, InstImpResults);
     }
     
     ListInit *LI = Patterns[i]->getValueAsListInit("ResultInstrs");
@@ -1741,6 +1712,34 @@
   return N;
 }
 
+/// NodeHasChain - return true if TreePatternNode has the property
+/// 'hasChain', meaning it reads a ctrl-flow chain operand and writes
+/// a chain result.
+static bool NodeHasChain(TreePatternNode *N, DAGISelEmitter &ISE)
+{
+  if (N->isLeaf()) return false;
+  Record *Operator = N->getOperator();
+  if (!Operator->isSubClassOf("SDNode")) return false;
+
+  const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(Operator);
+  return NodeInfo.hasProperty(SDNodeInfo::SDNPHasChain);
+}
+
+static bool PatternHasCtrlDep(TreePatternNode *N, DAGISelEmitter &ISE)
+{
+  if (NodeHasChain(N, ISE))
+    return true;
+  else {
+    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+      TreePatternNode *Child = N->getChild(i);
+      if (PatternHasCtrlDep(Child, ISE))
+        return true;
+    }
+  }
+
+  return false;
+}
+
 class PatternCodeEmitter {
 private:
   DAGISelEmitter &ISE;
@@ -1757,17 +1756,14 @@
   std::map<std::string,std::string> VariableMap;
   // Names of all the folded nodes which produce chains.
   std::vector<std::pair<std::string, unsigned> > FoldedChains;
-  bool FoundChain;
   unsigned TmpNo;
-  unsigned NumImpInputs;
 
 public:
   PatternCodeEmitter(DAGISelEmitter &ise, ListInit *preds,
                      TreePatternNode *pattern, TreePatternNode *instr,
                      unsigned PatNum, std::ostream &os) :
     ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr),
-    PatternNo(PatNum), OS(os), FoundChain(false), TmpNo(0),
-    NumImpInputs(0) {}
+    PatternNo(PatNum), OS(os), TmpNo(0) {}
 
   /// isPredeclaredSDOperand - Return true if this is one of the predeclared
   /// SDOperands.
@@ -1794,7 +1790,7 @@
   /// 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 EmitMatchCode(TreePatternNode *N, const std::string &RootName,
-                     bool isRoot = false) {
+                     bool &FoundChain, bool isRoot = false) {
 
     // Emit instruction predicates. Each predicate is just a string for now.
     if (isRoot) {
@@ -1873,7 +1869,7 @@
         const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator());
         OS << "      if (" << RootName << OpNo << ".getOpcode() != "
            << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n";
-        EmitMatchCode(Child, RootName + utostr(OpNo));
+        EmitMatchCode(Child, RootName + utostr(OpNo), FoundChain);
         if (NodeHasChain(Child, ISE)) {
           FoldedChains.push_back(std::make_pair(RootName + utostr(OpNo),
                                                 CInfo.getNumResults()));
@@ -1903,12 +1899,8 @@
             // Handle register references.  Nothing to do here.
           } else if (LeafRec->isSubClassOf("Register")) {
             // Handle register references.
-            NumImpInputs++;
           } else if (LeafRec->isSubClassOf("ComplexPattern")) {
             // Handle complex pattern. Nothing to do here.
-          } else if (LeafRec->getName() == "FLAG") {
-            // Handle pseudo FLAG register nodes.
-            NumImpInputs++;
           } else if (LeafRec->getName() == "srcvalue") {
             // Place holder for SRCVALUE nodes. Nothing to do here.
           } else if (LeafRec->isSubClassOf("ValueType")) {
@@ -2048,11 +2040,18 @@
 
     Record *Op = N->getOperator();
     if (Op->isSubClassOf("Instruction")) {
+      const CodeGenTarget &CGT = ISE.getTargetInfo();
+      CodeGenInstruction &II = CGT.getInstruction(Op->getName());
       const DAGInstruction &Inst = ISE.getInstruction(Op);
-      bool InFlag  = NumImpInputs > 0;
-      bool OutFlag = Inst.getNumImpResults() > 0;
-
-      if (InFlag || OutFlag)
+      bool HasImpInputs  = Inst.getNumImpOperands() > 0;
+      bool HasImpResults = Inst.getNumImpResults() > 0;
+      bool HasInFlag  = II.hasInFlag  || HasImpInputs;
+      bool HasOutFlag = II.hasOutFlag || HasImpResults;
+      bool HasChain   = II.hasCtrlDep;
+
+      if (isRoot && PatternHasCtrlDep(Pattern, ISE))
+        HasChain = true;
+      if (HasInFlag || HasOutFlag)
         OS << "      InFlag = SDOperand(0, 0);\n";
 
       // Determine operand emission order. Complex pattern first.
@@ -2086,14 +2085,11 @@
           Ops.push_back(NumTemps[i].second + j);
       }
 
-      const CodeGenTarget &CGT = ISE.getTargetInfo();
-      CodeGenInstruction &II = CGT.getInstruction(Op->getName());
-
       // Emit all the chain and CopyToReg stuff.
-      if (II.hasCtrlDep)
+      if (HasChain)
         OS << "      Chain = Select(Chain);\n";
-      if (InFlag)
-        EmitCopyToRegs(Pattern, "N", II.hasCtrlDep);
+      if (HasInFlag)
+        EmitInFlags(Pattern, "N", HasChain, II.hasInFlag, true);
 
       unsigned NumResults = Inst.getNumResults();    
       unsigned ResNo = TmpNo++;
@@ -2104,7 +2100,7 @@
            << II.Namespace << "::" << II.TheDef->getName();
         if (N->getType() != MVT::isVoid)
           OS << ", MVT::" << getEnumName(N->getType());
-        if (OutFlag)
+        if (HasOutFlag)
           OS << ", MVT::Flag";
 
         unsigned LastOp = 0;
@@ -2113,12 +2109,12 @@
           OS << ", Tmp" << LastOp;
         }
         OS << ");\n";
-        if (II.hasCtrlDep) {
+        if (HasChain) {
           // Must have at least one result
           OS << "      Chain = Tmp" << LastOp << ".getValue("
              << NumResults << ");\n";
         }
-      } else if (II.hasCtrlDep || OutFlag) {
+      } else if (HasChain || HasOutFlag) {
         OS << "      Result = CurDAG->getTargetNode("
            << II.Namespace << "::" << II.TheDef->getName();
 
@@ -2129,16 +2125,16 @@
           if (N->getType() != MVT::isVoid)
             OS << ", MVT::" << getEnumName(N->getType());
         }
-        if (II.hasCtrlDep)
+        if (HasChain)
           OS << ", MVT::Other";
-        if (OutFlag)
+        if (HasOutFlag)
           OS << ", MVT::Flag";
 
         // Inputs.
         for (unsigned i = 0, e = Ops.size(); i != e; ++i)
           OS << ", Tmp" << Ops[i];
-        if (II.hasCtrlDep) OS << ", Chain";
-        if (InFlag)        OS << ", InFlag";
+        if (HasChain)  OS << ", Chain";
+        if (HasInFlag) OS << ", InFlag";
         OS << ");\n";
 
         unsigned ValNo = 0;
@@ -2148,27 +2144,24 @@
           ValNo++;
         }
 
-        if (II.hasCtrlDep)
+        if (HasChain)
           OS << "      Chain = Result.getValue(" << ValNo << ");\n";
 
-        if (OutFlag)
+        if (HasOutFlag)
           OS << "      InFlag = Result.getValue("
-             << ValNo + (unsigned)II.hasCtrlDep << ");\n";
+             << ValNo + (unsigned)HasChain << ");\n";
 
-        unsigned NumCopies = 0;
-        if (OutFlag) {
-          NumCopies = EmitCopyFromRegs(N, II.hasCtrlDep);
-          for (unsigned i = 0; i < NumCopies; i++) {
+        if (HasImpResults) {
+          if (EmitCopyFromRegs(N, HasChain)) {
             OS << "      CodeGenMap[N.getValue(" << ValNo << ")] = "
                << "Result.getValue(" << ValNo << ");\n";
             ValNo++;
+            HasChain = true;
           }
         }
 
-        // User does not expect that I produce a chain!
-        bool AddedChain =
-          !NodeHasChain(Pattern, ISE) && (II.hasCtrlDep || NumCopies > 0);
-
+        // User does not expect that the instruction produces a chain!
+        bool AddedChain = HasChain && !NodeHasChain(Pattern, ISE);
         if (NodeHasChain(Pattern, ISE))
           OS << "      CodeGenMap[N.getValue(" << ValNo++  << ")] = Chain;\n";
 
@@ -2180,10 +2173,10 @@
           OS << "Chain;\n";
         }
 
-        if (OutFlag)
+        if (HasOutFlag)
           OS << "      CodeGenMap[N.getValue(" << ValNo << ")] = InFlag;\n";
 
-        if (AddedChain && OutFlag) {
+        if (AddedChain && HasOutFlag) {
           if (NumResults == 0) {
             OS << "      return Result.getValue(N.ResNo+1);\n";
           } else {
@@ -2203,11 +2196,11 @@
            << II.Namespace << "::" << II.TheDef->getName();
         if (N->getType() != MVT::isVoid)
           OS << ", MVT::" << getEnumName(N->getType());
-        if (OutFlag)
+        if (HasOutFlag)
           OS << ", MVT::Flag";
         for (unsigned i = 0, e = Ops.size(); i != e; ++i)
           OS << ", Tmp" << Ops[i];
-        if (InFlag)
+        if (HasInFlag)
           OS << ", InFlag";
         OS << ");\n";
         OS << "      } else {\n";
@@ -2215,11 +2208,11 @@
            << II.Namespace << "::" << II.TheDef->getName();
         if (N->getType() != MVT::isVoid)
           OS << ", MVT::" << getEnumName(N->getType());
-        if (OutFlag)
+        if (HasOutFlag)
           OS << ", MVT::Flag";
         for (unsigned i = 0, e = Ops.size(); i != e; ++i)
           OS << ", Tmp" << Ops[i];
-        if (InFlag)
+        if (HasInFlag)
           OS << ", InFlag";
         OS << ");\n";
         OS << "      }\n";
@@ -2270,16 +2263,16 @@
   }
 
 private:
-  /// EmitCopyToRegs - Emit the flag operands for the DAG that is
+  /// EmitInFlags - Emit the flag operands for the DAG that is
   /// being built.
-  void EmitCopyToRegs(TreePatternNode *N, const std::string &RootName,
-                      bool HasCtrlDep) {
+  void EmitInFlags(TreePatternNode *N, const std::string &RootName,
+                   bool HasChain, bool HasInFlag, bool isRoot = false) {
     const CodeGenTarget &T = ISE.getTargetInfo();
     unsigned OpNo = (unsigned) NodeHasChain(N, ISE);
     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
       TreePatternNode *Child = N->getChild(i);
       if (!Child->isLeaf()) {
-        EmitCopyToRegs(Child, RootName + utostr(OpNo), HasCtrlDep);
+        EmitInFlags(Child, RootName + utostr(OpNo), HasChain, HasInFlag);
       } else {
         if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
           Record *RR = DI->getDef();
@@ -2287,7 +2280,7 @@
             MVT::ValueType RVT = getRegisterValueType(RR, T);
             if (RVT == MVT::Flag) {
               OS << "      InFlag = Select(" << RootName << OpNo << ");\n";
-            } else if (HasCtrlDep) {
+            } else if (HasChain) {
               OS << "      SDOperand " << RootName << "CR" << i << ";\n";
               OS << "      " << RootName << "CR" << i
                  << "  = CurDAG->getCopyToReg(Chain, CurDAG->getRegister("
@@ -2305,19 +2298,23 @@
                  << ", Select(" << RootName << OpNo
                  << "), InFlag).getValue(1);\n";
             }
-          } else if (RR->getName() == "FLAG") {
-            OS << "      InFlag = Select(" << RootName << OpNo << ");\n";
           }
         }
       }
     }
+
+    if (isRoot && HasInFlag) {
+      OS << "      " << RootName << OpNo << " = " << RootName
+         << ".getOperand(" << OpNo << ");\n";
+      OS << "      InFlag = Select(" << RootName << OpNo << ");\n";
+    }
   }
 
   /// EmitCopyFromRegs - Emit code to copy result to physical registers
-  /// as specified by the instruction. It returns the number of
-  /// CopyFromRegs emitted.
-  unsigned EmitCopyFromRegs(TreePatternNode *N, bool HasCtrlDep) {
-    unsigned NumCopies = 0;
+  /// as specified by the instruction. It returns true if any copy is
+  /// emitted.
+  bool EmitCopyFromRegs(TreePatternNode *N, bool HasChain) {
+    bool RetVal = false;
     Record *Op = N->getOperator();
     if (Op->isSubClassOf("Instruction")) {
       const DAGInstruction &Inst = ISE.getInstruction(Op);
@@ -2329,7 +2326,7 @@
         if (RR->isSubClassOf("Register")) {
           MVT::ValueType RVT = getRegisterValueType(RR, CGT);
           if (RVT != MVT::Flag) {
-            if (HasCtrlDep) {
+            if (HasChain) {
               OS << "      Result = CurDAG->getCopyFromReg(Chain, "
                  << ISE.getQualifiedName(RR)
                  << ", MVT::" << getEnumName(RVT) << ", InFlag);\n";
@@ -2343,12 +2340,12 @@
               OS << "      Chain  = Result.getValue(1);\n";
               OS << "      InFlag = Result.getValue(2);\n";
             }
-            NumCopies++;
+            RetVal = true;
           }
         }
       }
     }
-    return NumCopies;
+    return RetVal;
   }
 };
 
@@ -2374,7 +2371,9 @@
                              PatternNo, OS);
 
   // Emit the matcher, capturing named arguments in VariableMap.
-  Emitter.EmitMatchCode(Pattern.getSrcPattern(), "N", true /*the root*/);
+  bool FoundChain = false;
+  Emitter.EmitMatchCode(Pattern.getSrcPattern(), "N", FoundChain,
+                        true /*the root*/);
 
   // TP - Get *SOME* tree pattern, we don't care which.
   TreePattern &TP = *PatternFragments.begin()->second;


Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.47 llvm/utils/TableGen/DAGISelEmitter.h:1.48
--- llvm/utils/TableGen/DAGISelEmitter.h:1.47	Wed Dec 21 20:24:50 2005
+++ llvm/utils/TableGen/DAGISelEmitter.h	Fri Dec 23 16:11:47 2005
@@ -328,19 +328,23 @@
     std::vector<Record*> Results;
     std::vector<Record*> Operands;
     std::vector<Record*> ImpResults;
+    std::vector<Record*> ImpOperands;
     TreePatternNode *ResultPattern;
   public:
     DAGInstruction(TreePattern *TP,
                    const std::vector<Record*> &results,
                    const std::vector<Record*> &operands,
-                   const std::vector<Record*> &impresults)
+                   const std::vector<Record*> &impresults,
+                   const std::vector<Record*> &impoperands)
       : Pattern(TP), Results(results), Operands(operands), 
-        ImpResults(impresults), ResultPattern(0) {}
+        ImpResults(impresults), ImpOperands(impoperands),
+        ResultPattern(0) {}
 
     TreePattern *getPattern() const { return Pattern; }
     unsigned getNumResults() const { return Results.size(); }
     unsigned getNumOperands() const { return Operands.size(); }
     unsigned getNumImpResults() const { return ImpResults.size(); }
+    unsigned getNumImpOperands() const { return ImpOperands.size(); }
     
     void setResultPattern(TreePatternNode *R) { ResultPattern = R; }
     
@@ -359,6 +363,11 @@
       return ImpResults[RN];
     }
     
+    Record *getImpOperand(unsigned ON) const {
+      assert(ON < ImpOperands.size());
+      return ImpOperands[ON];
+    }
+
     TreePatternNode *getResultPattern() const { return ResultPattern; }
   };
   
@@ -444,6 +453,7 @@
                                    std::map<std::string,
                                             TreePatternNode*> &InstInputs,
                                    std::map<std::string, Record*> &InstResults,
+                                   std::vector<Record*> &InstImpInputs,
                                    std::vector<Record*> &InstImpResults);
   void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS);
   void EmitInstructionSelector(std::ostream &OS);






More information about the llvm-commits mailing list