+
+ OS << "// Instance var to keep track of mapping of chain generating nodes\n"
+ << "// and their place handle nodes.\n";
+ OS << "std::map<SDOperand, SDOperand> HandleMap;\n";
+ OS << "// Instance var to keep track of mapping of place handle nodes\n"
+ << "// and their replacement nodes.\n";
+ OS << "std::map<SDOperand, SDOperand> ReplaceMap;\n";
+ OS << "// Keep track of nodes that are currently being selecte and therefore\n"
+ << "// should not be folded.\n";
+ OS << "std::set<SDNode*> InFlightSet;\n";
+
+ OS << "\n";
+ OS << "static void findNonImmUse(SDNode* Use, SDNode* Def, bool &found, "
+ << "std::set<SDNode *> &Visited) {\n";
+ OS << " if (found || !Visited.insert(Use).second) return;\n";
+ OS << " for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {\n";
+ OS << " SDNode *N = Use->getOperand(i).Val;\n";
+ OS << " if (N != Def) {\n";
+ OS << " findNonImmUse(N, Def, found, Visited);\n";
+ OS << " } else {\n";
+ OS << " found = true;\n";
+ OS << " break;\n";
+ OS << " }\n";
+ OS << " }\n";
+ OS << "}\n";
+
+ OS << "\n";
+ OS << "static bool isNonImmUse(SDNode* Use, SDNode* Def) {\n";
+ OS << " std::set<SDNode *> Visited;\n";
+ OS << " bool found = false;\n";
+ OS << " for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {\n";
+ OS << " SDNode *N = Use->getOperand(i).Val;\n";
+ OS << " if (N != Def) {\n";
+ OS << " findNonImmUse(N, Def, found, Visited);\n";
+ OS << " if (found) break;\n";
+ OS << " }\n";
+ OS << " }\n";
+ OS << " return found;\n";
+ OS << "}\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<SDOperand, SDOperand>::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 << "}\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<SDOperand, SDOperand>::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 << "}\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<SDOperand, SDOperand>::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<SDOperand> 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 << "}\n";
+
+ OS << "\n";
+ OS << "// UpdateFoldedChain - return a SDOperand of the new chain created\n";
+ OS << "// if the folding were to happen. This is called when, for example,\n";
+ OS << "// a load is folded into a store. If the store's chain is the load,\n";
+ OS << "// then the resulting node's input chain would be the load's input\n";
+ OS << "// chain. If the store's chain is a TokenFactor and the load's\n";
+ OS << "// output chain feeds into in, then the new chain is a TokenFactor\n";
+ OS << "// with the other operands along with the input chain of the load.\n";
+ OS << "SDOperand UpdateFoldedChain(SelectionDAG *DAG, SDNode *N, "
+ << "SDNode *Chain, SDNode* &OldTF) {\n";
+ OS << " OldTF = NULL;\n";
+ OS << " if (N == Chain) {\n";
+ OS << " return N->getOperand(0);\n";
+ OS << " } else if (Chain->getOpcode() == ISD::TokenFactor &&\n";
+ OS << " N->isOperand(Chain)) {\n";
+ OS << " SDOperand Ch = SDOperand(Chain, 0);\n";
+ OS << " std::map<SDOperand, SDOperand>::iterator CGMI = "
+ << "CodeGenMap.find(Ch);\n";
+ OS << " if (CGMI != CodeGenMap.end())\n";
+ OS << " return SDOperand(0, 0);\n";
+ OS << " OldTF = Chain;\n";
+ OS << " std::vector<SDOperand> Ops;\n";
+ OS << " for (unsigned i = 0; i < Chain->getNumOperands(); ++i) {\n";
+ OS << " SDOperand Op = Chain->getOperand(i);\n";
+ OS << " if (Op.Val == N)\n";
+ OS << " Ops.push_back(N->getOperand(0));\n";
+ OS << " else\n";
+ OS << " Ops.push_back(Op);\n";
+ OS << " }\n";
+ OS << " return DAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n";
+ OS << " }\n";
+ OS << " return SDOperand(0, 0);\n";
+ OS << "}\n";
+
+ OS << "\n";
+ OS << "// SelectRoot - Top level entry to DAG isel.\n";
+ OS << "SDOperand SelectRoot(SDOperand N) {\n";
+ OS << " SDOperand ResNode;\n";
+ OS << " Select(ResNode, N);\n";
+ OS << " SelectDanglingHandles();\n";
+ OS << " ReplaceHandles();\n";
+ OS << " ReplaceMap.clear();\n";
+ OS << " return ResNode;\n";
+ OS << "}\n";