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

Chris Lattner sabre at nondot.org
Fri Nov 3 21:12:17 PST 2006



Changes in directory llvm/utils/TableGen:

DAGISelEmitter.cpp updated: 1.278 -> 1.279
DAGISelEmitter.h updated: 1.70 -> 1.71
---
Log message:

Parse PredicateOperand's.  When an instruction takes one, have the generated
isel fill in the instruction operands with the 'execute always' value 
automatically.


---
Diffs of the changes:  (+86 -6)

 DAGISelEmitter.cpp |   80 +++++++++++++++++++++++++++++++++++++++++++++++++----
 DAGISelEmitter.h   |   12 +++++++
 2 files changed, 86 insertions(+), 6 deletions(-)


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.278 llvm/utils/TableGen/DAGISelEmitter.cpp:1.279
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.278	Fri Nov  3 19:35:50 2006
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Fri Nov  3 23:12:02 2006
@@ -1230,6 +1230,50 @@
   }
 }
 
+void DAGISelEmitter::ParsePredicateOperands() {
+  std::vector<Record*> PredOps =
+    Records.getAllDerivedDefinitions("PredicateOperand");
+
+  // Find some SDNode.
+  assert(!SDNodes.empty() && "No SDNodes parsed?");
+  Init *SomeSDNode = new DefInit(SDNodes.begin()->first);
+  
+  for (unsigned i = 0, e = PredOps.size(); i != e; ++i) {
+    DagInit *AlwaysInfo = PredOps[i]->getValueAsDag("ExecuteAlways");
+    
+    // Clone the AlwaysInfo dag node, changing the operator from 'ops' to
+    // SomeSDnode so that we can parse this.
+    std::vector<std::pair<Init*, std::string> > Ops;
+    for (unsigned op = 0, e = AlwaysInfo->getNumArgs(); op != e; ++op)
+      Ops.push_back(std::make_pair(AlwaysInfo->getArg(op),
+                                   AlwaysInfo->getArgName(op)));
+    DagInit *DI = new DagInit(SomeSDNode, Ops);
+    
+    // Create a TreePattern to parse this.
+    TreePattern P(PredOps[i], DI, false, *this);
+    assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
+
+    // Copy the operands over into a DAGPredicateOperand.
+    DAGPredicateOperand PredOpInfo;
+    
+    TreePatternNode *T = P.getTree(0);
+    for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
+      TreePatternNode *TPN = T->getChild(op);
+      while (TPN->ApplyTypeConstraints(P, false))
+        /* Resolve all types */;
+      
+      if (TPN->ContainsUnresolvedType())
+        throw "Value #" + utostr(i) + " of PredicateOperand '" +
+              PredOps[i]->getName() + "' doesn't have a concrete type!";
+      
+      PredOpInfo.AlwaysOps.push_back(TPN);
+    }
+
+    // Insert it into the PredicateOperands map so we can find it later.
+    PredicateOperands[PredOps[i]] = PredOpInfo;
+  }
+}
+
 /// 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,
