Changes in directory llvm/utils/TableGen:
DAGISelEmitter.cpp updated: 1.278 -> 1.279 DAGISelEmitter.h updated: 1.70 -> 1.71 --- Log message: Parse PredicateOperand's. When an instruction takes one, have the generated isel fill in the instruction operands with the 'execute always' value automatically. --- Diffs of the changes: (+86 -6) DAGISelEmitter.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++---- DAGISelEmitter.h | 12 +++++++ 2 files changed, 86 insertions(+), 6 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.278 llvm/utils/TableGen/DAGISelEmitter.cpp:1.279 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.278 Fri Nov 3 19:35:50 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Nov 3 23:12:02 2006 @@ -1230,6 +1230,50 @@ } } +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 @@ 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 @@ PatternHasProperty(InstPatNode, SDNPHasChain, ISE); bool InputHasChain = isRoot && NodeHasProperty(Pattern, SDNPHasChain, ISE); + unsigned NumResults = Inst.getNumResults(); if (NodeHasOptInFlag) { emitCode("bool HasInFlag = " @@ -2726,11 +2771,34 @@ "&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 @@ } } - unsigned NumResults = Inst.getNumResults(); unsigned ResNo = TmpNo++; if (!isRoot || InputHasChain || NodeHasChain || NodeHasOutFlag || NodeHasOptInFlag) { @@ -3820,6 +3887,7 @@ ParseNodeTransforms(OS); ParseComplexPatterns(); ParsePatternFragments(OS); + ParsePredicateOperands(); ParseInstructions(); ParsePatterns(); Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.70 llvm/utils/TableGen/DAGISelEmitter.h:1.71 --- llvm/utils/TableGen/DAGISelEmitter.h:1.70 Wed Oct 11 16:02:01 2006 +++ llvm/utils/TableGen/DAGISelEmitter.h Fri Nov 3 23:12:02 2006 @@ -343,6 +343,11 @@ 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 @@ 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 @@ 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 @@ void ParseNodeTransforms(std::ostream &OS); void ParseComplexPatterns(); void ParsePatternFragments(std::ostream &OS); + void ParsePredicateOperands(); void ParseInstructions(); void ParsePatterns(); void GenerateVariants(); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits