diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2012-09-06 14:15:52 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2012-09-06 14:15:52 +0000 |
commit | 6d3d7656539188b496089a3313ed4d13759adba3 (patch) | |
tree | 2167b65519599cb776e3b40c2236c607c476f522 | |
parent | 4178946afba97a9a432a33ab1596f49a1ac090e7 (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.td | 16 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 84 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.h | 4 | ||||
-rw-r--r-- | utils/TableGen/DAGISelMatcherGen.cpp | 3 | ||||
-rw-r--r-- | utils/TableGen/PseudoLoweringEmitter.cpp | 2 |
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) |