use escape string.
[oota-llvm.git] / utils / TableGen / CodeGenDAGPatterns.h
index 0d29eb51658d63d4c2c7cbefb1f08ba667cda898..f1b0d37605b8185e5e994c8b04abfde21f46f2ce 100644 (file)
@@ -16,6 +16,8 @@
 #define CODEGEN_DAGPATTERNS_H
 
 #include <set>
+#include <algorithm>
+#include <vector>
 
 #include "CodeGenTarget.h"
 #include "CodeGenIntrinsics.h"
@@ -31,15 +33,15 @@ namespace llvm {
   class CodeGenDAGPatterns;
   class ComplexPattern;
 
-/// MVT::DAGISelGenValueType - These are some extended forms of MVT::ValueType
-/// that we use as lattice values during type inferrence.
-namespace MVT {
+/// EMVT::DAGISelGenValueType - These are some extended forms of
+/// MVT::SimpleValueType that we use as lattice values during type inference.
+namespace EMVT {
   enum DAGISelGenValueType {
     isFP  = MVT::LAST_VALUETYPE,
     isInt,
     isUnknown
   };
-  
+
   /// isExtIntegerVT - Return true if the specified extended value type vector
   /// contains isInt or an integer value type.
   bool isExtIntegerInVTs(const std::vector<unsigned char> &EVTs);
@@ -66,7 +68,7 @@ struct SDTypeConstraint {
   
   union {   // The discriminated union.
     struct {
-      MVT::ValueType VT;
+      unsigned char VT;
     } SDTCisVT_Info;
     struct {
       unsigned OtherOperandNum;
@@ -142,8 +144,9 @@ public:
 /// patterns), and as such should be ref counted.  We currently just leak all
 /// TreePatternNode objects!
 class TreePatternNode {
-  /// The inferred type for this node, or MVT::isUnknown if it hasn't
-  /// been determined yet.
+  /// The inferred type for this node, or EMVT::isUnknown if it hasn't
+  /// been determined yet. This is a std::vector because during inference
+  /// there may be multiple possible types.
   std::vector<unsigned char> Types;
   
   /// Operator - The Record for the operator if this is an interior node (not
@@ -158,9 +161,9 @@ class TreePatternNode {
   ///
   std::string Name;
   
-  /// PredicateFn - The predicate function to execute on this node to check
-  /// for a match.  If this string is empty, no predicate is involved.
-  std::string PredicateFn;
+  /// PredicateFns - The predicate functions to execute on this node to check
+  /// for a match.  If this list is empty, no predicate is involved.
+  std::vector<std::string> PredicateFns;
   
   /// TransformFn - The transformation function to execute on this node before
   /// it can be substituted into the resulting instruction on a pattern match.
@@ -170,10 +173,10 @@ class TreePatternNode {
 public:
   TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch) 
     : Types(), Operator(Op), Val(0), TransformFn(0),
-    Children(Ch) { Types.push_back(MVT::isUnknown); }
+    Children(Ch) { Types.push_back(EMVT::isUnknown); }
   TreePatternNode(Init *val)    // leaf ctor
     : Types(), Operator(0), Val(val), TransformFn(0) {
-    Types.push_back(MVT::isUnknown);
+    Types.push_back(EMVT::isUnknown);
   }
   ~TreePatternNode();
   
@@ -182,18 +185,19 @@ public:
   
   bool isLeaf() const { return Val != 0; }
   bool hasTypeSet() const {
-    return (Types[0] < MVT::LAST_VALUETYPE) || (Types[0] == MVT::iPTR);
+    return (Types[0] < MVT::LAST_VALUETYPE) || (Types[0] == MVT::iPTR) || 
+          (Types[0] == MVT::iPTRAny);
   }
   bool isTypeCompletelyUnknown() const {
-    return Types[0] == MVT::isUnknown;
+    return Types[0] == EMVT::isUnknown;
   }
   bool isTypeDynamicallyResolved() const {
-    return Types[0] == MVT::iPTR;
+    return (Types[0] == MVT::iPTR) || (Types[0] == MVT::iPTRAny);
   }
-  MVT::ValueType getTypeNum(unsigned Num) const {
+  MVT::SimpleValueType getTypeNum(unsigned Num) const {
     assert(hasTypeSet() && "Doesn't have a type yet!");
     assert(Types.size() > Num && "Type num out of range!");
-    return (MVT::ValueType)Types[Num];
+    return (MVT::SimpleValueType)Types[Num];
   }
   unsigned char getExtTypeNum(unsigned Num) const { 
     assert(Types.size() > Num && "Extended type num out of range!");
@@ -201,7 +205,7 @@ public:
   }
   const std::vector<unsigned char> &getExtTypes() const { return Types; }
   void setTypes(const std::vector<unsigned char> &T) { Types = T; }
-  void removeTypes() { Types = std::vector<unsigned char>(1,MVT::isUnknown); }
+  void removeTypes() { Types = std::vector<unsigned char>(1, EMVT::isUnknown); }
   
   Init *getLeafValue() const { assert(isLeaf()); return Val; }
   Record *getOperator() const { assert(!isLeaf()); return Operator; }
@@ -212,8 +216,18 @@ public:
     Children[i] = N;
   }
 
-  const std::string &getPredicateFn() const { return PredicateFn; }
-  void setPredicateFn(const std::string &Fn) { PredicateFn = Fn; }
+  const std::vector<std::string> &getPredicateFns() const { return PredicateFns; }
+  void clearPredicateFns() { PredicateFns.clear(); }
+  void setPredicateFns(const std::vector<std::string> &Fns) {
+    assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
+    PredicateFns = Fns;
+  }
+  void addPredicateFn(const std::string &Fn) { 
+    assert(!Fn.empty() && "Empty predicate string!");
+    if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) ==
+          PredicateFns.end())
+      PredicateFns.push_back(Fn);
+  }
 
   Record *getTransformFn() const { return TransformFn; }
   void setTransformFn(Record *Fn) { TransformFn = Fn; }
@@ -221,6 +235,10 @@ public:
   /// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
   /// CodeGenIntrinsic information for it, otherwise return a null pointer.
   const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
+
+  /// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
+  /// marked isCommutative.
+  bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
   
   void print(std::ostream &OS) const;
   void dump() const;
@@ -248,7 +266,7 @@ public:   // Higher level manipulation routines.
   /// PatFrag references.
   TreePatternNode *InlinePatternFragments(TreePattern &TP);
   
-  /// ApplyTypeConstraints - Apply all of the type constraints relevent to
+  /// ApplyTypeConstraints - Apply all of the type constraints relevant to
   /// this node and its children in the tree.  This returns true if it makes a
   /// change, false otherwise.  If a type contradiction is found, throw an
   /// exception.
@@ -348,7 +366,7 @@ public:
   }
   
   /// InferAllTypes - Infer/propagate as many types throughout the expression
-  /// patterns as possible.  Return true if all types are infered, false
+  /// patterns as possible.  Return true if all types are inferred, false
   /// otherwise.  Throw an exception if a type contradiction is found.
   bool InferAllTypes();
   
@@ -439,6 +457,8 @@ struct PatternToMatch {
   TreePatternNode *getDstPattern() const { return DstPattern; }
   const std::vector<Record*> &getDstRegs() const { return Dstregs; }
   unsigned         getAddedComplexity() const { return AddedComplexity; }
+
+  std::string getPredicateCheck() const;
 };
 
   
@@ -446,6 +466,7 @@ class CodeGenDAGPatterns {
   RecordKeeper &Records;
   CodeGenTarget Target;
   std::vector<CodeGenIntrinsic> Intrinsics;
+  std::vector<CodeGenIntrinsic> TgtIntrinsics;
   
   std::map<Record*, SDNodeInfo> SDNodes;
   std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
@@ -496,18 +517,26 @@ public:
   const CodeGenIntrinsic &getIntrinsic(Record *R) const {
     for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
       if (Intrinsics[i].TheDef == R) return Intrinsics[i];
+    for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+      if (TgtIntrinsics[i].TheDef == R) return TgtIntrinsics[i];
     assert(0 && "Unknown intrinsic!");
     abort();
   }
   
   const CodeGenIntrinsic &getIntrinsicInfo(unsigned IID) const {
-    assert(IID-1 < Intrinsics.size() && "Bad intrinsic ID!");
-    return Intrinsics[IID-1];
+    if (IID-1 < Intrinsics.size())
+      return Intrinsics[IID-1];
+    if (IID-Intrinsics.size()-1 < TgtIntrinsics.size())
+      return TgtIntrinsics[IID-Intrinsics.size()-1];
+    assert(0 && "Bad intrinsic ID!");
+    abort();
   }
   
   unsigned getIntrinsicID(Record *R) const {
     for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i)
       if (Intrinsics[i].TheDef == R) return i;
+    for (unsigned i = 0, e = TgtIntrinsics.size(); i != e; ++i)
+      if (TgtIntrinsics[i].TheDef == R) return i + Intrinsics.size();
     assert(0 && "Unknown intrinsic!");
     abort();
   }