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

Chris Lattner lattner at cs.uiuc.edu
Wed Sep 28 12:27:37 PDT 2005



Changes in directory llvm/utils/TableGen:

DAGISelEmitter.cpp updated: 1.47 -> 1.48
DAGISelEmitter.h updated: 1.26 -> 1.27
---
Log message:

Emit an error if instructions or patterns are defined but can never match.
Currently we check that immediate values live on the RHS of commutative 
operators.  Defining ORI like this, for example:

def ORI   : DForm_4<24, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2),
                    "ori $dst, $src1, $src2",
                    [(set GPRC:$dst, (or immZExt16:$src2, GPRC:$src1))]>;

results in:

tblgen: In ORI: Instruction can never match: Immediate values must be on the RHS of commutative operators!



---
Diffs of the changes:  (+52 -3)

 DAGISelEmitter.cpp |   50 +++++++++++++++++++++++++++++++++++++++++++++++---
 DAGISelEmitter.h   |    5 +++++
 2 files changed, 52 insertions(+), 3 deletions(-)


Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.47 llvm/utils/TableGen/DAGISelEmitter.cpp:1.48
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.47	Wed Sep 28 13:28:29 2005
+++ llvm/utils/TableGen/DAGISelEmitter.cpp	Wed Sep 28 14:27:25 2005
@@ -372,6 +372,34 @@
   }
 }
 
+/// canPatternMatch - If it is impossible for this pattern to match on this
+/// target, fill in Reason and return false.  Otherwise, return true.  This is
+/// used as a santity check for .td files (to prevent people from writing stuff
+/// that can never possibly work), and to prevent the pattern permuter from
+/// generating stuff that is useless.
+bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE) {
+  if (isLeaf()) return true;
+
+  for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+    if (!getChild(i)->canPatternMatch(Reason, ISE))
+      return false;
+  
+  // If this node is a commutative operator, check that the LHS isn't an
+  // immediate.
+  const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator());
+  if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) {
+    // Scan all of the operands of the node and make sure that only the last one
+    // is a constant node.
+    for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i)
+      if (!getChild(i)->isLeaf() && 
+          getChild(i)->getOperator()->getName() == "imm") {
+        Reason = "Immediate value must be on the RHS of commutative operators!";
+        return false;
+      }
+  }
+  
+  return true;
+}
 
 //===----------------------------------------------------------------------===//
 // TreePattern implementation
@@ -962,6 +990,11 @@
       continue;  // Not a set of a single value (not handled so far)
     
     TreePatternNode *SrcPattern = Pattern->getChild(1)->clone();
+    
+    std::string Reason;
+    if (!SrcPattern->canPatternMatch(Reason, *this))
+      I->error("Instruction can never match: " + Reason);
+    
     TreePatternNode *DstPattern = II->second.getResultPattern();
     PatternsToMatch.push_back(std::make_pair(SrcPattern, DstPattern));
   }
@@ -999,6 +1032,11 @@
     if (Result->getNumTrees() != 1)
       Result->error("Cannot handle instructions producing instructions "
                     "with temporaries yet!");
+
+    std::string Reason;
+    if (!Pattern->getOnlyTree()->canPatternMatch(Reason, *this))
+      Pattern->error("Pattern can never match: " + Reason);
+    
     PatternsToMatch.push_back(std::make_pair(Pattern->getOnlyTree(),
                                              Result->getOnlyTree()));
   }
@@ -1011,6 +1049,12 @@
         });
 }
 
+// GenerateVariants - Generate variants.  For example, commutative patterns can
+// match multiple ways.  Add them to PatternsToMatch as well.
+void DAGISelEmitter::GenerateVariants() {
+  
+}
+
 /// getPatternSize - Return the 'size' of this pattern.  We want to match large
 /// patterns before small ones.  This is used to determine the size of a
 /// pattern.
@@ -1331,13 +1375,13 @@
   ParseInstructions();
   ParsePatterns();
   
-  // FIXME: Generate variants.  For example, commutative patterns can match
+  // Generate variants.  For example, commutative patterns can match
   // multiple ways.  Add them to PatternsToMatch as well.
+  GenerateVariants();
 
   // At this point, we have full information about the 'Patterns' we need to
   // parse, both implicitly from instructions as well as from explicit pattern
-  // definitions.
-  
+  // definitions.  Emit the resultant instruction selector.
   EmitInstructionSelector(OS);  
   
   for (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),


Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.26 llvm/utils/TableGen/DAGISelEmitter.h:1.27
--- llvm/utils/TableGen/DAGISelEmitter.h:1.26	Wed Sep 28 13:28:29 2005
+++ llvm/utils/TableGen/DAGISelEmitter.h	Wed Sep 28 14:27:25 2005
@@ -204,6 +204,10 @@
         if (getChild(i)->ContainsUnresolvedType()) return true;
       return false;
     }
+    
+    /// canPatternMatch - Return false if it is impossible for this pattern to
+    /// match on this target.
+    bool canPatternMatch(std::string &Reason, DAGISelEmitter &ISE);
   };
   
   
@@ -369,6 +373,7 @@
   void ParsePatternFragments(std::ostream &OS);
   void ParseInstructions();
   void ParsePatterns();
+  void GenerateVariants();
   void FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
                                    std::map<std::string,
                                             TreePatternNode*> &InstInputs,






More information about the llvm-commits mailing list