aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2012-09-06 14:15:52 +0000
committerTom Stellard <thomas.stellard@amd.com>2012-09-06 14:15:52 +0000
commit6d3d7656539188b496089a3313ed4d13759adba3 (patch)
tree2167b65519599cb776e3b40c2236c607c476f522
parent4178946afba97a9a432a33ab1596f49a1ac090e7 (diff)
Tablegen: Add OperandWithDefaultOps Operand type
This Operand type takes a default argument, and is initialized to this value if it does not appear in a patter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163315 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/Target.td16
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp84
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h4
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp3
-rw-r--r--utils/TableGen/PseudoLoweringEmitter.cpp2
5 files changed, 53 insertions, 56 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 52b491d434..87bd84ec84 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -602,23 +602,31 @@ def f64imm : Operand<f64>;
///
def zero_reg;
+/// OperandWithDefaultOps - This Operand class can be used as the parent class
+/// for an Operand that needs to be initialized with a default value if
+/// no value is supplied in a pattern. This class can be used to simplify the
+/// pattern definitions for instructions that have target specific flags
+/// encoded as immediate operands.
+class OperandWithDefaultOps<ValueType ty, dag defaultops>
+ : Operand<ty> {
+ dag DefaultOps = defaultops;
+}
+
/// PredicateOperand - This can be used to define a predicate operand for an
/// instruction. OpTypes specifies the MIOperandInfo for the operand, and
/// AlwaysVal specifies the value of this predicate when set to "always
/// execute".
class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal>
- : Operand<ty> {
+ : OperandWithDefaultOps<ty, AlwaysVal> {
let MIOperandInfo = OpTypes;
- dag DefaultOps = AlwaysVal;
}
/// OptionalDefOperand - This is used to define a optional definition operand
/// for an instruction. DefaultOps is the register the operand represents if
/// none is supplied, e.g. zero_reg.
class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops>
- : Operand<ty> {
+ : OperandWithDefaultOps<ty, defaultops> {
let MIOperandInfo = OpTypes;
- dag DefaultOps = defaultops;
}
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 49db093f6e..8713a56916 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1575,8 +1575,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// If the instruction expects a predicate or optional def operand, we
// codegen this by setting the operand to it's default value if it has a
// non-empty DefaultOps field.
- if ((OperandNode->isSubClassOf("PredicateOperand") ||
- OperandNode->isSubClassOf("OptionalDefOperand")) &&
+ if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
!CDP.getDefaultOperand(OperandNode).DefaultOps.empty())
continue;
@@ -2173,53 +2172,46 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
}
void CodeGenDAGPatterns::ParseDefaultOperands() {
- std::vector<Record*> DefaultOps[2];
- DefaultOps[0] = Records.getAllDerivedDefinitions("PredicateOperand");
- DefaultOps[1] = Records.getAllDerivedDefinitions("OptionalDefOperand");
+ std::vector<Record*> DefaultOps;
+ DefaultOps = Records.getAllDerivedDefinitions("OperandWithDefaultOps");
// Find some SDNode.
assert(!SDNodes.empty() && "No SDNodes parsed?");
Init *SomeSDNode = DefInit::get(SDNodes.begin()->first);
- for (unsigned iter = 0; iter != 2; ++iter) {
- for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) {
- DagInit *DefaultInfo = DefaultOps[iter][i]->getValueAsDag("DefaultOps");
-
- // Clone the DefaultInfo dag node, changing the operator from 'ops' to
- // SomeSDnode so that we can parse this.
- std::vector<std::pair<Init*, std::string> > Ops;
- for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
- Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
- DefaultInfo->getArgName(op)));
- DagInit *DI = DagInit::get(SomeSDNode, "", Ops);
-
- // Create a TreePattern to parse this.
- TreePattern P(DefaultOps[iter][i], DI, false, *this);
- assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
-
- // Copy the operands over into a DAGDefaultOperand.
- DAGDefaultOperand DefaultOpInfo;
-
- TreePatternNode *T = P.getTree(0);
- for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
- TreePatternNode *TPN = T->getChild(op);
- while (TPN->ApplyTypeConstraints(P, false))
- /* Resolve all types */;
-
- if (TPN->ContainsUnresolvedType()) {
- if (iter == 0)
- throw "Value #" + utostr(i) + " of PredicateOperand '" +
- DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
- else
- throw "Value #" + utostr(i) + " of OptionalDefOperand '" +
- DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
- }
- DefaultOpInfo.DefaultOps.push_back(TPN);
+ for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {
+ DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
+
+ // Clone the DefaultInfo dag node, changing the operator from 'ops' to
+ // SomeSDnode so that we can parse this.
+ std::vector<std::pair<Init*, std::string> > Ops;
+ for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
+ Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
+ DefaultInfo->getArgName(op)));
+ DagInit *DI = DagInit::get(SomeSDNode, "", Ops);
+
+ // Create a TreePattern to parse this.
+ TreePattern P(DefaultOps[i], DI, false, *this);
+ assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
+
+ // Copy the operands over into a DAGDefaultOperand.
+ DAGDefaultOperand DefaultOpInfo;
+
+ TreePatternNode *T = P.getTree(0);
+ for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
+ TreePatternNode *TPN = T->getChild(op);
+ while (TPN->ApplyTypeConstraints(P, false))
+ /* Resolve all types */;
+
+ if (TPN->ContainsUnresolvedType()) {
+ throw "Value #" + utostr(i) + " of OperandWithDefaultOps '" +
+ DefaultOps[i]->getName() +"' doesn't have a concrete type!";
}
-
- // Insert it into the DefaultOperands map so we can find it later.
- DefaultOperands[DefaultOps[iter][i]] = DefaultOpInfo;
+ DefaultOpInfo.DefaultOps.push_back(TPN);
}
+
+ // Insert it into the DefaultOperands map so we can find it later.
+ DefaultOperands[DefaultOps[i]] = DefaultOpInfo;
}
}
@@ -2687,11 +2679,9 @@ void CodeGenDAGPatterns::ParseInstructions() {
I->error("Operand #" + utostr(i) + " in operands list has no name!");
if (!InstInputsCheck.count(OpName)) {
- // If this is an predicate operand or optional def operand with an
- // DefaultOps set filled in, we can ignore this. When we codegen it,
- // we will do so as always executed.
- if (Op.Rec->isSubClassOf("PredicateOperand") ||
- Op.Rec->isSubClassOf("OptionalDefOperand")) {
+ // If this is an operand with a DefaultOps set filled in, we can ignore
+ // this. When we codegen it, we will do so as always executed.
+ if (Op.Rec->isSubClassOf("OperandWithDefaultOps")) {
// Does it have a non-empty DefaultOps field? If so, ignore this
// operand.
if (!getDefaultOperand(Op.Rec).DefaultOps.empty())
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index 09b2a5ba7f..25a0e4bb10 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -582,8 +582,8 @@ private:
void ComputeNamedNodes(TreePatternNode *N);
};
-/// DAGDefaultOperand - One of these is created for each PredicateOperand
-/// or OptionalDefOperand that has a set ExecuteAlways / DefaultOps field.
+/// DAGDefaultOperand - One of these is created for each OperandWithDefaultOps
+/// that has a set ExecuteAlways / DefaultOps field.
struct DAGDefaultOperand {
std::vector<TreePatternNode*> DefaultOps;
};
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index aed222c094..b291269933 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -727,8 +727,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
// Determine what to emit for this operand.
Record *OperandNode = II.Operands[InstOpNo].Rec;
- if ((OperandNode->isSubClassOf("PredicateOperand") ||
- OperandNode->isSubClassOf("OptionalDefOperand")) &&
+ if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
!CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
// This is a predicate or optional def operand; emit the
// 'default ops' operands.
diff --git a/utils/TableGen/PseudoLoweringEmitter.cpp b/utils/TableGen/PseudoLoweringEmitter.cpp
index 8d9d419544..8e28180ae8 100644
--- a/utils/TableGen/PseudoLoweringEmitter.cpp
+++ b/utils/TableGen/PseudoLoweringEmitter.cpp
@@ -156,7 +156,7 @@ void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) {
// If there are more operands that weren't in the DAG, they have to
// be operands that have default values, or we have an error. Currently,
- // PredicateOperand and OptionalDefOperand both have default values.
+ // Operands that are a sublass of OperandWithDefaultOp have default values.
// Validate that each result pattern argument has a matching (by name)