diff options
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 59 | ||||
-rw-r--r-- | utils/TableGen/DAGISelMatcherGen.cpp | 25 |
2 files changed, 44 insertions, 40 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 031e75eca8..ba9a98d8dd 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -775,10 +775,9 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { if (Operator->isSubClassOf("Instruction")) { CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator); - - // FIXME: Handle implicit defs right. - if (InstInfo.NumDefs != 0) - return 1; // FIXME: Handle inst results right! + + // FIXME: Should allow access to all the results here. + unsigned NumDefsToAdd = InstInfo.NumDefs ? 1 : 0; if (!InstInfo.ImplicitDefs.empty()) { // Add on one implicit def if it has a resolvable type. @@ -787,9 +786,9 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { const std::vector<MVT::SimpleValueType> &RegVTs = CDP.getTargetInfo().getRegisterVTs(FirstImplicitDef); if (RegVTs.size() == 1) - return 1; + return NumDefsToAdd+1; } - return 0; + return NumDefsToAdd; } if (Operator->isSubClassOf("SDNodeXForm")) @@ -1250,21 +1249,20 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { if (getOperator()->isSubClassOf("Instruction")) { const DAGInstruction &Inst = CDP.getInstruction(getOperator()); - unsigned ResNo = 0; - assert(Inst.getNumResults() <= 1 && - "FIXME: Only supports zero or one result instrs!"); - CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(getOperator()); - EEVT::TypeSet ResultType; - - // Apply the result type to the node - if (InstInfo.NumDefs != 0) { // # of elements in (outs) list - Record *ResultNode = Inst.getResult(0); + bool MadeChange = false; + + // Apply the result types to the node, these come from the things in the + // (outs) list of the instruction. + // FIXME: Cap at one result so far. + unsigned NumResultsToAdd = InstInfo.NumDefs ? 1 : 0; + for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) { + Record *ResultNode = Inst.getResult(ResNo); if (ResultNode->isSubClassOf("PointerLikeRegClass")) { - ResultType = EEVT::TypeSet(MVT::iPTR, TP); + MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP); } else if (ResultNode->getName() == "unknown") { // Nothing to do. } else { @@ -1272,26 +1270,23 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { "Operands should be register classes!"); const CodeGenRegisterClass &RC = CDP.getTargetInfo().getRegisterClass(ResultNode); - ResultType = RC.getValueTypes(); + MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP); } - } else if (!InstInfo.ImplicitDefs.empty()) { - // If the instruction has implicit defs, the first one defines the result - // type. + } + + // If the instruction has implicit defs, we apply the first one as a result. + // FIXME: This sucks, it should apply all implicit defs. + if (!InstInfo.ImplicitDefs.empty()) { + unsigned ResNo = NumResultsToAdd; + Record *FirstImplicitDef = InstInfo.ImplicitDefs[0]; assert(FirstImplicitDef->isSubClassOf("Register")); const std::vector<MVT::SimpleValueType> &RegVTs = CDP.getTargetInfo().getRegisterVTs(FirstImplicitDef); if (RegVTs.size() == 1) // FIXME: Generalize. - ResultType = EEVT::TypeSet(RegVTs); - } else { - // Otherwise, the instruction produces no value result. + MadeChange |= UpdateNodeType(ResNo, EEVT::TypeSet(RegVTs), TP); } - bool MadeChange = false; - - if (!ResultType.isCompletelyUnknown()) - MadeChange |= UpdateNodeType(ResNo, ResultType, TP); - // If this is an INSERT_SUBREG, constrain the source and destination VTs to // be the same. if (getOperator()->getName() == "INSERT_SUBREG") { @@ -1319,17 +1314,17 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { MVT::SimpleValueType VT; TreePatternNode *Child = getChild(ChildNo++); - assert(Child->getNumTypes() == 1 && "Unknown case?"); + unsigned ChildResNo = 0; // Instructions always use res #0 of their op. if (OperandNode->isSubClassOf("RegisterClass")) { const CodeGenRegisterClass &RC = CDP.getTargetInfo().getRegisterClass(OperandNode); - MadeChange |= Child->UpdateNodeType(0, RC.getValueTypes(), TP); + MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP); } else if (OperandNode->isSubClassOf("Operand")) { VT = getValueType(OperandNode->getValueAsDef("Type")); - MadeChange |= Child->UpdateNodeType(0, VT, TP); + MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP); } else if (OperandNode->isSubClassOf("PointerLikeRegClass")) { - MadeChange |= Child->UpdateNodeType(0, MVT::iPTR, TP); + MadeChange |= Child->UpdateNodeType(ChildResNo, MVT::iPTR, TP); } else if (OperandNode->getName() == "unknown") { // Nothing to do. } else { diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index fda1d457b9..f7fd493cd3 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -687,9 +687,19 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, continue; } + const TreePatternNode *Child = N->getChild(ChildNo); + // Otherwise this is a normal operand or a predicate operand without // 'execute always'; emit it. - EmitResultOperand(N->getChild(ChildNo), InstOps); + unsigned BeforeAddingNumOps = InstOps.size(); + EmitResultOperand(Child, InstOps); + assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands"); + + // If the operand is an instruction and it produced multiple results, just + // take the first one. + if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction")) + InstOps.resize(BeforeAddingNumOps+1); + ++ChildNo; } @@ -711,12 +721,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, // Determine the result types. SmallVector<MVT::SimpleValueType, 4> ResultVTs; - if (N->getNumTypes()) { - // FIXME2: If the node has multiple results, we should add them. For now, - // preserve existing behavior?! - assert(N->getNumTypes() == 1); - ResultVTs.push_back(N->getType(0)); - } + for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) + ResultVTs.push_back(N->getType(i)); // If this is the root instruction of a pattern that has physical registers in // its result pattern, add output VTs for them. For example, X86 has: @@ -727,7 +733,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, // If the root came from an implicit def in the instruction handling stuff, // don't re-add it. Record *HandledReg = 0; - if (NumResults == 0 && N->getNumTypes() != 0 && + if (N->getNumTypes() != 0 && !II.ImplicitDefs.empty()) HandledReg = II.ImplicitDefs[0]; @@ -762,6 +768,9 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, bool NodeHasMemRefs = isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP); + assert((!ResultVTs.empty() || TreeHasOutFlag || NodeHasChain) && + "Node has no result"); + AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(), ResultVTs.data(), ResultVTs.size(), InstOps.data(), InstOps.size(), |