X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FDAGISelEmitter.cpp;h=3d79ea09b3e1743880fee52c46d98d8d4e6e10b0;hb=dfdaeb276e50baea18abbe30a85f1c206bb3d154;hp=4d4fa9dabd011198c4777bf0347d22f41e5e3c69;hpb=7905c55b12bd5bff95304e3e7152d7a41ec8a78c;p=oota-llvm.git diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 4d4fa9dabd0..3d79ea09b3e 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -15,6 +15,7 @@ #include "Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include #include using namespace llvm; @@ -758,27 +759,40 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { MadeChange = UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP); } - if (getNumChildren() != Inst.getNumOperands()) - TP.error("Instruction '" + getOperator()->getName() + " expects " + - utostr(Inst.getNumOperands()) + " operands, not " + - utostr(getNumChildren()) + " operands!"); - for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { + unsigned ChildNo = 0; + for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) { Record *OperandNode = Inst.getOperand(i); + + // If the instruction expects a predicate operand, we codegen this by + // setting the predicate to it's "execute always" value. + if (OperandNode->isSubClassOf("PredicateOperand")) + continue; + + // Verify that we didn't run out of provided operands. + if (ChildNo >= getNumChildren()) + TP.error("Instruction '" + getOperator()->getName() + + "' expects more operands than were provided."); + MVT::ValueType VT; + TreePatternNode *Child = getChild(ChildNo++); if (OperandNode->isSubClassOf("RegisterClass")) { const CodeGenRegisterClass &RC = ISE.getTargetInfo().getRegisterClass(OperandNode); - MadeChange |=getChild(i)->UpdateNodeType(ConvertVTs(RC.getValueTypes()), - TP); + MadeChange |= Child->UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP); } else if (OperandNode->isSubClassOf("Operand")) { VT = getValueType(OperandNode->getValueAsDef("Type")); - MadeChange |= getChild(i)->UpdateNodeType(VT, TP); + MadeChange |= Child->UpdateNodeType(VT, TP); } else { assert(0 && "Unknown operand type!"); abort(); } - MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); + MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters); } + + if (ChildNo != getNumChildren()) + TP.error("Instruction '" + getOperator()->getName() + + "' was provided too many operands!"); + return MadeChange; } else { assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); @@ -800,6 +814,17 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { } } +/// OnlyOnRHSOfCommutative - Return true if this value is only allowed on the +/// RHS of a commutative operation, not the on LHS. +static bool OnlyOnRHSOfCommutative(TreePatternNode *N) { + if (!N->isLeaf() && N->getOperator()->getName() == "imm") + return true; + if (N->isLeaf() && dynamic_cast(N->getLeafValue())) + return true; + return false; +} + + /// canPatternMatch - If it is impossible for this pattern to match on this /// target, fill in Reason and return false. Otherwise, return true. This is /// used as a santity check for .td files (to prevent people from writing stuff @@ -822,15 +847,13 @@ bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE){ // If this node is a commutative operator, check that the LHS isn't an // immediate. const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator()); - if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) { + if (NodeInfo.hasProperty(SDNPCommutative)) { // Scan all of the operands of the node and make sure that only the last one // is a constant node, unless the RHS also is. - if (getChild(getNumChildren()-1)->isLeaf() || - getChild(getNumChildren()-1)->getOperator()->getName() != "imm") { + if (!OnlyOnRHSOfCommutative(getChild(getNumChildren()-1))) { for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) - if (!getChild(i)->isLeaf() && - getChild(i)->getOperator()->getName() == "imm") { - Reason = "Immediate value must be on the RHS of commutative operators!"; + if (OnlyOnRHSOfCommutative(getChild(i))) { + Reason="Immediate value must be on the RHS of commutative operators!"; return false; } } @@ -1158,15 +1181,19 @@ void DAGISelEmitter::ParsePatternFragments(std::ostream &OS) { // keep track of the fact that this fragment uses it. std::string Code = Fragments[i]->getValueAsCode("Predicate"); if (!Code.empty()) { - assert(!P->getOnlyTree()->isLeaf() && "Can't be a leaf!"); - std::string ClassName = - getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName(); - const char *C2 = ClassName == "SDNode" ? "N" : "inN"; + if (P->getOnlyTree()->isLeaf()) + OS << "inline bool Predicate_" << Fragments[i]->getName() + << "(SDNode *N) {\n"; + else { + std::string ClassName = + getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName(); + const char *C2 = ClassName == "SDNode" ? "N" : "inN"; - OS << "inline bool Predicate_" << Fragments[i]->getName() - << "(SDNode *" << C2 << ") {\n"; - if (ClassName != "SDNode") - OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n"; + OS << "inline bool Predicate_" << Fragments[i]->getName() + << "(SDNode *" << C2 << ") {\n"; + if (ClassName != "SDNode") + OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n"; + } OS << Code << "\n}\n"; P->getOnlyTree()->setPredicateFn("Predicate_"+Fragments[i]->getName()); } @@ -1457,25 +1484,35 @@ void DAGISelEmitter::ParseInstructions() { std::vector ResultNodeOperands; std::vector Operands; for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) { - const std::string &OpName = CGI.OperandList[i].Name; + CodeGenInstruction::OperandInfo &Op = CGI.OperandList[i]; + const std::string &OpName = Op.Name; if (OpName.empty()) I->error("Operand #" + utostr(i) + " in operands list has no name!"); - if (!InstInputsCheck.count(OpName)) + if (!InstInputsCheck.count(OpName)) { + // If this is an predicate operand with an ExecuteAlways set filled in, + // we can ignore this. When we codegen it, we will do so as always + // executed. + if (Op.Rec->isSubClassOf("PredicateOperand")) { + // Does it have a non-empty ExecuteAlways field? If so, ignore this + // operand. + if (Op.Rec->getValueAsDag("ExecuteAlways")->getNumArgs()) + continue; + } I->error("Operand $" + OpName + " does not appear in the instruction pattern"); + } TreePatternNode *InVal = InstInputsCheck[OpName]; InstInputsCheck.erase(OpName); // It occurred, remove from map. if (InVal->isLeaf() && dynamic_cast(InVal->getLeafValue())) { Record *InRec = static_cast(InVal->getLeafValue())->getDef(); - if (CGI.OperandList[i].Rec != InRec && - !InRec->isSubClassOf("ComplexPattern")) + if (Op.Rec != InRec && !InRec->isSubClassOf("ComplexPattern")) I->error("Operand $" + OpName + "'s register class disagrees" " between the operand and pattern"); } - Operands.push_back(CGI.OperandList[i].Rec); + Operands.push_back(Op.Rec); // Construct the result for the dest-pattern operand list. TreePatternNode *OpNode = InVal->clone(); @@ -1586,8 +1623,8 @@ void DAGISelEmitter::ParsePatterns() { // can never do anything with this pattern: report it to the user. InferredAllPatternTypes = Pattern->InferAllTypes(); - // Infer as many types as possible. If we cannot infer all of them, we can - // never do anything with this pattern: report it to the user. + // Infer as many types as possible. If we cannot infer all of them, we + // can never do anything with this pattern: report it to the user. InferredAllResultTypes = Result->InferAllTypes(); // Apply the type of the result to the source pattern. This helps us @@ -1768,7 +1805,7 @@ static void GenerateVariantsOf(TreePatternNode *N, const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(N->getOperator()); // If this node is associative, reassociate. - if (NodeInfo.hasProperty(SDNodeInfo::SDNPAssociative)) { + if (NodeInfo.hasProperty(SDNPAssociative)) { // Reassociate by pulling together all of the linked operators std::vector MaximalChildren; GatherChildrenOfAssociativeOpcode(N, MaximalChildren); @@ -1829,7 +1866,7 @@ static void GenerateVariantsOf(TreePatternNode *N, CombineChildVariants(N, ChildVariants, OutVariants, ISE); // If this node is commutative, consider the commuted order. - if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) { + if (NodeInfo.hasProperty(SDNPCommutative)) { assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!"); // Don't count children which are actually register references. unsigned NC = 0; @@ -2074,10 +2111,15 @@ Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const { /// NodeHasProperty - return true if TreePatternNode has the specified /// property. -static bool NodeHasProperty(TreePatternNode *N, SDNodeInfo::SDNP Property, +static bool NodeHasProperty(TreePatternNode *N, SDNP Property, DAGISelEmitter &ISE) { - if (N->isLeaf()) return false; + if (N->isLeaf()) { + const ComplexPattern *CP = NodeGetComplexPattern(N, ISE); + if (CP) + return CP->hasProperty(Property); + return false; + } Record *Operator = N->getOperator(); if (!Operator->isSubClassOf("SDNode")) return false; @@ -2085,7 +2127,7 @@ static bool NodeHasProperty(TreePatternNode *N, SDNodeInfo::SDNP Property, return NodeInfo.hasProperty(Property); } -static bool PatternHasProperty(TreePatternNode *N, SDNodeInfo::SDNP Property, +static bool PatternHasProperty(TreePatternNode *N, SDNP Property, DAGISelEmitter &ISE) { if (NodeHasProperty(N, Property, ISE)) @@ -2119,6 +2161,8 @@ private: std::map OperatorMap; // Names of all the folded nodes which produce chains. std::vector > FoldedChains; + // Original input chain(s). + std::vector > OrigChains; std::set Duplicates; /// GeneratedCode - This is the buffer that we emit code to. The first int @@ -2179,8 +2223,8 @@ public: /// 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 EmitMatchCode(TreePatternNode *N, TreePatternNode *P, - const std::string &RootName, const std::string &ParentName, - const std::string &ChainSuffix, bool &FoundChain) { + const std::string &RootName, const std::string &ChainSuffix, + bool &FoundChain) { bool isRoot = (P == NULL); // Emit instruction predicates. Each predicate is just a string for now. if (isRoot) { @@ -2195,7 +2239,7 @@ public: assert(0 && "Unknown predicate type!"); } if (!PredicateCheck.empty()) - PredicateCheck += " || "; + PredicateCheck += " && "; PredicateCheck += "(" + Def->getValueAsString("CondString") + ")"; } } @@ -2236,15 +2280,13 @@ public: // Emit code to load the child nodes and match their contents recursively. unsigned OpNo = 0; - bool NodeHasChain = NodeHasProperty (N, SDNodeInfo::SDNPHasChain, ISE); - bool HasChain = PatternHasProperty(N, SDNodeInfo::SDNPHasChain, ISE); - bool HasOutFlag = PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE); + bool NodeHasChain = NodeHasProperty (N, SDNPHasChain, ISE); + bool HasChain = PatternHasProperty(N, SDNPHasChain, ISE); bool EmittedUseCheck = false; if (HasChain) { if (NodeHasChain) OpNo = 1; if (!isRoot) { - const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator()); // Multiple uses of actual result? emitCheck(RootName + ".hasOneUse()"); EmittedUseCheck = true; @@ -2262,20 +2304,36 @@ public: // / [YY] // | ^ // [XX]-------| - const SDNodeInfo &PInfo = ISE.getSDNodeInfo(P->getOperator()); - if (PInfo.getNumOperands() > 1 || - PInfo.hasProperty(SDNodeInfo::SDNPHasChain) || - PInfo.hasProperty(SDNodeInfo::SDNPInFlag) || - PInfo.hasProperty(SDNodeInfo::SDNPOptInFlag)) + bool NeedCheck = false; + if (P != Pattern) + NeedCheck = true; + else { + const SDNodeInfo &PInfo = ISE.getSDNodeInfo(P->getOperator()); + NeedCheck = + P->getOperator() == ISE.get_intrinsic_void_sdnode() || + P->getOperator() == ISE.get_intrinsic_w_chain_sdnode() || + P->getOperator() == ISE.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("CanBeFoldedBy(" + RootName + ".Val, " + ParentName + - ".Val)"); + ".Val, N.Val)"); + } } } if (NodeHasChain) { - if (FoundChain) - emitCheck("Chain.Val == " + RootName + ".Val"); - else + if (FoundChain) { + emitCheck("(" + ChainName + ".Val == " + RootName + ".Val || " + "IsChainCompatible(" + ChainName + ".Val, " + + RootName + ".Val))"); + OrigChains.push_back(std::make_pair(ChainName, RootName)); + } else FoundChain = true; ChainName = "Chain" + ChainSuffix; emitInit("SDOperand " + ChainName + " = " + RootName + @@ -2289,106 +2347,65 @@ public: // FIXME: If the optional incoming flag does not exist. Then it is ok to // fold it. if (!isRoot && - (PatternHasProperty(N, SDNodeInfo::SDNPInFlag, ISE) || - PatternHasProperty(N, SDNodeInfo::SDNPOptInFlag, ISE) || - PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE))) { - const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator()); + (PatternHasProperty(N, SDNPInFlag, ISE) || + PatternHasProperty(N, SDNPOptInFlag, ISE) || + PatternHasProperty(N, SDNPOutFlag, ISE))) { if (!EmittedUseCheck) { // Multiple uses of actual result? emitCheck(RootName + ".hasOneUse()"); } } - const ComplexPattern *CP; + // If there is a node predicate for this, emit the call. + if (!N->getPredicateFn().empty()) + emitCheck(N->getPredicateFn() + "(" + RootName + ".Val)"); + + + // 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)->getPredicateFn().empty()) { + if (IntInit *II = dynamic_cast(N->getChild(1)->getLeafValue())) { + if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits. + emitInit("SDOperand " + RootName + "0" + " = " + + RootName + ".getOperand(" + utostr(0) + ");"); + emitInit("SDOperand " + RootName + "1" + " = " + + RootName + ".getOperand(" + utostr(1) + ");"); + + emitCheck("isa(" + RootName + "1)"); + const char *MaskPredicate = N->getOperator()->getName() == "or" + ? "CheckOrMask(" : "CheckAndMask("; + emitCheck(MaskPredicate + RootName + "0, cast(" + + RootName + "1), " + itostr(II->getValue()) + ")"); + + EmitChildMatchCode(N->getChild(0), N, RootName + utostr(0), + ChainSuffix + utostr(0), FoundChain); + return; + } + } + } + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { emitInit("SDOperand " + RootName + utostr(OpNo) + " = " + RootName + ".getOperand(" +utostr(OpNo) + ");"); - TreePatternNode *Child = N->getChild(i); - if (!Child->isLeaf()) { - // If it's not a leaf, recursively match. - const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator()); - emitCheck(RootName + utostr(OpNo) + ".getOpcode() == " + - CInfo.getEnumName()); - EmitMatchCode(Child, N, RootName + utostr(OpNo), RootName, - ChainSuffix + utostr(OpNo), FoundChain); - if (NodeHasProperty(Child, SDNodeInfo::SDNPHasChain, ISE)) - FoldedChains.push_back(std::make_pair(RootName + utostr(OpNo), - CInfo.getNumResults())); - } 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 = RootName + utostr(OpNo); - } 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 + utostr(OpNo)); - Duplicates.insert(RootName + utostr(OpNo)); - continue; - } - } - - // Handle leaves of various types. - if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { - Record *LeafRec = DI->getDef(); - if (LeafRec->isSubClassOf("RegisterClass")) { - // Handle register references. Nothing to do here. - } else if (LeafRec->isSubClassOf("Register")) { - // Handle register references. - } else if (LeafRec->isSubClassOf("ComplexPattern")) { - // Handle complex pattern. - CP = NodeGetComplexPattern(Child, ISE); - std::string Fn = CP->getSelectFunc(); - unsigned NumOps = CP->getNumOperands(); - for (unsigned i = 0; i < NumOps; ++i) { - emitDecl("CPTmp" + utostr(i)); - emitCode("SDOperand CPTmp" + utostr(i) + ";"); - } - - std::string Code = Fn + "(" + RootName + utostr(OpNo); - for (unsigned i = 0; i < NumOps; i++) - Code += ", CPTmp" + utostr(i); - 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(" + RootName + utostr(OpNo) + - ")->getVT() == MVT::" + LeafRec->getName()); - } else if (LeafRec->isSubClassOf("CondCode")) { - // Make sure this is the specified cond code. - emitCheck("cast(" + RootName + utostr(OpNo) + - ")->get() == ISD::" + LeafRec->getName()); - } else { -#ifndef NDEBUG - Child->dump(); - std::cerr << " "; -#endif - assert(0 && "Unknown leaf type!"); - } - } else if (IntInit *II = - dynamic_cast(Child->getLeafValue())) { - emitCheck("isa(" + RootName + utostr(OpNo) + ")"); - unsigned CTmp = TmpNo++; - emitCode("int64_t CN"+utostr(CTmp)+" = cast("+ - RootName + utostr(OpNo) + ")->getSignExtended();"); - - emitCheck("CN" + utostr(CTmp) + " == " +itostr(II->getValue())); - } else { -#ifndef NDEBUG - Child->dump(); -#endif - assert(0 && "Unknown leaf type!"); - } - } + 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, ISE))) { std::string Fn = CP->getSelectFunc(); unsigned NumOps = CP->getNumOperands(); @@ -2396,16 +2413,128 @@ public: emitDecl("CPTmp" + utostr(i)); emitCode("SDOperand CPTmp" + utostr(i) + ";"); } + if (CP->hasProperty(SDNPHasChain)) { + emitDecl("CPInChain"); + emitDecl("Chain" + ChainSuffix); + emitCode("SDOperand CPInChain;"); + emitCode("SDOperand Chain" + ChainSuffix + ";"); + } std::string Code = Fn + "(" + RootName; for (unsigned i = 0; i < NumOps; i++) Code += ", CPTmp" + utostr(i); + if (CP->hasProperty(SDNPHasChain)) { + ChainName = "Chain" + ChainSuffix; + Code += ", CPInChain, Chain" + ChainSuffix; + } emitCheck(Code + ")"); } + } - // If there is a node predicate for this, emit the call. - if (!N->getPredicateFn().empty()) - emitCheck(N->getPredicateFn() + "(" + RootName + ".Val)"); + 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 = ISE.getSDNodeInfo(Child->getOperator()); + emitCheck(RootName + ".getOpcode() == " + + CInfo.getEnumName()); + EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain); + if (NodeHasProperty(Child, SDNPHasChain, ISE)) + FoldedChains.push_back(std::make_pair(RootName, CInfo.getNumResults())); + } 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 = 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); + Duplicates.insert(RootName); + return; + } + } + + // Handle leaves of various types. + if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { + Record *LeafRec = DI->getDef(); + if (LeafRec->isSubClassOf("RegisterClass")) { + // 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, ISE); + std::string Fn = CP->getSelectFunc(); + unsigned NumOps = CP->getNumOperands(); + for (unsigned i = 0; i < NumOps; ++i) { + emitDecl("CPTmp" + utostr(i)); + emitCode("SDOperand CPTmp" + utostr(i) + ";"); + } + if (CP->hasProperty(SDNPHasChain)) { + const SDNodeInfo &PInfo = ISE.getSDNodeInfo(Parent->getOperator()); + FoldedChains.push_back(std::make_pair("CPInChain", + PInfo.getNumResults())); + ChainName = "Chain" + ChainSuffix; + emitDecl("CPInChain"); + emitDecl(ChainName); + emitCode("SDOperand CPInChain;"); + emitCode("SDOperand " + ChainName + ";"); + } + + std::string Code = Fn + "("; + if (CP->hasProperty(SDNPHasChain)) { + std::string ParentName(RootName.begin(), RootName.end()-1); + Code += "N, " + ParentName + ", "; + } + Code += RootName; + for (unsigned i = 0; i < NumOps; i++) + Code += ", CPTmp" + 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(" + RootName + + ")->getVT() == MVT::" + LeafRec->getName()); + } else if (LeafRec->isSubClassOf("CondCode")) { + // Make sure this is the specified cond code. + emitCheck("cast(" + RootName + + ")->get() == ISD::" + LeafRec->getName()); + } else { +#ifndef NDEBUG + Child->dump(); + std::cerr << " "; +#endif + assert(0 && "Unknown leaf type!"); + } + + // If there is a node predicate for this, emit the call. + if (!Child->getPredicateFn().empty()) + emitCheck(Child->getPredicateFn() + "(" + RootName + + ".Val)"); + } else if (IntInit *II = + dynamic_cast(Child->getLeafValue())) { + emitCheck("isa(" + RootName + ")"); + unsigned CTmp = TmpNo++; + emitCode("int64_t CN"+utostr(CTmp)+" = cast("+ + RootName + ")->getSignExtended();"); + + emitCheck("CN" + utostr(CTmp) + " == " +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 @@ -2457,8 +2586,8 @@ public: Val + ")->getSymbol(), " + getEnumName(N->getTypeNum(0)) + ");"); NodeOps.push_back("Tmp" + utostr(ResNo)); - // Add Tmp to VariableMap, so that we don't multiply select this - // value if used multiple times by this pattern result. + // Add Tmp to VariableMap, so that we don't multiply select + // this value if used multiple times by this pattern result. Val = "Tmp"+utostr(ResNo); } else { NodeOps.push_back(Val); @@ -2472,8 +2601,8 @@ public: ")->getGlobal(), " + getEnumName(N->getTypeNum(0)) + ");"); NodeOps.push_back("Tmp" + utostr(ResNo)); - // Add Tmp to VariableMap, so that we don't multiply select this - // value if used multiple times by this pattern result. + // Add Tmp to VariableMap, so that we don't multiply select + // this value if used multiple times by this pattern result. Val = "Tmp"+utostr(ResNo); } else { NodeOps.push_back(Val); @@ -2552,15 +2681,15 @@ public: bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0; bool HasImpResults = isRoot && Inst.getNumImpResults() > 0; bool NodeHasOptInFlag = isRoot && - PatternHasProperty(Pattern, SDNodeInfo::SDNPOptInFlag, ISE); + PatternHasProperty(Pattern, SDNPOptInFlag, ISE); bool NodeHasInFlag = isRoot && - PatternHasProperty(Pattern, SDNodeInfo::SDNPInFlag, ISE); + PatternHasProperty(Pattern, SDNPInFlag, ISE); bool NodeHasOutFlag = HasImpResults || (isRoot && - PatternHasProperty(Pattern, SDNodeInfo::SDNPOutFlag, ISE)); + PatternHasProperty(Pattern, SDNPOutFlag, ISE)); bool NodeHasChain = InstPatNode && - PatternHasProperty(InstPatNode, SDNodeInfo::SDNPHasChain, ISE); + PatternHasProperty(InstPatNode, SDNPHasChain, ISE); bool InputHasChain = isRoot && - NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE); + NodeHasProperty(Pattern, SDNPHasChain, ISE); if (NodeHasOptInFlag) { emitCode("bool HasInFlag = " @@ -2577,6 +2706,26 @@ public: PatResults++; } + if (OrigChains.size() > 0) { + // The original input chain is being ignored. If it is not just + // pointing to the op that's being folded, we should create a + // TokenFactor with it and the chain of the folded op as the new chain. + // We could potentially be doing multiple levels of folding, in that + // case, the TokenFactor can have more operands. + emitCode("SmallVector InChains;"); + for (unsigned i = 0, e = OrigChains.size(); i < e; ++i) { + emitCode("if (" + OrigChains[i].first + ".Val != " + + OrigChains[i].second + ".Val) {"); + emitCode(" AddToISelQueue(" + OrigChains[i].first + ");"); + emitCode(" InChains.push_back(" + OrigChains[i].first + ");"); + emitCode("}"); + } + emitCode("AddToISelQueue(" + ChainName + ");"); + emitCode("InChains.push_back(" + ChainName + ");"); + emitCode(ChainName + " = CurDAG->getNode(ISD::TokenFactor, MVT::Other, " + "&InChains[0], InChains.size());"); + } + std::vector AllOps; for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { std::vector Ops = EmitResultCode(N->getChild(i), @@ -2756,8 +2905,8 @@ public: utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));"); if (InputHasChain) emitCode("ReplaceUses(SDOperand(N.Val, " + - utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " + - ChainName + ".ResNo" + "));"); + utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " + + ChainName + ".ResNo" + "));"); } else RetSelected = true; @@ -2855,7 +3004,7 @@ public: } unsigned OpNo = - (unsigned) NodeHasProperty(Pat, SDNodeInfo::SDNPHasChain, ISE); + (unsigned) NodeHasProperty(Pat, SDNPHasChain, ISE); for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo) if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i), Prefix + utostr(OpNo))) @@ -2871,8 +3020,8 @@ private: bool &ResNodeDecled, bool isRoot = false) { const CodeGenTarget &T = ISE.getTargetInfo(); unsigned OpNo = - (unsigned) NodeHasProperty(N, SDNodeInfo::SDNPHasChain, ISE); - bool HasInFlag = NodeHasProperty(N, SDNodeInfo::SDNPInFlag, ISE); + (unsigned) NodeHasProperty(N, SDNPHasChain, ISE); + bool HasInFlag = NodeHasProperty(N, SDNPInFlag, ISE); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { TreePatternNode *Child = N->getChild(i); if (!Child->isLeaf()) { @@ -2985,8 +3134,7 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern, // Emit the matcher, capturing named arguments in VariableMap. bool FoundChain = false; - Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", "", - FoundChain); + Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", FoundChain); // TP - Get *SOME* tree pattern, we don't care which. TreePattern &TP = *PatternFragments.begin()->second; @@ -3190,8 +3338,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]); } else { const ComplexPattern *CP; - if (IntInit *II = - dynamic_cast(Node->getLeafValue())) { + if (dynamic_cast(Node->getLeafValue())) { PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); } else if ((CP = NodeGetComplexPattern(Node, *this))) { std::vector OpNodes = CP->getRootNodes(); @@ -3257,8 +3404,8 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { ++II) { MVT::ValueType OpVT = II->first; std::vector &Patterns = II->second; - typedef std::vector > CodeList; - typedef std::vector >::iterator CodeListI; + typedef std::vector > CodeList; + typedef std::vector >::iterator CodeListI; std::vector > CodeForPatterns; std::vector > PatternOpcodes; @@ -3399,8 +3546,8 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { // Emit all of the patterns now, grouped together to share code. EmitPatterns(CodeForPatterns, 2, OS); - // If the last pattern has predicates (which could fail) emit code to catch - // the case where nothing handles a pattern. + // If the last pattern has predicates (which could fail) emit code to + // catch the case where nothing handles a pattern. if (mightNotMatch) { OS << " std::cerr << \"Cannot yet select: \";\n"; if (OpcodeInfo.getEnumName() != "ISD::INTRINSIC_W_CHAIN" && @@ -3494,7 +3641,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { } else { if (OpcodeInfo.getNumResults()) OS << " MVT::ValueType NVT = N.Val->getValueType(0);\n"; - else if (OpcodeInfo.hasProperty(SDNodeInfo::SDNPHasChain)) + else if (OpcodeInfo.hasProperty(SDNPHasChain)) OS << " MVT::ValueType NVT = (N.getNumOperands() > 1) ?" << " N.getOperand(1).Val->getValueType(0) : MVT::isVoid;\n"; else @@ -3560,6 +3707,21 @@ void DAGISelEmitter::run(std::ostream &OS) { OS << "/// Dummy parameter to ReplaceAllUsesOfValueWith().\n" << "std::vector ISelKilled;\n\n"; + OS << "/// IsChainCompatible - Returns true if Chain is Op or Chain does\n"; + OS << "/// not reach Op.\n"; + OS << "static bool IsChainCompatible(SDNode *Chain, SDNode *Op) {\n"; + OS << " if (Chain->getOpcode() == ISD::EntryToken)\n"; + OS << " return true;\n"; + OS << " else if (Chain->getOpcode() == ISD::TokenFactor)\n"; + OS << " return false;\n"; + OS << " else if (Chain->getNumOperands() > 0) {\n"; + OS << " SDOperand C0 = Chain->getOperand(0);\n"; + OS << " if (C0.getValueType() == MVT::Other)\n"; + OS << " return C0.Val != Op && IsChainCompatible(C0.Val, Op);\n"; + OS << " }\n"; + OS << " return true;\n"; + OS << "}\n"; + OS << "/// Sorting functions for the selection queue.\n" << "struct isel_sort : public std::binary_function" << " {\n" @@ -3596,7 +3758,8 @@ OS << " unsigned NumKilled = ISelKilled.size();\n"; OS << " if (NumKilled) {\n"; OS << " for (unsigned i = 0; i != NumKilled; ++i) {\n"; OS << " SDNode *Temp = ISelKilled[i];\n"; - OS << " std::remove(ISelQueue.begin(), ISelQueue.end(), Temp);\n"; + OS << " ISelQueue.erase(std::remove(ISelQueue.begin(), ISelQueue.end(), " + << "Temp), ISelQueue.end());\n"; OS << " };\n"; OS << " std::make_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n"; OS << " ISelKilled.clear();\n"; @@ -3614,16 +3777,6 @@ OS << " unsigned NumKilled = ISelKilled.size();\n"; OS << " RemoveKilled();\n"; OS << "}\n\n"; - OS << "void DeleteNode(SDNode *N) {\n"; - OS << " CurDAG->DeleteNode(N);\n"; - OS << " for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); " - << "I != E; ++I) {\n"; - OS << " SDNode *Operand = I->Val;\n"; - OS << " if (Operand->use_empty())\n"; - OS << " DeleteNode(Operand);\n"; - OS << " }\n"; - OS << "}\n"; - OS << "// SelectRoot - Top level entry to DAG isel.\n"; OS << "SDOperand SelectRoot(SDOperand Root) {\n"; OS << " SelectRootInit();\n"; @@ -3647,8 +3800,10 @@ OS << " unsigned NumKilled = ISelKilled.size();\n"; OS << " if (ResNode != Node) {\n"; OS << " if (ResNode)\n"; OS << " ReplaceUses(Node, ResNode);\n"; - OS << " if (Node->use_empty()) // Don't delete EntryToken, etc.\n"; - OS << " DeleteNode(Node);\n"; + OS << " if (Node->use_empty()) { // Don't delete EntryToken, etc.\n"; + OS << " CurDAG->RemoveDeadNode(Node, ISelKilled);\n"; + OS << " RemoveKilled();\n"; + OS << " }\n"; OS << " }\n"; OS << " }\n"; OS << " }\n";