diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index c8cfc2d1679..f03c7c3b0da 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -2134,7 +2134,6 @@ private: std::vector &TargetVTs; std::string ChainName; - bool DoReplace; unsigned TmpNo; unsigned OpcNo; unsigned VTNo; @@ -2165,11 +2164,10 @@ public: std::vector > &gc, std::set > &gd, std::vector &to, - std::vector &tv, - bool dorep) + std::vector &tv) : ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr), GeneratedCode(gc), GeneratedDecl(gd), TargetOpcodes(to), TargetVTs(tv), - DoReplace(dorep), TmpNo(0), OpcNo(0), VTNo(0) {} + TmpNo(0), OpcNo(0), VTNo(0) {} /// 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 @@ -2236,7 +2234,6 @@ public: bool HasChain = PatternHasProperty(N, SDNodeInfo::SDNPHasChain, ISE); bool HasOutFlag = PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE); bool EmittedUseCheck = false; - bool EmittedSlctedCheck = false; if (HasChain) { if (NodeHasChain) OpNo = 1; @@ -2245,13 +2242,6 @@ public: // Multiple uses of actual result? emitCheck(RootName + ".hasOneUse()"); EmittedUseCheck = true; - // hasOneUse() check is not strong enough. If the original node has - // already been selected, it may have been replaced with another. - for (unsigned j = 0; j != CInfo.getNumResults(); j++) - emitCheck("!CodeGenMap.count(" + RootName + ".getValue(" + utostr(j) + - "))"); - - EmittedSlctedCheck = true; if (NodeHasChain) { // FIXME: Don't fold if 1) the parent node writes a flag, 2) the node // has a chain use. @@ -2320,12 +2310,6 @@ public: // Multiple uses of actual result? emitCheck(RootName + ".hasOneUse()"); } - if (!EmittedSlctedCheck) - // hasOneUse() check is not strong enough. If the original node has - // already been selected, it may have been replaced with another. - for (unsigned j = 0; j < CInfo.getNumResults(); j++) - emitCheck("!CodeGenMap.count(" + RootName + ".getValue(" + utostr(j) + - "))"); } for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { @@ -2489,7 +2473,7 @@ public: for (unsigned i = 0; i < NumRes; ++i) { emitDecl("Tmp" + utostr(i+ResNo)); - emitCode("Select(Tmp" + utostr(i+ResNo) + ", CPTmp" + + emitCode("AddToQueue(Tmp" + utostr(i+ResNo) + ", CPTmp" + utostr(i+ResNo) + ");"); } @@ -2501,12 +2485,12 @@ public: if (LikeLeaf) emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";"); else { - emitCode("Select(Tmp" + utostr(ResNo) + ", " + Val + ");"); - } - - if (isRoot && N->isLeaf()) { - emitCode("Result = Tmp" + utostr(ResNo) + ";"); - emitCode("return;"); + emitCode("AddToQueue(Tmp" + utostr(ResNo) + ", " + Val + ");"); + if (isRoot && N->isLeaf()) { + emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");"); + emitCode("Result = Tmp" + utostr(ResNo) + ";"); + emitCode("return;"); + } } } // Add Tmp to VariableMap, so that we don't multiply select this @@ -2620,12 +2604,12 @@ public: // Emit all the chain and CopyToReg stuff. bool ChainEmitted = NodeHasChain; if (NodeHasChain) - emitCode("Select(" + ChainName + ", " + ChainName + ");"); + emitCode("AddToQueue(" + ChainName + ", " + ChainName + ");"); if (NodeHasInFlag || HasImpInputs) EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true); if (NodeHasOptInFlag) { emitCode("if (HasInFlag)"); - emitCode(" Select(InFlag, N.getOperand(N.getNumOperands()-1));"); + emitCode(" AddToQueue(InFlag, N.getOperand(N.getNumOperands()-1));"); } unsigned NumResults = Inst.getNumResults(); @@ -2677,7 +2661,7 @@ public: emitCode("for (unsigned i = 2, e = N.getNumOperands(); " "i != e; ++i) {"); emitCode(" SDOperand VarOp(0, 0);"); - emitCode(" Select(VarOp, N.getOperand(i));"); + emitCode(" AddToQueue(VarOp, N.getOperand(i));"); emitCode(" Ops.push_back(VarOp);"); emitCode("}"); } @@ -2720,50 +2704,35 @@ public: return std::make_pair(1, ResNo); for (unsigned i = 0; i < NumResults; i++) - emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(i) + ", ResNode, " + utostr(i) + ");"); + emitCode("ReplaceUses(SDOperand(N.Val, " + + utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));"); if (NodeHasOutFlag) emitCode("InFlag = SDOperand(ResNode, " + utostr(NumResults + (unsigned)NodeHasChain) + ");"); if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) { - emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " - "0, ResNode, 0);"); + emitCode("ReplaceUses(SDOperand(N.Val, 0), SDOperand(ResNode, 0));"); NumResults = 1; } - if (InputHasChain) { - emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(PatResults) + ", " + ChainName + ".Val, " + - ChainName + ".ResNo" + ");"); - if (DoReplace) - emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " + - utostr(PatResults) + ", " + ChainName + ".Val, " + - ChainName + ".ResNo" + ");"); - } + if (InputHasChain) + emitCode("ReplaceUses(SDOperand(N.Val, " + + utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " + + ChainName + ".ResNo" + "));"); if (FoldedChains.size() > 0) { std::string Code; for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) - emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, " + + emitCode("ReplaceUses(SDOperand(" + FoldedChains[j].first + ".Val, " + - utostr(FoldedChains[j].second) + ", ResNode, " + - utostr(NumResults) + ");"); - - for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) { - std::string Code = - FoldedChains[j].first + ".Val, " + - utostr(FoldedChains[j].second) + ", "; - emitCode("AddHandleReplacement(" + Code + "ResNode, " + - utostr(NumResults) + ");"); - } + utostr(FoldedChains[j].second) + "), SDOperand(ResNode, " + + utostr(NumResults) + "));"); } if (NodeHasOutFlag) - emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + - utostr(PatResults + (unsigned)InputHasChain) + - ", InFlag.Val, InFlag.ResNo);"); + emitCode("ReplaceUses(SDOperand(N.Val, " + + utostr(PatResults + (unsigned)InputHasChain) +"), InFlag);"); // User does not expect the instruction would produce a chain! bool AddedChain = NodeHasChain && !InputHasChain; @@ -2820,8 +2789,7 @@ public: if (NodeHasInFlag || HasImpInputs) Code += ", InFlag"; emitCode(Code + ");"); - emitCode(" SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo" - ", ResNode, 0);"); + emitCode(" ReplaceUses(N, SDOperand(ResNode, 0));"); emitCode(" Result = SDOperand(ResNode, 0);"); emitCode("}"); } @@ -2839,9 +2807,7 @@ public: emitCode("Tmp" + utostr(ResNo) + " = Transform_" + Op->getName() + "(Tmp" + utostr(OpVal) + ".Val);"); if (isRoot) { - emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val," - "N.ResNo, Tmp" + utostr(ResNo) + ".Val, Tmp" + - utostr(ResNo) + ".ResNo);"); + emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");"); emitCode("Result = Tmp" + utostr(ResNo) + ";"); emitCode("return;"); } @@ -2905,7 +2871,7 @@ private: if (RR->isSubClassOf("Register")) { MVT::ValueType RVT = getRegisterValueType(RR, T); if (RVT == MVT::Flag) { - emitCode("Select(InFlag, " + RootName + utostr(OpNo) + ");"); + emitCode("AddToQueue(InFlag, " + RootName + utostr(OpNo) + ");"); } else { if (!ChainEmitted) { emitDecl("Chain"); @@ -2913,7 +2879,7 @@ private: ChainName = "Chain"; ChainEmitted = true; } - emitCode("Select(" + RootName + utostr(OpNo) + ", " + + emitCode("AddToQueue(" + RootName + utostr(OpNo) + ", " + RootName + utostr(OpNo) + ");"); emitCode("ResNode = CurDAG->getCopyToReg(" + ChainName + ", CurDAG->getRegister(" + ISE.getQualifiedName(RR) + @@ -2928,7 +2894,7 @@ private: } if (HasInFlag) - emitCode("Select(InFlag, " + RootName + + emitCode("AddToQueue(InFlag, " + RootName + ".getOperand(" + utostr(OpNo) + "));"); } @@ -2974,13 +2940,11 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern, std::vector > &GeneratedCode, std::set > &GeneratedDecl, std::vector &TargetOpcodes, - std::vector &TargetVTs, - bool DoReplace) { + std::vector &TargetVTs) { PatternCodeEmitter Emitter(*this, Pattern.getPredicates(), Pattern.getSrcPattern(), Pattern.getDstPattern(), GeneratedCode, GeneratedDecl, - TargetOpcodes, TargetVTs, - DoReplace); + TargetOpcodes, TargetVTs); // Emit the matcher, capturing named arguments in VariableMap. bool FoundChain = false; @@ -3107,7 +3071,9 @@ void DAGISelEmitter::EmitPatterns(std::vectorfirst->getName(); const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); - bool OptSlctOrder = - (OpcodeInfo.hasProperty(SDNodeInfo::SDNPHasChain) && - OpcodeInfo.getNumResults() > 0); std::vector &PatternsOfOp = PBOI->second; assert(!PatternsOfOp.empty() && "No patterns but map has entry?"); @@ -3269,7 +3232,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { std::vector TargetOpcodes; std::vector TargetVTs; GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl, - TargetOpcodes, TargetVTs, OptSlctOrder); + TargetOpcodes, TargetVTs); for (std::set >::iterator si = GeneratedDecl.begin(), se = GeneratedDecl.end(); si!=se; ++si) AllGenDecls.insert(*si); @@ -3400,19 +3363,6 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { OS << "void Select_" << OpName << (OpVTStr != "" ? "_" : "") << OpVTStr << "(SDOperand &Result, const SDOperand &N) {\n"; - if (OptSlctOrder) { - OS << " if (N.ResNo == " << OpcodeInfo.getNumResults() - << " && N.getValue(0).hasOneUse()) {\n" - << " SDOperand Dummy = " - << "CurDAG->getNode(ISD::HANDLENODE, MVT::Other, N);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " - << OpcodeInfo.getNumResults() << ", Dummy.Val, 0);\n" - << " SelectionDAG::InsertISelMapEntry(HandleMap, N.Val, " - << OpcodeInfo.getNumResults() << ", Dummy.Val, 0);\n" - << " Result = Dummy;\n" - << " return;\n" - << " }\n"; - } // Print all declarations. for (std::set >::iterator @@ -3462,17 +3412,17 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { // Emit boilerplate. OS << "void Select_INLINEASM(SDOperand& Result, SDOperand N) {\n" << " std::vector Ops(N.Val->op_begin(), N.Val->op_end());\n" - << " Select(Ops[0], N.getOperand(0)); // Select the chain.\n\n" + << " AddToQueue(Ops[0], N.getOperand(0)); // Select the chain.\n\n" << " // Select the flag operand.\n" << " if (Ops.back().getValueType() == MVT::Flag)\n" - << " Select(Ops.back(), Ops.back());\n" + << " AddToQueue(Ops.back(), Ops.back());\n" << " SelectInlineAsmMemoryOperands(Ops, *CurDAG);\n" << " std::vector VTs;\n" << " VTs.push_back(MVT::Other);\n" << " VTs.push_back(MVT::Flag);\n" << " SDOperand New = CurDAG->getNode(ISD::INLINEASM, VTs, Ops);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, New.Val, 0);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, New.Val, 1);\n" + << " ReplaceUses(SDOperand(N.Val, 0), New);\n" + << " ReplaceUses(SDOperand(N.Val, 1), SDOperand(New.Val, 1));\n" << " Result = New.getValue(N.ResNo);\n" << " return;\n" << "}\n\n"; @@ -3485,11 +3435,6 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " Result = N;\n" << " return; // Already selected.\n" << " }\n\n" - << " std::map::iterator CGMI = CodeGenMap.find(N);\n" - << " if (CGMI != CodeGenMap.end()) {\n" - << " Result = CGMI->second;\n" - << " return;\n" - << " }\n\n" << " switch (N.getOpcode()) {\n" << " default: break;\n" << " case ISD::EntryToken: // These leaves remain the same.\n" @@ -3506,96 +3451,18 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " }\n" << " case ISD::AssertSext:\n" << " case ISD::AssertZext: {\n" - << " SDOperand Tmp0;\n" - << " Select(Tmp0, N.getOperand(0));\n" - << " if (!N.Val->hasOneUse())\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, " - << "Tmp0.Val, Tmp0.ResNo);\n" - << " Result = Tmp0;\n" + << " AddToQueue(Result, N.getOperand(0));\n" + << " ReplaceUses(N, Result);\n" << " return;\n" << " }\n" << " case ISD::TokenFactor:\n" - << " if (N.getNumOperands() == 2) {\n" - << " SDOperand Op0, Op1;\n" - << " Select(Op0, N.getOperand(0));\n" - << " Select(Op1, N.getOperand(1));\n" - << " Result = \n" - << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, " - << "Result.Val, Result.ResNo);\n" - << " } else {\n" - << " std::vector Ops;\n" - << " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) {\n" - << " SDOperand Val;\n" - << " Select(Val, N.getOperand(i));\n" - << " Ops.push_back(Val);\n" - << " }\n" - << " Result = \n" - << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, N.ResNo, " - << "Result.Val, Result.ResNo);\n" - << " }\n" - << " return;\n" - << " case ISD::CopyFromReg: {\n" - << " SDOperand Chain;\n" - << " Select(Chain, N.getOperand(0));\n" - << " unsigned Reg = cast(N.getOperand(1))->getReg();\n" - << " MVT::ValueType VT = N.Val->getValueType(0);\n" - << " if (N.Val->getNumValues() == 2) {\n" - << " if (Chain == N.getOperand(0)) {\n" - << " Result = N; // No change\n" - << " return;\n" - << " }\n" - << " SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, " - << "New.Val, 0);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, " - << "New.Val, 1);\n" - << " Result = New.getValue(N.ResNo);\n" - << " return;\n" - << " } else {\n" - << " SDOperand Flag;\n" - << " if (N.getNumOperands() == 3) Select(Flag, N.getOperand(2));\n" - << " if (Chain == N.getOperand(0) &&\n" - << " (N.getNumOperands() == 2 || Flag == N.getOperand(2))) {\n" - << " Result = N; // No change\n" - << " return;\n" - << " }\n" - << " SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT, Flag);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, " - << "New.Val, 0);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, " - << "New.Val, 1);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 2, " - << "New.Val, 2);\n" - << " Result = New.getValue(N.ResNo);\n" - << " return;\n" - << " }\n" - << " }\n" + << " case ISD::CopyFromReg:\n" << " case ISD::CopyToReg: {\n" - << " SDOperand Chain;\n" - << " Select(Chain, N.getOperand(0));\n" - << " unsigned Reg = cast(N.getOperand(1))->getReg();\n" - << " SDOperand Val;\n" - << " Select(Val, N.getOperand(2));\n" - << " Result = N;\n" - << " if (N.Val->getNumValues() == 1) {\n" - << " if (Chain != N.getOperand(0) || Val != N.getOperand(2))\n" - << " Result = CurDAG->getCopyToReg(Chain, Reg, Val);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, " - << "Result.Val, 0);\n" - << " } else {\n" - << " SDOperand Flag(0, 0);\n" - << " if (N.getNumOperands() == 4) Select(Flag, N.getOperand(3));\n" - << " if (Chain != N.getOperand(0) || Val != N.getOperand(2) ||\n" - << " (N.getNumOperands() == 4 && Flag != N.getOperand(3)))\n" - << " Result = CurDAG->getCopyToReg(Chain, Reg, Val, Flag);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 0, " - << "Result.Val, 0);\n" - << " SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, 1, " - << "Result.Val, 1);\n" - << " Result = Result.getValue(N.ResNo);\n" + << " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) {\n" + << " SDOperand Dummy;\n" + << " AddToQueue(Dummy, N.getOperand(i));\n" << " }\n" + << " Result = N;\n" << " return;\n" << " }\n" << " case ISD::INLINEASM: Select_INLINEASM(Result, N); return;\n"; @@ -3683,78 +3550,89 @@ void DAGISelEmitter::run(std::ostream &OS) { OS << "#define NOINLINE\n"; OS << "#endif\n\n"; - OS << "// Instance var to keep track of multiply used nodes that have \n" - << "// already been selected.\n" - << "std::map CodeGenMap;\n"; + OS << "// Instruction selector priority queue:\n" + << "std::vector ISelQueue;\n"; + OS << "/// Keep track of nodes which have already been added to queue.\n" + << "unsigned char *ISelQueued;\n"; + OS << "/// Keep track of nodes which have already been selected.\n" + << "unsigned char *ISelSelected;\n"; + OS << "/// Dummy parameter to ReplaceAllUsesOfValueWith().\n" + << "std::vector ISelKilled;\n\n"; - OS << "// Instance var to keep track of mapping of chain generating nodes\n" - << "// and their place handle nodes.\n"; - OS << "std::map HandleMap;\n"; - OS << "// Instance var to keep track of mapping of place handle nodes\n" - << "// and their replacement nodes.\n"; - OS << "std::map ReplaceMap;\n"; + OS << "/// Sorting functions for the selection queue.\n" + << "struct isel_sort : public std::binary_function" + << " {\n" + << " bool operator()(const SDNode* left, const SDNode* right) " + << "const {\n" + << " return (left->getNodeId() > right->getNodeId());\n" + << " }\n" + << "};\n\n"; - OS << "\n"; - OS << "// AddHandleReplacement - Note the pending replacement node for a\n" - << "// handle node in ReplaceMap.\n"; - OS << "void AddHandleReplacement(SDNode *H, unsigned HNum, SDNode *R, " - << "unsigned RNum) {\n"; - OS << " SDOperand N(H, HNum);\n"; - OS << " std::map::iterator HMI = HandleMap.find(N);\n"; - OS << " if (HMI != HandleMap.end()) {\n"; - OS << " ReplaceMap[HMI->second] = SDOperand(R, RNum);\n"; - OS << " HandleMap.erase(N);\n"; - OS << " }\n"; + OS << "inline void setQueued(int Id) {\n"; + OS << " ISelQueued[Id / 8] |= 1 << (Id % 8);\n"; OS << "}\n"; - - OS << "\n"; - OS << "// SelectDanglingHandles - Select replacements for all `dangling`\n"; - OS << "// handles.Some handles do not yet have replacements because the\n"; - OS << "// nodes they replacements have only dead readers.\n"; - OS << "void SelectDanglingHandles() {\n"; - OS << " for (std::map::iterator I = " - << "HandleMap.begin(),\n" - << " E = HandleMap.end(); I != E; ++I) {\n"; - OS << " SDOperand N = I->first;\n"; - OS << " SDOperand R;\n"; - OS << " Select(R, N.getValue(0));\n"; - OS << " AddHandleReplacement(N.Val, N.ResNo, R.Val, R.ResNo);\n"; - OS << " }\n"; + OS << "inline bool isQueued(int Id) {\n"; + OS << " return ISelQueued[Id / 8] & (1 << (Id % 8));\n"; OS << "}\n"; - OS << "\n"; - OS << "// ReplaceHandles - Replace all the handles with the real target\n"; - OS << "// specific nodes.\n"; - OS << "void ReplaceHandles() {\n"; - OS << " for (std::map::iterator I = " - << "ReplaceMap.begin(),\n" - << " E = ReplaceMap.end(); I != E; ++I) {\n"; - OS << " SDOperand From = I->first;\n"; - OS << " SDOperand To = I->second;\n"; - OS << " for (SDNode::use_iterator UI = From.Val->use_begin(), " - << "E = From.Val->use_end(); UI != E; ++UI) {\n"; - OS << " SDNode *Use = *UI;\n"; - OS << " std::vector Ops;\n"; - OS << " for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i){\n"; - OS << " SDOperand O = Use->getOperand(i);\n"; - OS << " if (O.Val == From.Val)\n"; - OS << " Ops.push_back(To);\n"; - OS << " else\n"; - OS << " Ops.push_back(O);\n"; - OS << " }\n"; - OS << " SDOperand U = SDOperand(Use, 0);\n"; - OS << " CurDAG->UpdateNodeOperands(U, Ops);\n"; - OS << " }\n"; - OS << " }\n"; + OS << "inline void setSelected(int Id) {\n"; + OS << " ISelSelected[Id / 8] |= 1 << (Id % 8);\n"; OS << "}\n"; + OS << "inline bool isSelected(int Id) {\n"; + OS << " return ISelSelected[Id / 8] & (1 << (Id % 8));\n"; + OS << "}\n\n"; + + OS << "inline void AddToQueue(SDOperand &Result, SDOperand N) {\n"; + OS << " Result = N;\n"; + OS << " int Id = N.Val->getNodeId();\n"; + OS << " if (Id != -1 && !isQueued(Id)) {\n"; + OS << " ISelQueue.push_back(N.Val);\n"; + OS << " std::push_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n"; + OS << " setQueued(Id);\n"; + OS << " }\n"; + OS << "}\n\n"; + + OS << "inline void RemoveKilled() {\n"; +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 << " };\n"; + OS << " std::make_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n"; + OS << " ISelKilled.clear();\n"; + OS << " }\n"; + OS << "}\n\n"; + + OS << "inline void ReplaceUses(SDOperand F, SDOperand T) {\n"; + OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, ISelKilled);\n"; + OS << " setSelected(F.Val->getNodeId());\n"; + OS << " RemoveKilled();\n"; + OS << "}\n\n"; - OS << "\n"; OS << "// SelectRoot - Top level entry to DAG isel.\n"; - OS << "SDOperand SelectRoot(SDOperand N) {\n"; + OS << "SDOperand SelectRoot(SDOperand Root) {\n"; + OS << " SelectRootInit();\n"; + OS << " unsigned NumBytes = (DAGSize + 7) / 8;\n"; + OS << " ISelQueued = new unsigned char[NumBytes];\n"; + OS << " ISelSelected = new unsigned char[NumBytes];\n"; + OS << " memset(ISelQueued, 0, NumBytes);\n"; + OS << " memset(ISelSelected, 0, NumBytes);\n"; + OS << "\n"; OS << " SDOperand ResNode;\n"; - OS << " Select(ResNode, N);\n"; - OS << " SelectDanglingHandles();\n"; - OS << " ReplaceHandles();\n"; - OS << " ReplaceMap.clear();\n"; + OS << " Select(ResNode, Root);\n"; + OS << " while (!ISelQueue.empty()) {\n"; + OS << " SDOperand Tmp;\n"; + OS << " SDNode *Node = ISelQueue.front();\n"; + OS << " std::pop_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n"; + OS << " ISelQueue.pop_back();\n"; + OS << " if (!isSelected(Node->getNodeId()))\n"; + OS << " Select(Tmp, SDOperand(Node, 0));\n"; + OS << " }\n"; + OS << "\n"; + OS << " delete[] ISelQueued;\n"; + OS << " ISelQueued = NULL;\n"; + OS << " delete[] ISelSelected;\n"; + OS << " ISelSelected = NULL;\n"; OS << " return ResNode;\n"; OS << "}\n"; diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h index e13b324e108..b118a1d95d7 100644 --- a/utils/TableGen/DAGISelEmitter.h +++ b/utils/TableGen/DAGISelEmitter.h @@ -523,8 +523,7 @@ private: std::vector > &GeneratedCode, std::set > &GeneratedDecl, std::vector &TargetOpcodes, - std::vector &TargetVTs, - bool DoReplace); + std::vector &TargetVTs); void EmitPatterns(std::vector > > > &Patterns, unsigned Indent, std::ostream &OS);