now that predicates have a decent abstraction layer on them, introduce a new
authorChris Lattner <sabre@nondot.org>
Sun, 17 Apr 2011 22:05:17 +0000 (22:05 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 17 Apr 2011 22:05:17 +0000 (22:05 +0000)
kind of predicate: one that is specific to imm nodes.  The predicate function
specified here just checks an int64_t directly instead of messing around with
SDNode's.  The virtue of this is that it means that fastisel and other things
can reason about these predicates.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129675 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetSelectionDAG.td
lib/Target/X86/X86InstrInfo.td
utils/TableGen/CodeGenDAGPatterns.cpp
utils/TableGen/CodeGenDAGPatterns.h
utils/TableGen/Record.h

index ffb9c5ee4924ddac3594c6ab66f38c4564b1e010..f7fac7afa3e5b43f41a99a767eb6f5a541bd89ec 100644 (file)
@@ -520,6 +520,7 @@ class PatFrag<dag ops, dag frag, code pred = [{}],
   dag Operands = ops;
   dag Fragment = frag;
   code PredicateCode = pred;
+  code ImmediateCode = [{}];
   SDNodeXForm OperandTransform = xform;
 }
 
@@ -528,6 +529,22 @@ class PatFrag<dag ops, dag frag, code pred = [{}],
 class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
  : PatFrag<(ops), frag, pred, xform>;
 
+
+// ImmLeaf is a pattern fragment with a constraint on the immediate.  The
+// constraint is a function that is run on the immediate (always with the value
+// sign extended out to an int64_t) as Imm.  The value type being matched is
+// available as VT.  For example:
+//
+//  def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>;
+//
+// this is a more convenient form to match 'imm' nodes in than PatLeaf and also
+// is preferred over using PatLeaf because it allows the code generator to
+// reason more about the constraint.
+class ImmLeaf<ValueType vt, code pred> : PatFrag<(ops), (vt imm)> {
+  let ImmediateCode = pred;
+}
+
+
 // Leaf fragments.
 
 def vtInt      : PatLeaf<(vt),  [{ return N->getVT().isInteger(); }]>;
index d1812254635f10ae155de79a0c27ad71aad3b404..e487e33e738bd83e3e17efc28dfc22f24dcd7ee9 100644 (file)
@@ -486,7 +486,12 @@ def immSext8 : PatLeaf<(imm), [{ return immSext8(N); }]>;
 def i16immSExt8  : PatLeaf<(i16 immSext8)>;
 def i32immSExt8  : PatLeaf<(i32 immSext8)>;
 def i64immSExt8  : PatLeaf<(i64 immSext8)>;
-def i64immSExt32  : PatLeaf<(i64 imm), [{ return i64immSExt32(N); }]>;
+
+
+def i64immSExt32  : ImmLeaf<i64, [{ return Imm == (int32_t)Imm; }]>;
+
+
+
 def i64immZExt32  : PatLeaf<(i64 imm), [{
   // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
   // unsignedsign extended field.
index b74144ebfdc801288743d1fe27696391d04eca2e..13ac6b15ba3ff1892d2968d3316cd4ab34200c5f 100644 (file)
@@ -621,14 +621,24 @@ static void DumpDepVars(MultipleUseVarSet &DepVars) {
 // TreePredicateFn Implementation
 //===----------------------------------------------------------------------===//
 
+/// TreePredicateFn constructor.  Here 'N' is a subclass of PatFrag.
+TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) {
+  assert((getPredCode().empty() || getImmCode().empty()) &&
+        ".td file corrupt: can't have a node predicate *and* an imm predicate");
+}
+
 std::string TreePredicateFn::getPredCode() const {
   return PatFragRec->getRecord()->getValueAsCode("PredicateCode");
 }
 
+std::string TreePredicateFn::getImmCode() const {
+  return PatFragRec->getRecord()->getValueAsCode("ImmediateCode");
+}
+
 
 /// isAlwaysTrue - Return true if this is a noop predicate.
 bool TreePredicateFn::isAlwaysTrue() const {
-  return getPredCode().empty();
+  return getPredCode().empty() && getImmCode().empty();
 }
 
 /// Return the name to use in the generated code to reference this, this is
@@ -642,6 +652,18 @@ std::string TreePredicateFn::getFnName() const {
 /// not N.  This handles casting and conversion to a concrete node type as
 /// appropriate.
 std::string TreePredicateFn::getCodeToRunOnSDNode() const {
+  // Handle immediate predicates first.
+  std::string ImmCode = getImmCode();
+  if (!ImmCode.empty()) {
+    std::string Result =
+      "    int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue();\n";
+    if (ImmCode.find("VT") != std::string::npos)
+      Result += "    MVT VT = Node->getValueType(0).getSimpleVT();\n";
+    return Result + ImmCode;
+  }
+  
+  // Handle arbitrary node predicates.
+  assert(!getPredCode().empty() && "Don't have any predicate code!");
   std::string ClassName;
   if (PatFragRec->getOnlyTree()->isLeaf())
     ClassName = "SDNode";
index 2624495a8dc062dfed5e1db09cbb34b09544ddb0..b113a59e4a94547178d96e4a5f9b4f777a7cd5d8 100644 (file)
@@ -249,7 +249,7 @@ class TreePredicateFn {
   TreePattern *PatFragRec;
 public:
   /// TreePredicateFn constructor.  Here 'N' is a subclass of PatFrag.
-  TreePredicateFn(TreePattern *N) : PatFragRec(N) {}
+  TreePredicateFn(TreePattern *N);
 
   
   TreePattern *getOrigPatFragRecord() const { return PatFragRec; }
@@ -276,6 +276,7 @@ public:
   
 private:
   std::string getPredCode() const;
+  std::string getImmCode() const;
 };
   
 
index f3a5df23ec5c13bea41b085023d5349514a27cae..522b719803c34061a35375b88467ce6001296417 100644 (file)
@@ -707,7 +707,7 @@ class CodeInit : public Init {
 public:
   explicit CodeInit(const std::string &V) : Value(V) {}
 
-  const std::string getValue() const { return Value; }
+  const std::string &getValue() const { return Value; }
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);