Teach tblgen's set theory "sequence" operator to support an optional stride operand.
authorOwen Anderson <resistor@mac.com>
Thu, 24 May 2012 21:37:08 +0000 (21:37 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 24 May 2012 21:37:08 +0000 (21:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157416 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/Target.td
test/TableGen/SetTheory.td
utils/TableGen/SetTheory.cpp

index 1f2bd470b7ea204879dc1e699a40148449570a17..e053ce8c6b507b032367970cdf765defeef7ef93 100644 (file)
@@ -191,7 +191,8 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
 // also in the second set.
 //
 // (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of
-// numbered registers.
+// numbered registers.  Takes an optional 4th operand which is a stride to use
+// when generating the sequence.
 //
 // (shl GPR, 4) - Remove the first N elements.
 //
index 4d85aa3e6f22538274eb93c38a3888f3f0bd7edd..761332312b0ff6b25fadd1cd905cfbd34ec68f24 100644 (file)
@@ -161,10 +161,12 @@ def S9a : Set<(sequence "e%u", 3, 7)>;
 def S9b : Set<(sequence "e%u", 7, 3)>;
 def S9c : Set<(sequence "e%u", 0, 0)>;
 def S9d : Set<(sequence "S%ua", 7, 9)>;
+def S9e : Set<(sequence "e%u", 3, 6, 2)>;
 // CHECK: S9a = [ e3 e4 e5 e6 e7 ]
 // CHECK: S9b = [ e7 e6 e5 e4 e3 ]
 // CHECK: S9c = [ e0 ]
 // CHECK: S9d = [ a b c d e0 e3 e6 e9 e4 e5 e7 ]
+// CHECK: S9e = [ e3 e5 ]
 
 // The 'interleave' operator is almost the inverse of 'decimate'.
 def interleave;
index 0649fd1cfaf95c91ba7c90c737dd332f3dfe7fce..46e6db173ea947cc0a454b46771701d0f45f4fee 100644 (file)
@@ -160,9 +160,17 @@ struct InterleaveOp : public SetTheory::Operator {
 // (sequence "Format", From, To) Generate a sequence of records by name.
 struct SequenceOp : public SetTheory::Operator {
   void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
-    if (Expr->arg_size() != 3)
+    int Step = 1;
+    if (Expr->arg_size() > 4)
       throw "Bad args to (sequence \"Format\", From, To): " +
         Expr->getAsString();
+    else if (Expr->arg_size() == 4) {
+      if (IntInit *II = dynamic_cast<IntInit*>(Expr->arg_begin()[3])) {
+        Step = II->getValue();
+      } else
+        throw "Stride must be an integer: " + Expr->getAsString();
+    }
+
     std::string Format;
     if (StringInit *SI = dynamic_cast<StringInit*>(Expr->arg_begin()[0]))
       Format = SI->getValue();
@@ -187,8 +195,12 @@ struct SequenceOp : public SetTheory::Operator {
     RecordKeeper &Records =
       dynamic_cast<DefInit&>(*Expr->getOperator()).getDef()->getRecords();
 
-    int Step = From <= To ? 1 : -1;
-    for (To += Step; From != To; From += Step) {
+    Step *= From <= To ? 1 : -1;
+    while (true) {
+      if (Step > 0 && From > To)
+        break;
+      else if (Step < 0 && From < To)
+        break;
       std::string Name;
       raw_string_ostream OS(Name);
       OS << format(Format.c_str(), unsigned(From));
@@ -200,6 +212,8 @@ struct SequenceOp : public SetTheory::Operator {
         Elts.insert(Result->begin(), Result->end());
       else
         Elts.insert(Rec);
+
+      From += Step;
     }
   }
 };