diff options
author | Chris Lattner <sabre@nondot.org> | 2010-02-13 20:06:50 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-02-13 20:06:50 +0000 |
commit | a0cdf17f3708cb4ef4c90c9e759794a7efe628b0 (patch) | |
tree | e552fd74b98b5af0111afda11cb1e67c0eab434a | |
parent | 1cea10a66339a412ce02db3d2c4d57a4681571c0 (diff) |
pull a bunch of huge inline methods in the PatternCodeEmitter
class out of line.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96113 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | utils/TableGen/DAGISelEmitter.cpp | 1756 |
1 files changed, 890 insertions, 866 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index c97582b30b..6281b89a93 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -463,760 +463,881 @@ public: /// matches, and the SDNode for the result has the RootName specified name. void EmitMatchCode(TreePatternNode *N, TreePatternNode *P, const std::string &RootName, const std::string &ChainSuffix, - bool &FoundChain) { + bool &FoundChain); - // Save loads/stores matched by a pattern. - if (!N->isLeaf() && N->getName().empty()) { - if (NodeHasProperty(N, SDNPMemOperand, CGP)) - LSI.push_back(getNodeName(RootName)); - } - - bool isRoot = (P == NULL); - // Emit instruction predicates. Each predicate is just a string for now. - if (isRoot) { - // Record input varargs info. - NumInputRootOps = N->getNumChildren(); - - if (DisablePatternForFastISel(N, CGP)) - emitCheck("OptLevel != CodeGenOpt::None"); + void EmitChildMatchCode(TreePatternNode *Child, TreePatternNode *Parent, + const std::string &RootName, + const std::string &ChainSuffix, bool &FoundChain); - emitCheck(PredicateCheck); - } + /// EmitResultCode - Emit the action for a pattern. Now that it has matched + /// we actually have to build a DAG! + std::vector<std::string> + EmitResultCode(TreePatternNode *N, std::vector<Record*> DstRegs, + bool InFlagDecled, bool ResNodeDecled, + bool LikeLeaf = false, bool isRoot = false); - if (N->isLeaf()) { - if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) { - emitCheck("cast<ConstantSDNode>(" + getNodeName(RootName) + - ")->getSExtValue() == INT64_C(" + - itostr(II->getValue()) + ")"); - return; - } else if (!NodeIsComplexPattern(N)) { - assert(0 && "Cannot match this as a leaf value!"); - abort(); - } + /// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat' + /// and add it to the tree. 'Pat' and 'Other' are isomorphic trees except that + /// 'Pat' may be missing types. If we find an unresolved type to add a check + /// for, this returns true otherwise false if Pat has all types. + bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other, + const std::string &Prefix, bool isRoot = false) { + // Did we find one? + if (Pat->getExtTypes() != Other->getExtTypes()) { + // Move a type over from 'other' to 'pat'. + Pat->setTypes(Other->getExtTypes()); + // The top level node type is checked outside of the select function. + if (!isRoot) + emitCheck(Prefix + ".getValueType() == " + + getName(Pat->getTypeNum(0))); + return true; } - // If this node has a name associated with it, capture it in VariableMap. If - // we already saw this in the pattern, emit code to verify dagness. - if (!N->getName().empty()) { - std::string &VarMapEntry = VariableMap[N->getName()]; - if (VarMapEntry.empty()) { - VarMapEntry = RootName; - } else { - // If we get here, this is a second reference to a specific name. Since - // we already have checked that the first reference is valid, we don't - // have to recursively match it, just check that it's the same as the - // previously named thing. - emitCheck(VarMapEntry + " == " + RootName); - return; - } - - if (!N->isLeaf()) - OperatorMap[N->getName()] = N->getOperator(); - } - + unsigned OpNo = + (unsigned) NodeHasProperty(Pat, SDNPHasChain, CGP); + for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo) + if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i), + Prefix + utostr(OpNo))) + return true; + return false; + } - // Emit code to load the child nodes and match their contents recursively. - unsigned OpNo = 0; - bool NodeHasChain = NodeHasProperty (N, SDNPHasChain, CGP); - bool HasChain = PatternHasProperty(N, SDNPHasChain, CGP); - bool EmittedUseCheck = false; - if (HasChain) { - if (NodeHasChain) - OpNo = 1; - if (!isRoot) { - // Multiple uses of actual result? - emitCheck(getValueName(RootName) + ".hasOneUse()"); - EmittedUseCheck = true; - if (NodeHasChain) { - // If the immediate use can somehow reach this node through another - // path, then can't fold it either or it will create a cycle. - // e.g. In the following diagram, XX can reach ld through YY. If - // ld is folded into XX, then YY is both a predecessor and a successor - // of XX. - // - // [ld] - // ^ ^ - // | | - // / \--- - // / [YY] - // | ^ - // [XX]-------| - bool NeedCheck = P != Pattern; - if (!NeedCheck) { - const SDNodeInfo &PInfo = CGP.getSDNodeInfo(P->getOperator()); - NeedCheck = - P->getOperator() == CGP.get_intrinsic_void_sdnode() || - P->getOperator() == CGP.get_intrinsic_w_chain_sdnode() || - P->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() || - PInfo.getNumOperands() > 1 || - PInfo.hasProperty(SDNPHasChain) || - PInfo.hasProperty(SDNPInFlag) || - PInfo.hasProperty(SDNPOptInFlag); +private: + /// EmitInFlagSelectCode - Emit the flag operands for the DAG that is + /// being built. + void EmitInFlagSelectCode(TreePatternNode *N, const std::string &RootName, + bool &ChainEmitted, bool &InFlagDecled, + bool &ResNodeDecled, bool isRoot = false) { + const CodeGenTarget &T = CGP.getTargetInfo(); + unsigned OpNo = + (unsigned) NodeHasProperty(N, SDNPHasChain, CGP); + bool HasInFlag = NodeHasProperty(N, SDNPInFlag, CGP); + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { + TreePatternNode *Child = N->getChild(i); + if (!Child->isLeaf()) { + EmitInFlagSelectCode(Child, RootName + utostr(OpNo), ChainEmitted, + InFlagDecled, ResNodeDecled); + } else { + if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) { + if (!Child->getName().empty()) { + std::string Name = RootName + utostr(OpNo); + if (Duplicates.find(Name) != Duplicates.end()) + // A duplicate! Do not emit a copy for this node. + continue; } - if (NeedCheck) { - std::string ParentName(RootName.begin(), RootName.end()-1); - emitCheck("IsLegalAndProfitableToFold(" + getNodeName(RootName) + - ", " + getNodeName(ParentName) + ", N)"); + Record *RR = DI->getDef(); + if (RR->isSubClassOf("Register")) { + MVT::SimpleValueType RVT = getRegisterValueType(RR, T); + if (RVT == MVT::Flag) { + if (!InFlagDecled) { + emitCode("SDValue InFlag = " + + getValueName(RootName + utostr(OpNo)) + ";"); + InFlagDecled = true; + } else + emitCode("InFlag = " + + getValueName(RootName + utostr(OpNo)) + ";"); + } else { + if (!ChainEmitted) { + emitCode("SDValue Chain = CurDAG->getEntryNode();"); + ChainName = "Chain"; + ChainEmitted = true; + } + if (!InFlagDecled) { + emitCode("SDValue InFlag(0, 0);"); + InFlagDecled = true; + } + std::string Decl = (!ResNodeDecled) ? "SDNode *" : ""; + emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" + ChainName + + ", " + getNodeName(RootName) + "->getDebugLoc()" + + ", " + getQualifiedName(RR) + + ", " + getValueName(RootName + utostr(OpNo)) + + ", InFlag).getNode();"); + ResNodeDecled = true; + emitCode(ChainName + " = SDValue(ResNode, 0);"); + emitCode("InFlag = SDValue(ResNode, 1);"); + } } } } - - if (NodeHasChain) { - if (FoundChain) { - emitCheck("(" + ChainName + ".getNode() == " + - getNodeName(RootName) + " || " - "IsChainCompatible(" + ChainName + ".getNode(), " + - getNodeName(RootName) + "))"); - OrigChains.push_back(std::make_pair(ChainName, - getValueName(RootName))); - } else - FoundChain = true; - ChainName = "Chain" + ChainSuffix; - emitInit("SDValue " + ChainName + " = " + getNodeName(RootName) + - "->getOperand(0);"); - } } - // Don't fold any node which reads or writes a flag and has multiple uses. - // FIXME: We really need to separate the concepts of flag and "glue". Those - // real flag results, e.g. X86CMP output, can have multiple uses. - // FIXME: If the optional incoming flag does not exist. Then it is ok to - // fold it. - if (!isRoot && - (PatternHasProperty(N, SDNPInFlag, CGP) || - PatternHasProperty(N, SDNPOptInFlag, CGP) || - PatternHasProperty(N, SDNPOutFlag, CGP))) { - if (!EmittedUseCheck) { - // Multiple uses of actual result? - emitCheck(getValueName(RootName) + ".hasOneUse()"); - } + if (HasInFlag) { + if (!InFlagDecled) { + emitCode("SDValue InFlag = " + getNodeName(RootName) + + "->getOperand(" + utostr(OpNo) + ");"); + InFlagDecled = true; + } else + emitCode("InFlag = " + getNodeName(RootName) + + "->getOperand(" + utostr(OpNo) + ");"); } + } +}; - // If there are node predicates for this, emit the calls. - for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i) - emitCheck(N->getPredicateFns()[i] + "(" + getNodeName(RootName) + ")"); - - // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is - // a constant without a predicate fn that has more that one bit set, handle - // this as a special case. This is usually for targets that have special - // handling of certain large constants (e.g. alpha with it's 8/16/32-bit - // handling stuff). Using these instructions is often far more efficient - // than materializing the constant. Unfortunately, both the instcombiner - // and the dag combiner can often infer that bits are dead, and thus drop - // them from the mask in the dag. For example, it might turn 'AND X, 255' - // into 'AND X, 254' if it knows the low bit is set. Emit code that checks - // to handle this. - if (!N->isLeaf() && - (N->getOperator()->getName() == "and" || - N->getOperator()->getName() == "or") && - N->getChild(1)->isLeaf() && - N->getChild(1)->getPredicateFns().empty()) { - if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) { - if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits. - emitInit("SDValue " + RootName + "0" + " = " + - getNodeName(RootName) + "->getOperand(" + utostr(0) + ");"); - emitInit("SDValue " + RootName + "1" + " = " + - getNodeName(RootName) + "->getOperand(" + utostr(1) + ");"); - - unsigned NTmp = TmpNo++; - emitCode("ConstantSDNode *Tmp" + utostr(NTmp) + - " = dyn_cast<ConstantSDNode>(" + - getNodeName(RootName + "1") + ");"); - emitCheck("Tmp" + utostr(NTmp)); - const char *MaskPredicate = N->getOperator()->getName() == "or" - ? "CheckOrMask(" : "CheckAndMask("; - emitCheck(MaskPredicate + getValueName(RootName + "0") + - ", Tmp" + utostr(NTmp) + - ", INT64_C(" + itostr(II->getValue()) + "))"); - - EmitChildMatchCode(N->getChild(0), N, RootName + utostr(0), - ChainSuffix + utostr(0), FoundChain); - return; + +/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo +/// if the match fails. At this point, we already know that the opcode for N +/// matches, and the SDNode for the result has the RootName specified name. +void PatternCodeEmitter::EmitMatchCode(TreePatternNode *N, TreePatternNode *P, + const std::string &RootName, + const std::string &ChainSuffix, + bool &FoundChain) { + + // Save loads/stores matched by a pattern. + if (!N->isLeaf() && N->getName().empty()) { + if (NodeHasProperty(N, SDNPMemOperand, CGP)) + LSI.push_back(getNodeName(RootName)); + } + + bool isRoot = (P == NULL); + // Emit instruction predicates. Each predicate is just a string for now. + if (isRoot) { + // Record input varargs info. + NumInputRootOps = N->getNumChildren(); + + if (DisablePatternForFastISel(N, CGP)) + emitCheck("OptLevel != CodeGenOpt::None"); + + emitCheck(PredicateCheck); + } + + if (N->isLeaf()) { + if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) { + emitCheck("cast<ConstantSDNode>(" + getNodeName(RootName) + + ")->getSExtValue() == INT64_C(" + + itostr(II->getValue()) + ")"); + return; + } else if (!NodeIsComplexPattern(N)) { + assert(0 && "Cannot match this as a leaf value!"); + abort(); + } + } + + // If this node has a name associated with it, capture it in VariableMap. If + // we already saw this in the pattern, emit code to verify dagness. + if (!N->getName().empty()) { + std::string &VarMapEntry = VariableMap[N->getName()]; + if (VarMapEntry.empty()) { + VarMapEntry = RootName; + } else { + // If we get here, this is a second reference to a specific name. Since + // we already have checked that the first reference is valid, we don't + // have to recursively match it, just check that it's the same as the + // previously named thing. + emitCheck(VarMapEntry + " == " + RootName); + return; + } + + if (!N->isLeaf()) + OperatorMap[N->getName()] = N->getOperator(); + } + + + // Emit code to load the child nodes and match their contents recursively. + unsigned OpNo = 0; + bool NodeHasChain = NodeHasProperty (N, SDNPHasChain, CGP); + bool HasChain = PatternHasProperty(N, SDNPHasChain, CGP); + bool EmittedUseCheck = false; + if (HasChain) { + if (NodeHasChain) + OpNo = 1; + if (!isRoot) { + // Multiple uses of actual result? + emitCheck(getValueName(RootName) + ".hasOneUse()"); + EmittedUseCheck = true; + if (NodeHasChain) { + // If the immediate use can somehow reach this node through another + // path, then can't fold it either or it will create a cycle. + // e.g. In the following diagram, XX can reach ld through YY. If + // ld is folded into XX, then YY is both a predecessor and a successor + // of XX. + // + // [ld] + // ^ ^ + // | | + // / \--- + // / [YY] + // | ^ + // [XX]-------| + bool NeedCheck = P != Pattern; + if (!NeedCheck) { + const SDNodeInfo &PInfo = CGP.getSDNodeInfo(P->getOperator()); + NeedCheck = + P->getOperator() == CGP.get_intrinsic_void_sdnode() || + P->getOperator() == CGP.get_intrinsic_w_chain_sdnode() || + P->getOperator() == CGP.get_intrinsic_wo_chain_sdnode() || + PInfo.getNumOperands() > 1 || + PInfo.hasProperty(SDNPHasChain) || + PInfo.hasProperty(SDNPInFlag) || + PInfo.hasProperty(SDNPOptInFlag); + } + + if (NeedCheck) { + std::string ParentName(RootName.begin(), RootName.end()-1); + emitCheck("IsLegalAndProfitableToFold(" + getNodeName(RootName) + + ", " + getNodeName(ParentName) + ", N)"); } } } - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { - emitInit("SDValue " + getValueName(RootName + utostr(OpNo)) + " = " + - getNodeName(RootName) + "->getOperand(" + utostr(OpNo) + ");"); - - EmitChildMatchCode(N->getChild(i), N, RootName + utostr(OpNo), - ChainSuffix + utostr(OpNo), FoundChain); + if (NodeHasChain) { + if (FoundChain) { + emitCheck("(" + ChainName + ".getNode() == " + + getNodeName(RootName) + " || " + "IsChainCompatible(" + ChainName + ".getNode(), " + + getNodeName(RootName) + "))"); + OrigChains.push_back(std::make_pair(ChainName, + getValueName(RootName))); + } else + FoundChain = true; + ChainName = "Chain" + ChainSuffix; + emitInit("SDValue " + ChainName + " = " + getNodeName(RootName) + + "->getOperand(0);"); } - - // Handle cases when root is a complex pattern. - const ComplexPattern *CP; - if (isRoot && N->isLeaf() && (CP = NodeGetComplexPattern(N, CGP))) { - std::string Fn = CP->getSelectFunc(); - unsigned NumOps = CP->getNumOperands(); - for (unsigned i = 0; i < NumOps; ++i) { - emitDecl("CPTmp" + RootName + "_" + utostr(i)); - emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";"); - } - if (CP->hasProperty(SDNPHasChain)) { - emitDecl("CPInChain"); - emitDecl("Chain" + ChainSuffix); - emitCode("SDValue CPInChain;"); - emitCode("SDValue Chain" + ChainSuffix + ";"); + } + + // Don't fold any node which reads or writes a flag and has multiple uses. + // FIXME: We really need to separate the concepts of flag and "glue". Those + // real flag results, e.g. X86CMP output, can have multiple uses. + // FIXME: If the optional incoming flag does not exist. Then it is ok to + // fold it. + if (!isRoot && + (PatternHasProperty(N, SDNPInFlag, CGP) || + PatternHasProperty(N, SDNPOptInFlag, CGP) || + PatternHasProperty(N, SDNPOutFlag, CGP))) { + if (!EmittedUseCheck) { + // Multiple uses of actual result? + emitCheck(getValueName(RootName) + ".hasOneUse()"); + } } - - std::string Code = Fn + "(" + - getNodeName(RootName) + ", " + - getValueName(RootName); - for (unsigned i = 0; i < NumOps; i++) - Code += ", CPTmp" + RootName + "_" + utostr(i); - if (CP->hasProperty(SDNPHasChain)) { - ChainName = "Chain" + ChainSuffix; - Code += ", CPInChain, Chain" + ChainSuffix; + + // If there are node predicates for this, emit the calls. + for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i) + emitCheck(N->getPredicateFns()[i] + "(" + getNodeName(RootName) + ")"); + + // If this is an 'and R, 1234' where the operation is AND/OR and the RHS is + // a constant without a predicate fn that has more that one bit set, handle + // this as a special case. This is usually for targets that have special + // handling of certain large constants (e.g. alpha with it's 8/16/32-bit + // handling stuff). Using these instructions is often far more efficient + // than materializing the constant. Unfortunately, both the instcombiner + // and the dag combiner can often infer that bits are dead, and thus drop + // them from the mask in the dag. For example, it might turn 'AND X, 255' + // into 'AND X, 254' if it knows the low bit is set. Emit code that checks + // to handle this. + if (!N->isLeaf() && + (N->getOperator()->getName() == "and" || + N->getOperator()->getName() == "or") && + N->getChild(1)->isLeaf() && + N->getChild(1)->getPredicateFns().empty()) { + if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) { + if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits. + emitInit("SDValue " + RootName + "0" + " = " + + getNodeName(RootName) + "->getOperand(" + utostr(0) + ");"); + emitInit("SDValue " + RootName + "1" + " = " + + getNodeName(RootName) + "->getOperand(" + utostr(1) + ");"); + + unsigned NTmp = TmpNo++; + emitCode("ConstantSDNode *Tmp" + utostr(NTmp) + + " = dyn_cast<ConstantSDNode>(" + + getNodeName(RootName + "1") + ");"); + emitCheck("Tmp" + utostr(NTmp)); + const char *MaskPredicate = N->getOperator()->getName() == "or" + ? "CheckOrMask(" : "CheckAndMask("; + emitCheck(MaskPredicate + getValueName(RootName + "0") + + ", Tmp" + utostr(NTmp) + + ", INT64_C(" + itostr(II->getValue()) + "))"); + + EmitChildMatchCode(N->getChild(0), N, RootName + utostr(0), + ChainSuffix + utostr(0), FoundChain); + return; } - emitCheck(Code + ")"); } } + + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { + emitInit("SDValue " + getValueName(RootName + utostr(OpNo)) + " = " + + getNodeName(RootName) + "->getOperand(" + utostr(OpNo) + ");"); + + EmitChildMatchCode(N->getChild(i), N, RootName + utostr(OpNo), + ChainSuffix + utostr(OpNo), FoundChain); + } + + // Handle cases when root is a complex pattern. + const ComplexPattern *CP; + if (isRoot && N->isLeaf() && (CP = NodeGetComplexPattern(N, CGP))) { + std::string Fn = CP->getSelectFunc(); + unsigned NumOps = CP->getNumOperands(); + for (unsigned i = 0; i < NumOps; ++i) { + emitDecl("CPTmp" + RootName + "_" + utostr(i)); + emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";"); + } + if (CP->hasProperty(SDNPHasChain)) { + emitDecl("CPInChain"); + emitDecl("Chain" + ChainSuffix); + emitCode("SDValue CPInChain;"); + emitCode("SDValue Chain" + ChainSuffix + ";"); + } + + std::string Code = Fn + "(" + + getNodeName(RootName) + ", " + + getValueName(RootName); + for (unsigned i = 0; i < NumOps; i++) + Code += ", CPTmp" + RootName + "_" + utostr(i); + if (CP->hasProperty(SDNPHasChain)) { + ChainName = "Chain" + ChainSuffix; + Code += ", CPInChain, Chain" + ChainSuffix; + } + emitCheck(Code + ")"); + } +} - void EmitChildMatchCode(TreePatternNode *Child, TreePatternNode *Parent, - const std::string &RootName, - const std::string &ChainSuffix, bool &FoundChain) { - if (!Child->isLeaf()) { - // If it's not a leaf, recursively match. - const SDNodeInfo &CInfo = CGP.getSDNodeInfo(Child->getOperator()); - emitCheck(getNodeName(RootName) + "->getOpcode() == " + - CInfo.getEnumName()); - EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain); - bool HasChain = false; - if (NodeHasProperty(Child, SDNPHasChain, CGP)) { - HasChain = true; - FoldedChains.push_back(std::make_pair(getValueName(RootName), - CInfo.getNumResults())); - } - if (NodeHasProperty(Child, SDNPOutFlag, CGP)) { - assert(FoldedFlag.first == "" && FoldedFlag.second == 0 && - "Pattern folded multiple nodes which produce flags?"); - FoldedFlag = std::make_pair(getValueName(RootName), - CInfo.getNumResults() + (unsigned)HasChain); +void PatternCodeEmitter::EmitChildMatchCode(TreePatternNode *Child, + TreePatternNode *Parent, + const std::string &RootName, + const std::string &ChainSuffix, + bool &FoundChain) { + if (!Child->isLeaf()) { + // If it's not a leaf, recursively match. + const SDNodeInfo &CInfo = CGP.getSDNodeInfo(Child->getOperator()); + emitCheck(getNodeName(RootName) + "->getOpcode() == " + + CInfo.getEnumName()); + EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain); + bool HasChain = false; + if (NodeHasProperty(Child, SDNPHasChain, CGP)) { + HasChain = true; + FoldedChains.push_back(std::make_pair(getValueName(RootName), + CInfo.getNumResults())); + } + if (NodeHasProperty(Child, SDNPOutFlag, CGP)) { + assert(FoldedFlag.first == "" && FoldedFlag.second == 0 && + "Pattern folded multiple nodes which produce flags?"); + FoldedFlag = std::make_pair(getValueName(RootName), + CInfo.getNumResults() + (unsigned)HasChain); + } + } else { + // If this child has a name associated with it, capture it in VarMap. If + // we already saw this in the pattern, emit code to verify dagness. + if (!Child->getName().empty()) { + std::string &VarMapEntry = VariableMap[Child->getName()]; + if (VarMapEntry.empty()) { + VarMapEntry = getValueName(RootName); + } else { + // If we get here, this is a second reference to a specific name. + // Since we already have checked that the first reference is valid, + // we don't have to recursively match it, just check that it's the + // same as the previously named thing. + emitCheck(VarMapEntry + " == " + getValueName(RootName)); + Duplicates.insert(getValueName(RootName)); + return; } - } else { - // If this child has a name associated with it, capture it in VarMap. If - // we already saw this in the pattern, emit code to verify dagness. - if (!Child->getName().empty()) { - std::string &VarMapEntry = VariableMap[Child->getName()]; - if (VarMapEntry.empty()) { - VarMapEntry = getValueName(RootName); - } else { - // If we get here, this is a second reference to a specific name. - // Since we already have checked that the first reference is valid, - // we don't have to recursively match it, just check that it's the - // same as the previously named thing. - emitCheck(VarMapEntry + " == " + getValueName(RootName)); - Duplicates.insert(getValueName(RootName)); - return; + } + + // Handle leaves of various types. + if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) { + Record *LeafRec = DI->getDef(); + if (LeafRec->isSubClassOf("RegisterClass") || + LeafRec->isSubClassOf("PointerLikeRegClass")) { + // Handle register references. Nothing to do here. + } else if (LeafRec->isSubClassOf("Register")) { + // Handle register references. + } else if (LeafRec->isSubClassOf("ComplexPattern")) { + // Handle complex pattern. + const ComplexPattern *CP = NodeGetComplexPattern(Child, CGP); + std::string Fn = CP->getSelectFunc(); + unsigned NumOps = CP->getNumOperands(); + for (unsigned i = 0; i < NumOps; ++i) { + emitDecl("CPTmp" + RootName + "_" + utostr(i)); + emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";"); } - } - - // Handle leaves of various types. - if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) { - Record *LeafRec = DI->getDef(); - if (LeafRec->isSubClassOf("RegisterClass") || - LeafRec->isSubClassOf("PointerLikeRegClass")) { - // Handle register references. Nothing to do here. - } else if (LeafRec->isSubClassOf("Register")) { - // Handle register references. - } else if (LeafRec->isSubClassOf("ComplexPattern")) { - // Handle complex pattern. - const ComplexPattern *CP = NodeGetComplexPattern(Child, CGP); - std::string Fn = CP->getSelectFunc(); - unsigned NumOps = CP->getNumOperands(); - for (unsigned i = 0; i < NumOps; ++i) { - emitDecl("CPTmp" + RootName + "_" + utostr(i)); - emitCode("SDValue CPTmp" + RootName + "_" + utostr(i) + ";"); - } - if (CP->hasProperty(SDNPHasChain)) { - const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Parent->getOperator()); - FoldedChains.push_back(std::make_pair("CPInChain", - PInfo.getNumResults())); - ChainName = "Chain" + ChainSuffix; - emitDecl("CPInChain"); - emitDecl(ChainName); - emitCode("SDValue CPInChain;"); - emitCode("SDValue " + ChainName + ";"); - } - - std::string Code = Fn + "(N, "; - if (CP->hasProperty(SDNPHasChain)) { - std::string ParentName(RootName.begin(), RootName.end()-1); - Code += getValueName(ParentName) + ", "; - } - Code += getValueName(RootName); - for (unsigned i = 0; i < NumOps; i++) - Code += ", CPTmp" + RootName + "_" + utostr(i); - if (CP->hasProperty(SDNPHasChain)) - Code += ", CPInChain, Chain" + ChainSuffix; - emitCheck(Code + ")"); - } else if (LeafRec->getName() == "srcvalue") { - // Place holder for SRCVALUE nodes. Nothing to do here. - } else if (LeafRec->isSubClassOf("ValueType")) { - // Make sure this is the specified value type. - emitCheck("cast<VTSDNode>(" + getNodeName(RootName) + - ")->getVT() == MVT::" + LeafRec->getName()); - } else if (LeafRec->isSubClassOf("CondCode")) { - // Make sure this is the specified cond code. - emitCheck("cast<CondCodeSDNode>(" + getNodeName(RootName) + - ")->get() == ISD::" + LeafRec->getName()); - } else { -#ifndef NDEBUG - Child->dump(); - errs() << " "; -#endif - assert(0 && "Unknown leaf type!"); + if (CP->hasProperty(SDNPHasChain)) { + const SDNodeInfo &PInfo = CGP.getSDNodeInfo(Parent->getOperator()); + FoldedChains.push_back(std::make_pair("CPInChain", + PInfo.getNumResults())); + ChainName = "Chain" + ChainSuffix; + emitDecl("CPInChain"); + emitDecl(ChainName); + emitCode("SDValue CPInChain;"); + emitCode("SDValue " + ChainName + ";"); } - // If there are node predicates for this, emit the calls. - for (unsigned i = 0, e = Child->getPredicateFns().size(); i != e; ++i) - emitCheck(Child->getPredicateFns()[i] + "(" + getNodeName(RootName) + - ")"); - } else if (IntInit *II = - dynamic_cast<IntInit*>(Child->getLeafValue())) { - unsigned NTmp = TmpNo++; - emitCode("ConstantSDNode *Tmp"+ utostr(NTmp) + - " = dyn_cast<ConstantSDNode>("+ - getNodeName(RootName) + ");"); - emitCheck("Tmp" + utostr(NTmp)); - unsigned CTmp = TmpNo++; - emitCode("int64_t CN"+ utostr(CTmp) + - " = Tmp" + utostr(NTmp) + "->getSExtValue();"); - emitCheck("CN" + utostr(CTmp) + " == " - "INT64_C(" +itostr(II->getValue()) + ")"); + std::string Code = Fn + "(N, "; + if (CP->hasProperty(SDNPHasChain)) { + std::string ParentName(RootName.begin(), RootName.end()-1); + Code += getValueName(ParentName) + ", "; + } + Code += getValueName(RootName); + for (unsigned i = 0; i < NumOps; i++) + Code += ", CPTmp" + RootName + "_" + utostr(i); + if (CP->hasProperty(SDNPHasChain)) + Code += ", CPInChain, Chain" + ChainSuffix; + emitCheck(Code + ")"); + } else if (LeafRec->getName() == "srcvalue") { + // Place holder for SRCVALUE nodes. Nothing to do here. + } else if (LeafRec->isSubClassOf("ValueType")) { + // Make sure this is the specified value type. + emitCheck("cast<VTSDNode>(" + getNodeName(RootName) + + ")->getVT() == MVT::" + LeafRec->getName()); + } else if (LeafRec->isSubClassOf("CondCode")) { + // Make sure this is the specified cond code. + emitCheck("cast<CondCodeSDNode>(" + getNodeName(RootName) + + ")->get() == ISD::" + LeafRec->getName()); } else { #ifndef NDEBUG Child->dump(); + errs() << " "; #endif assert(0 && "Unknown leaf type!"); } + + // If there are node predicates for this, emit the calls. + for (unsigned i = 0, e = Child->getPredicateFns().size(); i != e; ++i) + emitCheck(Child->getPredicateFns()[i] + "(" + getNodeName(RootName) + + ")"); + } else if (IntInit *II = + dynamic_cast<IntInit*>(Child->getLeafValue())) { + unsigned NTmp = TmpNo++; + emitCode("ConstantSDNode *Tmp"+ utostr(NTmp) + + " = dyn_cast<ConstantSDNode>("+ + getNodeName(RootName) + ");"); + emitCheck("Tmp" + utostr(NTmp)); + unsigned CTmp = TmpNo++; + emitCode("int64_t CN"+ utostr(CTmp) + + " = Tmp" + utostr(NTmp) + "->getSExtValue();"); + emitCheck("CN" + utostr(CTmp) + " == " + "INT64_C(" +itostr(II->getValue()) + ")"); + } else { +#ifndef NDEBUG + Child->dump(); +#endif + assert(0 && "Unknown leaf type!"); } } +} - /// EmitResultCode - Emit the action for a pattern. Now that it has matched - /// we actually have to build a DAG! - std::vector<std::string> - EmitResultCode(TreePatternNode *N, std::vector<Record*> DstRegs, - bool InFlagDecled, bool ResNodeDecled, - bool LikeLeaf = false, bool isRoot = false) { - // List of arguments of getMachineNode() or SelectNodeTo(). - std::vector<std::string> NodeOps; - // This is something selected from the pattern we matched. - if (!N->getName().empty()) { - const std::string &VarName = N->getName(); - std::string Val = VariableMap[VarName]; - bool ModifiedVal = false; - if (Val.empty()) { - errs() << "Variable '" << VarName << " referenced but not defined " - << "and not caught earlier!\n"; - abort(); - } - if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') { - // Already selected this operand, just return the tmpval. - NodeOps.push_back(getValueName(Val)); - return NodeOps; - } - - const ComplexPattern *CP; - unsigned ResNo = TmpNo++; - if (!N->isLeaf() && N->getOperator()->getName() == "imm") { - assert(N->getExtTypes().size() == 1 && "Multiple types not handled!"); - std::string CastType; - std::string TmpVar = "Tmp" + utostr(ResNo); - switch (N->getTypeNum(0)) { +/// EmitResultCode - Emit the action for a pattern. Now that it has matched +/// we actually have to build a DAG! +std::vector<std::string> +PatternCodeEmitter::EmitResultCode(TreePatternNode *N, + std::vector<Record*> DstRegs, + bool InFlagDecled, bool ResNodeDecled, + bool LikeLeaf, bool isRoot) { + // List of arguments of getMachineNode() or SelectNodeTo(). + std::vector<std::string> NodeOps; + // This is something selected from the pattern we matched. + if (!N->getName().empty()) { + const std::string &VarName = N->getName(); + std::string Val = VariableMap[VarName]; + bool ModifiedVal = false; + if (Val.empty()) { + errs() << "Variable '" << VarName << " referenced but not defined " + << "and not caught earlier!\n"; + abort(); + } + if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') { + // Already selected this operand, just return the tmpval. + NodeOps.push_back(getValueName(Val)); + return NodeOps; + } + + const ComplexPattern *CP; + unsigned ResNo = TmpNo++; + if (!N->isLeaf() && N->getOperator()->getName() == "imm") { + assert(N->getExtTypes().size() == 1 && "Multiple types not handled!"); + std::string CastType; + std::string TmpVar = "Tmp" + utostr(ResNo); + switch (N->getTypeNum(0)) { default: errs() << "Cannot handle " << getEnumName(N->getTypeNum(0)) - << " type as an immediate constant. Aborting\n"; + << " type as an immediate constant. Aborting\n"; abort(); case MVT::i1: CastType = "bool"; break; case MVT::i8: CastType = "unsigned char"; break; case MVT::i16: CastType = "unsigned short"; break; case MVT::i32: CastType = "unsigned"; break; case MVT::i64: CastType = "uint64_t"; break; - } - emitCode("SDValue " + TmpVar + - " = CurDAG->getTargetConstant(((" + CastType + - ") cast<ConstantSDNode>(" + Val + ")->getZExtValue()), " + + } + emitCode("SDValue " + TmpVar + + " = CurDAG->getTargetConstant(((" + CastType + + ") cast<ConstantSDNode>(" + Val + ")->getZExtValue()), " + + getEnumName(N->getTypeNum(0)) + ");"); + // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this + // value if used multiple times by this pattern result. + Val = TmpVar; + ModifiedVal = true; + NodeOps.push_back(getValueName(Va |