diff options
author | Shih-wei Liao <sliao@google.com> | 2010-04-28 01:47:00 -0700 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2010-04-28 01:47:00 -0700 |
commit | 7abe37e4aee38cc79d91dd069a37d7e91d5bef53 (patch) | |
tree | c13b26fc3d8909240f981988535c0b82dd9bf37c /utils/TableGen/DAGISelMatcherGen.cpp | |
parent | 6037a7c3c97b651dd70e48ebe5453134713971ed (diff) | |
download | external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.zip external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.gz external_llvm-7abe37e4aee38cc79d91dd069a37d7e91d5bef53.tar.bz2 |
Sync upstream to r102410.
Re-turn on sdk.
Change-Id: I91a890863989a67243b4d2dfd1ae09b843ebaeaf
Diffstat (limited to 'utils/TableGen/DAGISelMatcherGen.cpp')
-rw-r--r-- | utils/TableGen/DAGISelMatcherGen.cpp | 124 |
1 files changed, 73 insertions, 51 deletions
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 4951a42..9d469a9 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -408,11 +408,13 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N, // If N and NodeNoTypes don't agree on a type, then this is a case where we // need to do a type check. Emit the check, apply the tyep to NodeNoTypes and // reinfer any correlated types. - unsigned NodeType = EEVT::isUnknown; - if (NodeNoTypes->getExtTypes() != N->getExtTypes()) { - NodeType = N->getTypeNum(0); - NodeNoTypes->setTypes(N->getExtTypes()); + SmallVector<unsigned, 2> ResultsToTypeCheck; + + for (unsigned i = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) { + if (NodeNoTypes->getExtType(i) == N->getExtType(i)) continue; + NodeNoTypes->setType(i, N->getExtType(i)); InferPossibleTypes(); + ResultsToTypeCheck.push_back(i); } // If this node has a name associated with it, capture it in VariableMap. If @@ -442,8 +444,9 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N, for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i) AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i])); - if (NodeType != EEVT::isUnknown) - AddMatcher(new CheckTypeMatcher((MVT::SimpleValueType)NodeType)); + for (unsigned i = 0, e = ResultsToTypeCheck.size(); i != e; ++i) + AddMatcher(new CheckTypeMatcher(N->getType(ResultsToTypeCheck[i]), + ResultsToTypeCheck[i])); } /// EmitMatcherCode - Generate the code that matches the predicate of this @@ -567,7 +570,7 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N, assert(N->isLeaf() && "Must be a leaf"); if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) { - AddMatcher(new EmitIntegerMatcher(II->getValue(),N->getTypeNum(0))); + AddMatcher(new EmitIntegerMatcher(II->getValue(), N->getType(0))); ResultOps.push_back(NextRecordedOperandNo++); return; } @@ -575,14 +578,13 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N, // If this is an explicit register reference, handle it. if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) { if (DI->getDef()->isSubClassOf("Register")) { - AddMatcher(new EmitRegisterMatcher(DI->getDef(), - N->getTypeNum(0))); + AddMatcher(new EmitRegisterMatcher(DI->getDef(), N->getType(0))); ResultOps.push_back(NextRecordedOperandNo++); return; } if (DI->getDef()->getName() == "zero_reg") { - AddMatcher(new EmitRegisterMatcher(0, N->getTypeNum(0))); + AddMatcher(new EmitRegisterMatcher(0, N->getType(0))); ResultOps.push_back(NextRecordedOperandNo++); return; } @@ -628,7 +630,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, SmallVectorImpl<unsigned> &OutputOps) { Record *Op = N->getOperator(); const CodeGenTarget &CGT = CGP.getTargetInfo(); - CodeGenInstruction &II = CGT.getInstruction(Op->getName()); + CodeGenInstruction &II = CGT.getInstruction(Op); const DAGInstruction &Inst = CGP.getInstruction(Op); // If we can, get the pattern for the instruction we're generating. We derive @@ -685,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; } @@ -699,7 +711,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, // occur in patterns like (mul:i8 AL:i8, GR8:i8:$src). for (unsigned i = 0, e = PhysRegInputs.size(); i != e; ++i) AddMatcher(new EmitCopyToRegMatcher(PhysRegInputs[i].second, - PhysRegInputs[i].first)); + PhysRegInputs[i].first)); // Even if the node has no other flag inputs, the resultant node must be // flagged to the CopyFromReg nodes we just generated. TreeHasInFlag = true; @@ -709,29 +721,34 @@ EmitResultInstructionAsOperand(const TreePatternNode *N, // Determine the result types. SmallVector<MVT::SimpleValueType, 4> ResultVTs; - if (NumResults != 0 && N->getTypeNum(0) != MVT::isVoid) { - // FIXME2: If the node has multiple results, we should add them. For now, - // preserve existing behavior?! - ResultVTs.push_back(N->getTypeNum(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: // (set AL, (mul ...)) // This also handles implicit results like: // (implicit EFLAGS) - if (isRoot && Pattern.getDstRegs().size() != 0) { - for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) - if (Pattern.getDstRegs()[i]->isSubClassOf("Register")) - ResultVTs.push_back(getRegisterValueType(Pattern.getDstRegs()[i], CGT)); + if (isRoot && !Pattern.getDstRegs().empty()) { + // If the root came from an implicit def in the instruction handling stuff, + // don't re-add it. + Record *HandledReg = 0; + if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other) + HandledReg = II.ImplicitDefs[0]; + + for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) { + Record *Reg = Pattern.getDstRegs()[i]; + if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue; + ResultVTs.push_back(getRegisterValueType(Reg, CGT)); + } } - // FIXME2: Instead of using the isVariadic flag on the instruction, we should - // have an SDNP that indicates variadicism. The TargetInstrInfo isVariadic - // property should be inferred from this when an instruction has a pattern. + // If this is the root of the pattern and the pattern we're matching includes + // a node that is variadic, mark the generated node as variadic so that it + // gets the excess operands from the input DAG. int NumFixedArityOperands = -1; - if (isRoot && II.isVariadic) + if (isRoot && + (Pattern.getSrcPattern()->NodeHasProperty(SDNPVariadic, CGP))) NumFixedArityOperands = Pattern.getSrcPattern()->getNumChildren(); // If this is the root node and any of the nodes matched nodes in the input @@ -750,6 +767,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(), @@ -817,33 +837,35 @@ void MatcherGen::EmitResultCode() { // At this point, we have however many values the result pattern produces. // However, the input pattern might not need all of these. If there are - // excess values at the end (such as condition codes etc) just lop them off. - // This doesn't need to worry about flags or chains, just explicit results. - // - // FIXME2: This doesn't work because there is currently no way to get an - // accurate count of the # results the source pattern sets. This is because - // of the "parallel" construct in X86 land, which looks like this: - // - //def : Pat<(parallel (X86and_flag GR8:$src1, GR8:$src2), - // (implicit EFLAGS)), - // (AND8rr GR8:$src1, GR8:$src2)>; - // - // This idiom means to match the two-result node X86and_flag (which is - // declared as returning a single result, because we can't match multi-result - // nodes yet). In this case, we would have to know that the input has two - // results. However, mul8r is modelled exactly the same way, but without - // implicit defs included. The fix is to support multiple results directly - // and eliminate 'parallel'. + // excess values at the end (such as implicit defs of condition codes etc) + // just lop them off. This doesn't need to worry about flags or chains, just + // explicit results. // - // FIXME2: When this is fixed, we should revert the terrible hack in the - // OPC_EmitNode code in the interpreter. -#if 0 - const TreePatternNode *Src = Pattern.getSrcPattern(); - unsigned NumSrcResults = Src->getTypeNum(0) != MVT::isVoid ? 1 : 0; - NumSrcResults += Pattern.getDstRegs().size(); + unsigned NumSrcResults = Pattern.getSrcPattern()->getNumTypes(); + + // If the pattern also has (implicit) results, count them as well. + if (!Pattern.getDstRegs().empty()) { + // If the root came from an implicit def in the instruction handling stuff, + // don't re-add it. + Record *HandledReg = 0; + const TreePatternNode *DstPat = Pattern.getDstPattern(); + if (!DstPat->isLeaf() &&DstPat->getOperator()->isSubClassOf("Instruction")){ + const CodeGenTarget &CGT = CGP.getTargetInfo(); + CodeGenInstruction &II = CGT.getInstruction(DstPat->getOperator()); + + if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other) + HandledReg = II.ImplicitDefs[0]; + } + + for (unsigned i = 0; i != Pattern.getDstRegs().size(); ++i) { + Record *Reg = Pattern.getDstRegs()[i]; + if (!Reg->isSubClassOf("Register") || Reg == HandledReg) continue; + ++NumSrcResults; + } + } + assert(Ops.size() >= NumSrcResults && "Didn't provide enough results"); Ops.resize(NumSrcResults); -#endif // If the matched pattern covers nodes which define a flag result, emit a node // that tells the matcher about them so that it can update their results. |