summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-24 18:06:05 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-24 18:06:05 +0000
commit5b52f6d655e34de5c6fedbb71b6c94775cc10032 (patch)
tree147d3d1569f63029f88d6f987730ba84081f31f3
parent9136f2112ca67bf360ee64b6546abea9dce0579c (diff)
downloadllvm-5b52f6d655e34de5c6fedbb71b6c94775cc10032.tar.gz
llvm-5b52f6d655e34de5c6fedbb71b6c94775cc10032.tar.bz2
llvm-5b52f6d655e34de5c6fedbb71b6c94775cc10032.tar.xz
Add an (interleave A, B, ...) SetTheory operator.
This will interleave the elements from two or more lists. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148824 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/Target.td3
-rw-r--r--test/TableGen/SetTheory.td7
-rw-r--r--utils/TableGen/SetTheory.cpp19
3 files changed, 29 insertions, 0 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index f9f30a8bb7..84e6b1bfef 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -200,12 +200,15 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
//
// (decimate GPR, 2) - Pick every N'th element, starting with the first.
//
+// (interleave A, B, ...) - Interleave the elements from each argument list.
+//
// All of these operators work on ordered sets, not lists. That means
// duplicates are removed from sub-expressions.
// Set operators. The rest is defined in TargetSelectionDAG.td.
def sequence;
def decimate;
+def interleave;
// RegisterTuples - Automatically generate super-registers by forming tuples of
// sub-registers. This is useful for modeling register sequence constraints
diff --git a/test/TableGen/SetTheory.td b/test/TableGen/SetTheory.td
index a4acea907d..4d85aa3e6f 100644
--- a/test/TableGen/SetTheory.td
+++ b/test/TableGen/SetTheory.td
@@ -165,3 +165,10 @@ def S9d : Set<(sequence "S%ua", 7, 9)>;
// CHECK: S9b = [ e7 e6 e5 e4 e3 ]
// CHECK: S9c = [ e0 ]
// CHECK: S9d = [ a b c d e0 e3 e6 e9 e4 e5 e7 ]
+
+// The 'interleave' operator is almost the inverse of 'decimate'.
+def interleave;
+def T0a : Set<(interleave S9a, S9b)>;
+def T0b : Set<(interleave S8e, S8d)>;
+// CHECK: T0a = [ e3 e7 e4 e6 e5 ]
+// CHECK: T0b = [ e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ]
diff --git a/utils/TableGen/SetTheory.cpp b/utils/TableGen/SetTheory.cpp
index 838b9246aa..0649fd1cfa 100644
--- a/utils/TableGen/SetTheory.cpp
+++ b/utils/TableGen/SetTheory.cpp
@@ -139,6 +139,24 @@ struct DecimateOp : public SetIntBinOp {
}
};
+// (interleave S1, S2, ...) Interleave elements of the arguments.
+struct InterleaveOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
+ // Evaluate the arguments individually.
+ SmallVector<RecSet, 4> Args(Expr->getNumArgs());
+ unsigned MaxSize = 0;
+ for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i) {
+ ST.evaluate(Expr->getArg(i), Args[i]);
+ MaxSize = std::max(MaxSize, unsigned(Args[i].size()));
+ }
+ // Interleave arguments into Elts.
+ for (unsigned n = 0; n != MaxSize; ++n)
+ for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i)
+ if (n < Args[i].size())
+ Elts.insert(Args[i][n]);
+ }
+};
+
// (sequence "Format", From, To) Generate a sequence of records by name.
struct SequenceOp : public SetTheory::Operator {
void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
@@ -211,6 +229,7 @@ SetTheory::SetTheory() {
addOperator("rotl", new RotOp(false));
addOperator("rotr", new RotOp(true));
addOperator("decimate", new DecimateOp);
+ addOperator("interleave", new InterleaveOp);
addOperator("sequence", new SequenceOp);
}