@@ -1496,7 +1540,7 @@
         if (Op.Rec->isSubClassOf("PredicateOperand")) {
           // Does it have a non-empty ExecuteAlways field?  If so, ignore this
           // operand.
-          if (Op.Rec->getValueAsDag("ExecuteAlways")->getNumArgs())
+          if (!getPredicateOperand(Op.Rec).AlwaysOps.empty())
             continue;
         }
         I->error("Operand $" + OpName +
@@ -2690,6 +2734,7 @@
         PatternHasProperty(InstPatNode, SDNPHasChain, ISE);
       bool InputHasChain = isRoot &&
         NodeHasProperty(Pattern, SDNPHasChain, ISE);
+      unsigned NumResults = Inst.getNumResults();    
 
       if (NodeHasOptInFlag) {
         emitCode("bool HasInFlag = "
@@ -2726,11 +2771,34 @@
                  "&InChains[0], InChains.size());");
       }
 
+      // Loop over all of the operands of the instruction pattern, emitting code
+      // to fill them all in.  The node 'N' usually has number children equal to
+      // the number of input operands of the instruction.  However, in cases
+      // where there are predicate operands for an instruction, we need to fill
+      // in the 'execute always' values.  Match up the node operands to the
+      // instruction operands to do this.
       std::vector<std::string> AllOps;
-      for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
-        std::vector<std::string> Ops = EmitResultCode(N->getChild(i),
-                                      RetSelected, InFlagDecled, ResNodeDecled);
-        AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+      for (unsigned ChildNo = 0, InstOpNo = NumResults;
+           InstOpNo != II.OperandList.size(); ++InstOpNo) {
+        std::vector<std::string> Ops;
+        
+        // If this is a normal operand, emit it.
+        if (!II.OperandList[InstOpNo].Rec->isSubClassOf("PredicateOperand")) {
+          Ops = EmitResultCode(N->getChild(ChildNo), RetSelected, 
+                               InFlagDecled, ResNodeDecled);
+          AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+          ++ChildNo;
+        } else {
+          // Otherwise, this is a predicate operand, emit the 'execute always'
+          // operands.
+          const DAGPredicateOperand &Pred =
+            ISE.getPredicateOperand(II.OperandList[InstOpNo].Rec);
+          for (unsigned i = 0, e = Pred.AlwaysOps.size(); i != e; ++i) {
+            Ops = EmitResultCode(Pred.AlwaysOps[i], RetSelected, 
+                                 InFlagDecled, ResNodeDecled);
+            AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+          }
+        }
       }
 
       // Emit all the chain and CopyToReg stuff.
@@ -2753,7 +2821,6 @@
         }
       }
 
-      unsigned NumResults = Inst.getNumResults();    
       unsigned ResNo = TmpNo++;
       if (!isRoot || InputHasChain || NodeHasChain || NodeHasOutFlag ||
           NodeHasOptInFlag) {
@@ -3820,6 +3887,7 @@
   ParseNodeTransforms(OS);
   ParseComplexPatterns();
   ParsePatternFragments(OS);
+  ParsePredicateOperands();
   ParseInstructions();
   ParsePatterns();
   


Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.70 llvm/utils/TableGen/DAGISelEmitter.h:1.71
--- llvm/utils/TableGen/DAGISelEmitter.h:1.70	Wed Oct 11 16:02:01 2006
+++ llvm/utils/TableGen/DAGISelEmitter.h	Fri Nov  3 23:12:02 2006
@@ -343,6 +343,11 @@
     TreePatternNode *ParseTreePattern(DagInit *DI);
   };
 
+  /// DAGPredicateOperand - One of these is created for each PredicateOperand
+  /// that has a set ExecuteAlways field.
+  struct DAGPredicateOperand {
+    std::vector<TreePatternNode*> AlwaysOps;
+  };
 
   class DAGInstruction {
     TreePattern *Pattern;
@@ -425,6 +430,7 @@
   std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
   std::map<Record*, ComplexPattern> ComplexPatterns;
   std::map<Record*, TreePattern*> PatternFragments;
+  std::map<Record*, DAGPredicateOperand> PredicateOperands;
   std::map<Record*, DAGInstruction> Instructions;
   
   // Specific SDNode definitions:
@@ -479,6 +485,11 @@
     abort();
   }
   
+  const DAGPredicateOperand &getPredicateOperand(Record *R) {
+    assert(PredicateOperands.count(R) &&"Isn't an analyzed predicate operand!");
+    return PredicateOperands.find(R)->second;
+  }
+  
   TreePattern *getPatternFragment(Record *R) const {
     assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
     return PatternFragments.find(R)->second;
@@ -505,6 +516,7 @@
   void ParseNodeTransforms(std::ostream &OS);
   void ParseComplexPatterns();
   void ParsePatternFragments(std::ostream &OS);
+  void ParsePredicateOperands();
   void ParseInstructions();
   void ParsePatterns();
   void GenerateVariants();






More information about the llvm-commits mailing list