summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-11-04 05:12:02 +0000
committerChris Lattner <sabre@nondot.org>2006-11-04 05:12:02 +0000
commitefe9f4a3b69eb2a31f006476996c8ef722345193 (patch)
tree7db59775b2f7f0477e72914488efaec8f76cb5e3 /utils
parentdfdaeb276e50baea18abbe30a85f1c206bb3d154 (diff)
downloadllvm-efe9f4a3b69eb2a31f006476996c8ef722345193.tar.gz
llvm-efe9f4a3b69eb2a31f006476996c8ef722345193.tar.bz2
llvm-efe9f4a3b69eb2a31f006476996c8ef722345193.tar.xz
Parse PredicateOperand's. When an instruction takes one, have the generated
isel fill in the instruction operands with the 'execute always' value automatically. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31448 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp80
-rw-r--r--utils/TableGen/DAGISelEmitter.h12
2 files changed, 86 insertions, 6 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 3d79ea09b3..0701ffbd7d 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1230,6 +1230,50 @@ void DAGISelEmitter::ParsePatternFragments(std::ostream &OS) {
}
}
+void DAGISelEmitter::ParsePredicateOperands() {
+ std::vector<Record*> PredOps =
+ Records.getAllDerivedDefinitions("PredicateOperand");
+
+ // Find some SDNode.
+ assert(!SDNodes.empty() && "No SDNodes parsed?");
+ Init *SomeSDNode = new DefInit(SDNodes.begin()->first);
+
+ for (unsigned i = 0, e = PredOps.size(); i != e; ++i) {
+ DagInit *AlwaysInfo = PredOps[i]->getValueAsDag("ExecuteAlways");
+
+ // Clone the AlwaysInfo 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 = AlwaysInfo->getNumArgs(); op != e; ++op)
+ Ops.push_back(std::make_pair(AlwaysInfo->getArg(op),
+ AlwaysInfo->getArgName(op)));
+ DagInit *DI = new DagInit(SomeSDNode, Ops);
+
+ // Create a TreePattern to parse this.
+ TreePattern P(PredOps[i], DI, false, *this);
+ assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
+
+ // Copy the operands over into a DAGPredicateOperand.
+ DAGPredicateOperand PredOpInfo;
+
+ 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 PredicateOperand '" +
+ PredOps[i]->getName() + "' doesn't have a concrete type!";
+
+ PredOpInfo.AlwaysOps.push_back(TPN);
+ }
+
+ // Insert it into the PredicateOperands map so we can find it later.
+ PredicateOperands[PredOps[i]] = PredOpInfo;
+ }
+}
+
/// HandleUse - Given "Pat" a leaf in the pattern, check to see if it is an
/// instruction input. Return true if this is a real use.
static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
@@ -1496,7 +1540,7 @@ void DAGISelEmitter::ParseInstructions() {
if (Op.Rec->isSubClassOf("PredicateOperand")) {
// Does it have a non-empty ExecuteAlways field? If so, ignore this
// operand.
- if (Op.Rec->getValueAsDag("ExecuteAlways")->getNumArgs())
+ if (!getPredicateOperand(Op.Rec).AlwaysOps.empty())
continue;
}
I->error("Operand $" + OpName +
@@ -2690,6 +2734,7 @@ public:
PatternHasProperty(InstPatNode, SDNPHasChain, ISE);
bool InputHasChain = isRoot &&
NodeHasProperty(Pattern, SDNPHasChain, ISE);
+ unsigned NumResults = Inst.getNumResults();
if (NodeHasOptInFlag) {
emitCode("bool HasInFlag = "
@@ -2726,11 +2771,34 @@ public:
"&InChains[0], InChains.size());");
}
+ // Loop over all of the operands of the instruction pattern, emitting code
+ // to fill them all in. The node 'N' usually has number children equal to
+ // the number of input operands of the instruction. However, in cases
+ // where there are predicate operands for an instruction, we need to fill
+ // in the 'execute always' values. Match up the node operands to the
+ // instruction operands to do this.
std::vector<std::string> AllOps;
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- std::vector<std::string> Ops = EmitResultCode(N->getChild(i),
- RetSelected, InFlagDecled, ResNodeDecled);
- AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+ for (unsigned ChildNo = 0, InstOpNo = NumResults;
+ InstOpNo != II.OperandList.size(); ++InstOpNo) {
+ std::vector<std::string> Ops;
+
+ // If this is a normal operand, emit it.
+ if (!II.OperandList[InstOpNo].Rec->isSubClassOf("PredicateOperand")) {
+ Ops = EmitResultCode(N->getChild(ChildNo), RetSelected,
+ InFlagDecled, ResNodeDecled);
+ AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+ ++ChildNo;
+ } else {
+ // Otherwise, this is a predicate operand, emit the 'execute always'
+ // operands.
+ const DAGPredicateOperand &Pred =
+ ISE.getPredicateOperand(II.OperandList[InstOpNo].Rec);
+ for (unsigned i = 0, e = Pred.AlwaysOps.size(); i != e; ++i) {
+ Ops = EmitResultCode(Pred.AlwaysOps[i], RetSelected,
+ InFlagDecled, ResNodeDecled);
+ AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
+ }
+ }
}
// Emit all the chain and CopyToReg stuff.
@@ -2753,7 +2821,6 @@ public:
}
}
- unsigned NumResults = Inst.getNumResults();
unsigned ResNo = TmpNo++;
if (!isRoot || InputHasChain || NodeHasChain || NodeHasOutFlag ||
NodeHasOptInFlag) {
@@ -3820,6 +3887,7 @@ OS << " unsigned NumKilled = ISelKilled.size();\n";
ParseNodeTransforms(OS);
ParseComplexPatterns();
ParsePatternFragments(OS);
+ ParsePredicateOperands();
ParseInstructions();
ParsePatterns();
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index e50303672c..a832b7dfe0 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -343,6 +343,11 @@ namespace llvm {
TreePatternNode *ParseTreePattern(DagInit *DI);
};
+ /// DAGPredicateOperand - One of these is created for each PredicateOperand
+ /// that has a set ExecuteAlways field.
+ struct DAGPredicateOperand {
+ std::vector<TreePatternNode*> AlwaysOps;
+ };
class DAGInstruction {
TreePattern *Pattern;
@@ -425,6 +430,7 @@ private:
std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
std::map<Record*, ComplexPattern> ComplexPatterns;
std::map<Record*, TreePattern*> PatternFragments;
+ std::map<Record*, DAGPredicateOperand> PredicateOperands;
std::map<Record*, DAGInstruction> Instructions;
// Specific SDNode definitions:
@@ -479,6 +485,11 @@ public:
abort();
}
+ const DAGPredicateOperand &getPredicateOperand(Record *R) {
+ assert(PredicateOperands.count(R) &&"Isn't an analyzed predicate operand!");
+ return PredicateOperands.find(R)->second;
+ }
+
TreePattern *getPatternFragment(Record *R) const {
assert(PatternFragments.count(R) && "Invalid pattern fragment request!");
return PatternFragments.find(R)->second;
@@ -505,6 +516,7 @@ private:
void ParseNodeTransforms(std::ostream &OS);
void ParseComplexPatterns();
void ParsePatternFragments(std::ostream &OS);
+ void ParsePredicateOperands();
void ParseInstructions();
void ParsePatterns();
void GenerateVariants();