From efe9f4a3b69eb2a31f006476996c8ef722345193 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 4 Nov 2006 05:12:02 +0000 Subject: [PATCH] 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 --- utils/TableGen/DAGISelEmitter.cpp | 80 ++++++++++++++++++++++++++++--- utils/TableGen/DAGISelEmitter.h | 12 +++++ 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 3d79ea09b3e..0701ffbd7d1 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 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 > 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 AllOps; - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { - std::vector 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 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 e50303672c2..a832b7dfe01 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 AlwaysOps; + }; class DAGInstruction { TreePattern *Pattern; @@ -425,6 +430,7 @@ private: std::map > SDNodeXForms; std::map ComplexPatterns; std::map PatternFragments; + std::map PredicateOperands; std::map 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();